Active Data Guard在Oracle 19c中不能真正实现应用层读写分离,仅支持备库只读查询,写操作必须路由至主库;启用前须满足FORCE LOGGING和ARCHIVELOG、DG参数严格一致、STANDBY_FILE_MANAGEMENT=AUTO等硬性条件,并按规范启停MRP以开启Real-Time Query。

Active Data Guard(ADG)在 Oracle 19c 中**不能真正实现应用层的读写分离**——它只提供物理备库的只读访问能力,所有写操作仍必须路由到主库;所谓“读写分离”只是把只读查询卸载到备库,而非自动拆分 SQL 类型。强行用连接池或中间件做读写路由,若未严格隔离事务上下文,极易触发 ORA-16000 或查不到刚提交的数据。
主库必须开启 FORCE LOGGING 和 ARCHIVELOG
这是 ADG 启动前的硬性门槛,缺一不可。否则备库无法持续应用重做,Real-Time Query 会直接失败。
-
SELECT log_mode, force_logging FROM v$database;必须返回ARCHIVELOG和YES - 若未启用归档:先
SHUTDOWN IMMEDIATE→STARTUP MOUNT→ALTER DATABASE ARCHIVELOG→ALTER DATABASE OPEN - 若未启用强制日志:
ALTER DATABASE FORCE LOGGING(注意:这会轻微拖慢小事务 DML,但不可跳过) - Oracle 18c+ 可选
STANDBY NOLOGGING FOR DATA AVAILABILITY来缓解批量加载时的重做压力,但仅限特定场景,不替代FORCE LOGGING
LOG_ARCHIVE_CONFIG 和 DB_UNIQUE_NAME 必须双向一致
参数名、大小写、拼写全对不上,MRP 进程连归档传输都起不来,更别说实时查询了。
- 主库和备库都需配置:
LOG_ARCHIVE_CONFIG='DG_CONFIG=(orcl_primary,orcl_standby)'(两边顺序可不同,但括号内名称必须完全一致) -
DB_UNIQUE_NAME必须不同:主库设为orcl_primary,备库设为orcl_standby(不能和DB_NAME混淆) - 主库的
LOG_ARCHIVE_DEST_2指向备库:SERVICE=orcl_standby ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl_standby - 备库的
LOG_ARCHIVE_DEST_2指向主库(故障回切用):SERVICE=orcl_primary ASYNC VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=orcl_primary - 务必用
tnsping orcl_standby和sqlplus /@orcl_standby as sysdba实测连通性,别只信 tnsnames.ora 语法正确
RMAN DUPLICATE 时漏掉 STANDBY_FILE_MANAGEMENT=AUTO 就会丢文件
主库新增表空间或数据文件后,备库不会自动创建对应文件,导致后续日志应用卡在 ORA-01111 或 ORA-01157,Real-Time Query 看到的就是旧快照甚至报错。
- 备库参数文件中必须显式设置:
STANDBY_FILE_MANAGEMENT=AUTO - RMAN DUPLICATE 命令里加
NOFILENAMECHECK(避免因主备路径不一致报错) - 密码文件必须单独生成并复制过去:
orapwd file=$ORACLE_HOME/dbs/orapworcl_standby password=xxx entries=10 - 备库启动后立即确认:
SELECT status FROM v$archive_dest_status WHERE dest_id = 2;应为VALID,且SELECT process, status FROM v$managed_standby;中要有MRP0进程在APPLYING_LOG
开启 Real-Time Query 前必须停掉 MRP、只读打开、再重启 MRP
很多人以为备库恢复完就能直接查,其实漏了关键三步:MRP 要暂停、数据库要 OPEN READ ONLY、MRP 再启动。跳过任意一步,SELECT 不是报 ORA-16000,就是查不到最新数据。
- 在备库执行:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; - 再执行:
ALTER DATABASE OPEN READ ONLY; - 最后启动实时应用:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT; - 验证是否生效:
SELECT database_role, open_mode FROM v$database;应返回PHYSICAL STANDBY和READ ONLY WITH APPLY
最易被忽略的是:备库上任何 DML(哪怕加了 /*+ DRIVING_SITE */)都会立刻报 ORA-16000;而主库的全局临时表、序列缓存、物化视图刷新等操作,在备库只读模式下天然不可见——这些不是配置问题,是物理备库的本质限制。真要读写分离,得配合应用改造或用 Oracle Sharding、GoldenGate 等逻辑方案,别指望 ADG 自己扛。


















