Oracle OCM考试的时候有ADG的搭建和切换。到19C的时候这部分都放到OCP中了。我自己做过,但是也错过。我看过不少团队的 ADG 建完就再没动过。日志在传,备库在应用,监控一片绿,看着万事大吉。实际上我经历的系统也的确不需要切换。稳定!
很久也没做了。今天想着在自己的环境中让AI做一次。能不能切、切完数据对不对、切完还能不能把失效主库收回来,这三件事,只有演练能回答。
这次拿一套状态健康的
Oracle 19c CDB Active Data Guard
做一次标准示范:先确认基线,再讲清楚重点参数,然后分别做一次 Switchover 和一次 Failover,最后把失效主库重新纳入。每一步都带真实数据。
Oracle 19c CDB · Active Data Guard
103 主 / 105 备 · MAXIMUM PERFORMANCE(LGWR ASYNC)
transport lag = apply lag = +00 00:00:00 · NO GAP
切换前别急着敲命令,先把两端状态看全。下面这些是演练起点的实测值。
▸
DATABASE_ROLE:103 =
PRIMARY
,105 =
PHYSICAL STANDBY
▸
OPEN_MODE:READ WRITE /
READ ONLY WITH APPLY
(实时应用已开)
▸
SWITCHOVER_STATUS:TO STANDBY / NOT ALLOWED(备库正常取值)
▸
进程对齐:LNS WRITING、MRP0 APPLYING_LOG,日志序号同为
1211
▸
V$ARCHIVE_GAP 为空,V$DATAGUARD_STATS 两项 lag 均为
0
▸
FORCE_LOGGING = YES、FLASHBACK_ON = YES,PDB
P1
两端均已打开
判断能不能切,看三个硬指标:
目标库 SWITCHOVER_STATUS 允许、v$archive_gap 为空、transport 与 apply lag 归零。
三个都满足,才具备切换基础。
ADG 的参数不算多,但每一个都决定切换那一刻的行为。下面这些是我每次演练前必看的,按「它管什么」来讲,不堆参数字典。
db_unique_name 与 log_archive_config —— DG 的点名册
两个库必须各有唯一名字(本例
orcl_pri
/
orcl_sty
),再用
dg_config=(orcl_pri,orcl_sty)
把成员列全。redo 传输、FAL 补档、角色校验都靠它认人,名字对不上后面全都不通。
log_archive_dest_1 —— 本库自己的归档落在哪
LOCATION=USE_DB_RECOVERY_FILE_DEST
,配
valid_for=(all_logfiles,all_roles)
和本库的
db_unique_name
。注意它对所有角色都生效:不管当前是主是备,本地归档都得能写。
log_archive_dest_2 —— 往对端送 redo
service=orcl_sty LGWR ASYNC valid_for=(online_logfiles,primary_role) db_unique_name=orcl_sty
。LGWR ASYNC 决定传输方式与保护级别,valid_for 决定「只有本库是 PRIMARY 时才发送」。
fal_server / fal_client —— 断档自动补日志
网络闪断产生 GAP 时,备库按
fal_server
找对端要缺的归档,
fal_client
告诉对方自己是谁。主备各配一份、分别指向对端,切换后两个方向才都通。
standby_file_management = AUTO
主库新增数据文件,备库自动同步创建。少了这一条,切换后加一个数据文件就可能在备库掉队。
log_archive_dest_state_2 与密码文件
state_2 是远程传输的开关(DEFER / ENABLE);
remote_login_passwordfile
配合两端一致的 orapw 文件,保证 SYS 认证能跨库完成——redo 传输用的正是 SYS。
最容易看漏的是
valid_for
:正是它让同一套 dest_2 配置在角色互换后自动生效——主库时往对端送,变成备库时自动停用。所以两端参数可以写得几乎对称,切换时不需要临时改参数。
参数要落在 spfile 里,改完用
v$spparameter
复核,而不是只看
show parameter
;切换前后各查一次
v$archive_dest_status
,确认 dest_1 / dest_2 都是 VALID、NO GAP。
计划内切换,主库先转、备库后转。全程不 RESETLOGS,角色可逆。
先
ALTER SYSTEM ARCHIVE LOG CURRENT
把当前 redo 冲刷到备库,再
COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN
,随后 SHUTDOWN IMMEDIATE + STARTUP MOUNT。结果:103 变为 PHYSICAL STANDBY / MOUNTED,SWITCHOVER_STATUS = RECOVERY NEEDED,切换起点
SCN 222039660
。
确认已收到 EOR(SWITCHOVER_STATUS = TO PRIMARY)后,取消 MRP、重启到 MOUNT,执行
COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN
,再 OPEN。结果:105 成为 PRIMARY / READ WRITE,
STANDBY_BECAME_PRIMARY_SCN = 222139679
,redo 序号推进到 1214 / 1215,dest_2 VALID / NO GAP。
103 在 MOUNT 下起 MRP 应用完 EOR,再 OPEN READ ONLY 并以 DISCONNECT 方式重启应用。结果:103 回到
READ ONLY WITH APPLY
,MRP0 APPLYING_LOG 序号 1215,两端都能查到基线行和切换后写入的标记行,双向同步成立。
09:11:09 → 09:14:31,3 分 22 秒
不 RESETLOGS · 不产生新 incarnation
角色可逆 · 双向数据同步验证通过
Switchover 的本质是两边协商好的角色互换:
主库把最后的 redo 冲过去,备库收到 EOR 才提交。
因为不产生新分支,切完还能原路切回来。
CDB 环境两个容易漏的动作:每次角色变化后都要显式
ALTER PLUGGABLE DATABASE ALL OPEN [READ ONLY]
,否则 PDB 停在 MOUNTED;归档切换要在 CDB$ROOT 执行。
计划外场景,没有协商,只有接管。演练里先在 105 写入最后一条已提交事务(id=3),两次归档切换把 redo 冲干净:
CURRENT_SCN = 222143083
,最大在线日志序号 1217,LNS WRITING、NO GAP。然后
SHUTDOWN ABORT
模拟主机宕机,PMON 消失。
①
RECOVER MANAGED STANDBY DATABASE FINISH
—— 把已接收的 redo 全部应用完,不加 FORCE,保住在途 redo;
②
ACTIVATE PHYSICAL STANDBY DATABASE
—— 激活为主库;
③
ALTER DATABASE OPEN
并打开所有 PDB。
RESETLOGS_CHANGE# = 222143087
STANDBY_BECAME_PRIMARY_SCN = 222143084
在线日志序号从 1 / 2 重新计数(新 incarnation)
▸
DATABASE_ROLE / OPEN_MODE =
PRIMARY / READ WRITE
▸
标记数据 id=1、2、3 全部存在,
崩溃前最后一条已提交事务完整保留
▸
P1 已 READ WRITE,业务可写;新主库开始独立产生 redo
Switchover 和 Failover 最本质的区别只有一个:
Failover 必须 RESETLOGS
,数据库从此分出一条新的 incarnation。这也正是后面需要 Reinstate 的原因。
Failover 之后还有个容易被忽略的收尾:原主库在配置里仍挂着 PRIMARY 角色。等它修好回来,一套 DG 里就出现了
两个主库
。Reinstate 做的就是让它降回备库、重新归队——而不是重新 duplicate 一遍全量数据。
能这么做靠的是闪回。在新主库上查
STANDBY_BECAME_PRIMARY_SCN
(本次
222143084
),那就是两条 redo 分支分叉的时刻;把原主库倒回分叉点之前,两边重新落在同一条分支上,MRP 就能接着应用。
①
原主库故障前已开启 FLASHBACK DATABASE,且闪回日志覆盖目标 SCN(本次 oldest_flashback_scn = 222038908,远早于目标);
②
故障后没被以 RESETLOGS 打开过、没有独立写入,否则真分叉就救不回来;
③
新主库到它的传输目标已启用。
FLASHBACK DATABASE TO SCN 222143083;
ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
CONVERT 会关闭实例,重新 MOUNT 后先追平 EOR,再以 READ ONLY 打开并重启 MRP,就回到 ADG 实时应用状态。
启用 Data Guard Broker 时,这一步收敛成
DGMGRL> REINSTATE DATABASE orcl_pri
一条命令:闪回、角色转换、重启传输由 Broker 自动完成,手工流程做的是同一组动作;Fast-Start Failover 场景下 Observer 还会自动发起。
结果:105 回到
PHYSICAL STANDBY / READ ONLY WITH APPLY
,RESETLOGS_CHANGE# 跟随新主库变为 222143087,MRP0 APPLYING_LOG,transport lag = apply lag = 0,dest_1 / dest_2 均 VALID。拓扑恢复为 103 主 / 105 备。
Reinstate
只在 Failover 之后才有意义
。Switchover 是协商好的角色互换,不产生新分支,切完各自就是对方的角色,压根不需要这一步;不少 DBA 对它没印象,恰恰是因为平时只做计划内切换。
整场演练在 PDB P1 里用一张标记表记录每个阶段的写入,最后在两端查询结果完全一致。
▸
01
00-BASELINE · 写入 or103 · SCN 222038869 · 09:05:21
▸
02
10-AFTER-SWITCHOVER-1 · 写入 or105 · SCN 222140360 · 09:13:04
▸
03
20-BEFORE-FAILOVER · 写入 or105 · SCN 222143047 · 09:15:56
▸
04
30-AFTER-REINSTATE · 写入 or103 · SCN 222145788 · 09:21:27
最终状态:103
PRIMARY / READ WRITE
,105
PHYSICAL STANDBY / READ ONLY WITH APPLY
;dest_1 / dest_2 均 VALID、NO GAP;transport lag = apply lag = 0;P1 两端分别 READ WRITE / READ ONLY。
演练前确认 lag=0、无 GAP 并先做归档切换,所以最后一条已提交事务完整保留。
切换演练的价值从来不在命令本身,而在切换前后那两次状态核对。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/637517/viewspace-3188674/
,如需转载,请注明出处,否则将追究法律责任。