ITPub博客

首页 > 数据库 > Oracle > 今天让Agent进行数据库主从切换

今天让Agent进行数据库主从切换

原创 Oracle 作者:xuexiaogang 时间:2026-11-12 10:27:55 0 删除 编辑
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

PART 01
先看基线:一套「好的」ADG 长什么样
切换前别急着敲命令,先把两端状态看全。下面这些是演练起点的实测值。
演练起点 · 实测
▸  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 归零。 三个都满足,才具备切换基础。

PART 02
重点关注哪些参数,分别是什么意思
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。

PART 03
Switchover —— 计划内的角色互换
计划内切换,主库先转、备库后转。全程不 RESETLOGS,角色可逆。
Step A · 103 提交转备
先  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 。
Step B · 105 提交转主
确认已收到 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。
Step C · 新备库恢复实时应用
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 执行。

PART 04
Failover —— 主库没了,备库强制接管
计划外场景,没有协商,只有接管。演练里先在 105 写入最后一条已提交事务(id=3),两次归档切换把 redo 冲干净: CURRENT_SCN = 222143083 ,最大在线日志序号 1217,LNS WRITING、NO GAP。然后  SHUTDOWN ABORT  模拟主机宕机,PMON 消失。
103 接管三步
①   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 的原因。

PART 05
Reinstate —— 失效主库怎么重新归队
Failover 之后还有个容易被忽略的收尾:原主库在配置里仍挂着 PRIMARY 角色。等它修好回来,一套 DG 里就出现了 两个主库 。Reinstate 做的就是让它降回备库、重新归队——而不是重新 duplicate 一遍全量数据。
能这么做靠的是闪回。在新主库上查  STANDBY_BECAME_PRIMARY_SCN (本次  222143084 ),那就是两条 redo 分支分叉的时刻;把原主库倒回分叉点之前,两边重新落在同一条分支上,MRP 就能接着应用。
三个前提,缺一个就只能重建
①  原主库故障前已开启 FLASHBACK DATABASE,且闪回日志覆盖目标 SCN(本次 oldest_flashback_scn = 222038908,远早于目标); ②  故障后没被以 RESETLOGS 打开过、没有独立写入,否则真分叉就救不回来; ③  新主库到它的传输目标已启用。
STARTUP MOUNT;
FLASHBACK DATABASE TO SCN 222143083;
ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
STARTUP MOUNT FORCE;
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 对它没印象,恰恰是因为平时只做计划内切换。

PART 06
最后看数据:4 行标记说明一切
整场演练在 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/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 没有了~
请登录后发表评论 登录
全部评论
OracleACE/PostgreSQLACE/阿里云MVP/腾讯云TVP/墨天轮 MVP/TiDBMVA/数盟会华东区长老/OpenTenBase社区委和技术委委员/架构师技术同盟名人堂成员上海地区理事会成员/if社区联合发起人/《DBA实战手记》作者/公众号:四海内皆兄弟

注册时间:2013-07-01

  • 博文量
    428
  • 访问量
    961517