四海内皆兄弟

把 ADG 交给 Broker 之后切换从一套 SQL 变成一条命令

    上一篇用 SQL*Plus 手工做完了 Switchover、Failover 和 Reinstate。每一步都要自己判断状态、自己启停实例、自己打开 PDB、自己重启 MRP——能做,但整场演练像在照着清单逐项打勾。
这次给同一套 Oracle 19c CDB Active Data Guard 补上 Data Guard Broker,再用它把同样的动作重做一遍。而且我这次还是让AI做的。
     结论先放这儿:Broker 不是「另一种切换语法」,它把角色状态机收进了 DMON 进程。人只负责下命令和看结果,实例启停、PDB 打开、redo 传输、MRP 恢复都由它自己收敛。全程带真实数据和原始输出。
Broker 配置 adg_orcl · 全线 SUCCESS
3 次 Switchover + 1 次 Failover + 1 次 Reinstate
单次切换 31 ~ 57 秒 · 两端 10 行数据完全一致
PART 01
Broker 到底接管了什么
手工方式里,ADG 的「状态」散落在各处:redo 参数在 spfile、角色在控制文件、应用在 MRP 进程、PDB 打开状态在 CDB 里。DBA 每次切换都得把这些对齐一遍。
Broker 加了一层 DMON 进程 + 两个配置文件(dr1 / dr2 .dat),把「谁在什么时候该处于什么状态」变成一份可查询、可执行的配置。
一条 SWITCHOVER TO 背后,Broker 自动做掉的事:
▸ 连接对端并以 SYSDBA 校验角色、确认无 GAP
▸ 启动新备库实例到 MOUNT,再打开数据库
▸ 打开 CDB 下所有 PDB(手工方式最容易漏的一步)
▸ 重写 redo 传输参数、恢复 MRP 实时应用
▸ 持续监控 lag 与成员状态,异常直接报在 SHOW CONFIGURATION 里
启用后 SHOW CONFIGURATION 就是唯一的状态入口:MaxPerformance、两个成员、Transport Lag 0 秒、Apply Lag 0 秒、Real Time Query ON,一眼看完,不用再拼十几条 SQL。
PART 02
启用 Broker 的四步,和两个绕不开的前置
Step 1 · listener 静态注册 _DGMGRL 服务
在两端 SID_LIST_LISTENER 增加 GLOBAL_DBNAME = orcl_pri_DGMGRL(备库对应 orcl_sty_DGMGRL),再 lsnrctl reload。切换时要重启数据库,动态注册此刻已经没了,DMON 全靠这个静态服务连进来。
Step 2 · 启动 DMON
两端 ALTER SYSTEM SET dg_broker_start=TRUE SCOPE=BOTH;。进程 ora_dmon_orcl 出现,同时生成 dr1*.dat / dr2*.dat 两个配置文件。此时 dgmgrl 从 ORA-16525 变成 ORA-16532(broker 可用、只是还没建配置)。
Step 3 · 建配置、加成员、启用
在主库用 DGMGRL 执行三条命令,配置名 adg_orcl:
CREATE CONFIGURATION 'adg_orcl' AS
  PRIMARY DATABASE IS 'orcl_pri' CONNECT IDENTIFIER IS orcl_pri;
ADD DATABASE 'orcl_sty' AS CONNECT IDENTIFIER IS orcl_sty
  MAINTAINED AS PHYSICAL;
