直接用dgmgrl而非手写sql+脚本,因其将切换、校验等操作封装为原子命令,自动维护元数据并跨实例校验一致性;但需满足db_unique_name显式设置、启用pdb、log_archive_config配置正确、监听支持global_dbname等严格前置条件。
为什么直接用 dgmgrl 而不手写 sql+脚本管理 data guard?
因为手动切换、校验、状态同步全靠 alter database 和 select * from v$dataguard_status,容易漏步骤、状态不同步、主备角色误判。broker 把这些操作封装成原子命令,自动维护配置元数据(存于 broker_config 表),还能跨实例校验日志应用一致性。
但 Broker 不是“开箱即用”——它依赖严格的前置条件,缺一不可:
-
DB_UNIQUE_NAME在主库和备库上必须显式设置且互不相同(不能沿用默认的ORCL) - 主备库都必须启用
ENABLE PLUGGABLE DATABASE(即使没用 PDB,12c+ 强制要求) -
LOG_ARCHIVE_CONFIG必须包含双方的DB_UNIQUE_NAME,例如:'DG_CONFIG=(orcl_primary,orcl_standby)' - 监听器必须支持
GLOBAL_DBNAME为db_unique_name_DGMGRL.db_domain(否则DGMGRL连不上备库)
如何用 DGMGRL 创建配置并验证连接性?
先确保主库已启动到 MOUNT 或 OPEN 状态,备库在 MOUNT 状态,且归档已开启。然后在任意节点执行:
DGMGRL DGMGRL> CONNECT sys/password@orcl_primary DGMGRL> CREATE CONFIGURATION 'my_dg_config' AS PRIMARY DATABASE IS 'orcl_primary' CONNECT IDENTIFIER IS orcl_primary; DGMGRL> ADD DATABASE 'orcl_standby' AS CONNECT IDENTIFIER IS orcl_standby MAINTAINED AS PHYSICAL; DGMGRL> ENABLE CONFIGURATION;
关键点在于 CONNECT IDENTIFIER:它不是 TNS 别名,而是 tnsnames.ora 中定义的、能连通对方实例的网络服务名,且该服务名对应的 GLOBAL_DBNAME 必须是 orcl_standby_DGMGRL(注意末尾 _DGMGRL)。常见失败是这里报错 ORA-16664: unable to receive the result from a database,基本就是 GLOBAL_DBNAME 不匹配或监听未重载。
Broker 配置后,哪些状态字段最值得盯?
运行 SHOW CONFIGURATION VERBOSE; 后重点关注三列:
-
Protection Mode:显示当前保护模式(MAXIMUM AVAILABILITY/MAXIMUM PERFORMANCE),但实际生效取决于主库的LOG_ARCHIVE_DEST_2的SYNC/ASYNC和VALID_FOR设置,Broker 只读取不强制修改 -
Fast-Start Failover:默认DISABLED,开启需额外配置 Observer,且主备库FAILOVER_THRESHOLD、REINSTATE等参数要对齐,否则 failover 后无法自动 reinstate 备库 -
Database Status下的Instance Status:若显示NOT INSIDE,说明该实例未被 Broker 纳入管理(通常是dg_broker_start=FALSE或实例未注册进LOCAL_LISTENER)
别只看 State 是 SUCCESS 就放心——它只表示 Broker 进程间通信正常,不代表 Redo 传输或应用没延迟。得配合 SELECT MAX(SEQUENCE#) FROM V$ARCHIVED_LOG WHERE DEST_ID=1; 主备比对序列号。
Broker 切换失败时,第一反应不该是重试,而是查什么?
执行 SWITCHOVER TO orcl_standby; 卡住或报错,优先检查:
-
SELECT STATUS, ERROR FROM V$DATAGUARD_STATUS WHERE SEVERITY = 'ERROR';—— Broker 自身错误会记录在这里,比如ORA-16778: redo transport error -
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY;—— 看MRP0是否 RUNNING,ARCH是否有卡住的归档进程 - 主库
LOG_ARCHIVE_DEST_STATE_2是否为ENABLE,且VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE);备库对应 dest 必须是STANDBY_LOGFILES,STANDBY_ROLE
最容易被忽略的是:Broker 切换前会尝试关闭主库的 LOG_ARCHIVE_DEST_STATE_2,如果这个 dest 指向了另一个备库(比如级联环境),会导致切换中止——此时必须先用 EDIT DATABASE ... SET PROPERTY 临时禁用多余 dest,切完再恢复。