ENABLE CONFIGURATION;
Step 4 · SHOW CONFIGURATION VERBOSE 验收
配置状态 SUCCESS;Broker 自动生成的 StaticConnectIdentifier 恰好指向第一步注册的 _DGMGRL 服务;它还接管了 dest_2,写成 ASYNC NOAFFIRM ... valid_for=(online_logfile,all_roles)。
从手工配置迁到 Broker,有两件事必须先做,否则切换会直接卡住:
① 备库的手工 dest_2 要交出去。 ADD DATABASE 时报 ORA-16698:member has a LOG_ARCHIVE_DEST_n parameter with SERVICE attribute set。清空备库 log_archive_dest_2 后重试即通过——redo 传输从此归 Broker 管,不要再手工改。
② DGMGRL 要带 SYS 口令。dgmgrl / 是本机 OS 认证,切换时 DGMGRL 需要跨主机连对端,会报 ORA-01017。改用 dgmgrl sys/<SYS口令>@orcl_pri,并把主库 orapw 文件复制到所有备库保证认证一致。
这两条都不是「配置错了」,而是手工 ADG 交给 Broker 时的所有权交接:redo 传输和跨主机认证,从此都归 Broker。配置属性里还有一句 FastStartFailoverAutoReinstate = TRUE,后面会用到。
PART 03
SWITCHOVER TO —— 一条命令,57 秒
手工方式要分三段:原主库 COMMIT TO SWITCHOVER、原备库 COMMIT TO SWITCHOVER、新备库重新起 MRP,中间还夹着两次 PDB 打开。Broker 只要一句:
DGMGRL> SWITCHOVER TO 'orcl_sty';
下面是原样输出,可以看到它把该干的都干完了:
Performing switchover NOW, please wait...
Operation requires a connection to database "orcl_sty"
Connected to "ORCL_STY" / Connected as SYSDBA.
New primary database "orcl_sty" is opening...
Operation requires start up of instance "orcl" on "orcl_pri"
Starting instance "orcl"... Database mounted. Database opened.
Switchover succeeded, new primary is "orcl_sty"
10:06:23 → 10:07:20,57 秒
103 → PHYSICAL STANDBY / READ ONLY WITH APPLY
105 → PRIMARY / READ WRITE,P1 自动打开,MRP 自动恢复
RESETLOGS_CHANGE# 全程保持 222143087 不变,说明 Switchover 依旧不产生新 incarnation、角色可逆;本次只记下 STANDBY_BECAME_PRIMARY_SCN = 222254674 作为角色变更点。
随后 SWITCHOVER TO 'orcl_pri'; 原路回切,10:08:40 → 10:09:36,56 秒,配置依旧 SUCCESS。两次切换都没有人工干预实例或 PDB。
PART 04
FAILOVER TO —— 主库没了,31 秒接管
在 103 写入最后一条已提交事务(id=8,SCN 222356997,在线日志 seq 16),两次归档切换把 redo 冲干净,然后 SHUTDOWN ABORT 模拟主机断电。
这时 Broker 的监控先起作用了,不用人去查:SHOW CONFIGURATION 立刻把配置状态打成 ERROR,并在成员上标出 ORA-1034: ORACLE not available。
DGMGRL> FAILOVER TO 'orcl_sty';
Performing failover NOW, please wait...
Failover succeeded, new primary is "orcl_sty"
RESETLOGS_CHANGE# = 222357014
STANDBY_BECAME_PRIMARY_SCN = 222357011
10:11:27 → 10:11:58,31 秒 · 在线日志从 seq 1 重新计数
接管后验证
▸ 105 = PRIMARY / READ WRITE,P1 自动 READ WRITE
▸ 崩溃前 8 行标记全部存在,最后一条已提交事务零丢失
▸ 新主库可写,写入标记 id=9(SCN 222357722)
▸ RESETLOGS 产生新 incarnation——这正是 Reinstate 的起点
Failover 之后,Broker 会自己把话挑明:orcl_pri - Physical standby database (disabled) — ORA-16661: the standby database needs to be reinstated。上一篇里「Reinstate 是什么场景」这个问题,其实配置状态里写着答案。
PART 05
REINSTATE DATABASE —— 一条命令让原主库归队
Failover 后原主库在配置里仍挂着 PRIMARY 角色,等它修好回来就是「两个主库」。Reinstate 做的是让它降回备库、重新归队,而不是重新 duplicate 一遍全量数据。上一篇用手工流程做了同样的事,这次看 Broker 怎么收敛。
动作对比
▸ 手工:查 SCN → STARTUP MOUNT → FLASHBACK DATABASE TO SCN → CONVERT TO PHYSICAL STANDBY → 重启 → 开 PDB → 起 MRP
▸ Broker:原主库 STARTUP MOUNT,然后一条 REINSTATE DATABASE 'orcl_pri'
DGMGRL> REINSTATE DATABASE 'orcl_pri';
Reinstating database "orcl_pri", please wait...
Reinstatement of database "orcl_pri" succeeded
10:13:28 → 10:14:20,52 秒
103 自动变回 PHYSICAL STANDBY / READ ONLY WITH APPLY
RESETLOGS_CHANGE# 自动跟随为 222357014 · 控制文件转 STANDBY · MRP0 应用 seq 4 · lag 0
它替你算出了分叉点、闪回到分叉点之前、转换角色、重启实例、打开 PDB、恢复应用。上面这些状态,一次 SHOW DATABASE 'orcl_pri' 就能全部看到:Transport Lag 0 秒、Apply Lag 0 秒、Real Time Query ON、Database Status SUCCESS。
但有一件事 Broker 不会替你做:FLASHBACK DATABASE 必须提前开着。本次 oldest_flashback_scn = 222038835,远早于分叉点 222357011,所以闪回可用。没开闪回,REINSTATE 一样做不到,只能全量重建备库。
PART 06
最后看数据:10 行标记,两端逐行一致
沿用上一篇那张 PDB P1 里的标记表,本次追加 6 行,覆盖启用、两次切换、崩溃前后、接管与归队。最后在主库查询、再通过 tns 远程连备库查询,结果完全一样。
▸05 40-BROKER-ENABLED · or103 · SCN 222152635 · 09:59:24
▸06 50-BROKER-SWITCHOVER-1 · or105 · SCN 222256061 · 10:08:15
▸07 60-BROKER-SWITCHOVER-BACK · or103 · SCN 222356993 · 10:10:47
▸08 70-BEFORE-BROKER-FAILOVER · or103 · SCN 222356997 · 10:10:48
▸09 80-AFTER-BROKER-FAILOVER · or105 · SCN 222357722 · 10:12:24
▸10 90-AFTER-BROKER-REINSTATE · or103 · SCN 222458900 · 10:18:09
最后再用 SWITCHOVER TO 'orcl_pri' 把拓扑切回最初的 103 主 / 105 备(10:16:02 → 10:16:57,55 秒)。最终:Broker 配置 SUCCESS、transport lag = apply lag = 0、NO GAP、两端 dg_broker_start=TRUE、P1 分别 READ WRITE / READ ONLY。
Image