active data guard是oracle 11.2.0.1+唯一支持主库写+备库实时只读查询的合法方式,需单独许可;必须启用force logging和归档模式,配置匹配的standby redo log,并精确设置log_archive_dest_2的service、valid_for等参数。
active data guard 是 oracle 11gr2(11.2.0.1 及以上)中唯一支持「主库写 + 备库实时只读查询」的合法方式。没有它,物理备库 standby 在应用日志时无法打开为 read only;开了 read only 就停了日志应用 —— 二者不可兼得。
所以,第一步不是配参数,而是确认许可证:
-
Active Data Guard是单独收费选项,非企业版默认不包含 - 运行
SELECT * FROM v$option WHERE parameter = 'Active Data Guard';,返回TRUE才能继续 - 若为
FALSE,所有后续配置都无法实现真正的读写分离,只能做灾备切换
FORCE LOGGING 和归档必须启用,否则同步会丢数据
主库没开强制日志、或部分表用了 nologging,会导致这些操作不生成完整 redo,备库就无法重放,出现逻辑不一致。这不是延迟问题,是数据损坏风险。
- 检查当前状态:
SELECT force_logging FROM v$database;,必须是YES - 若为
NO,执行:ALTER DATABASE FORCE LOGGING;(需MOUNT状态) - 归档模式必须开启:
ARCHIVE LOG LIST;返回Database log mode: Archive Mode - 如果是
No Archive Mode,先SHUTDOWN IMMEDIATE→STARTUP MOUNT→ALTER DATABASE ARCHIVELOG;→ALTER DATABASE OPEN;
注意:FORCE LOGGING 开启后,所有 DML(包括 INSERT /<em>+ APPEND </em>/)都会写 redo,性能略有下降,但这是读写分离的前提底线。
STANDBY REDO LOG 组数和大小必须严格匹配主库 ONLINE REDO
很多同步卡在 ARCHIVED LOG 传输后不再推进,实际是备库缺 STANDBY REDO,导致 LGWR ASYNC 传输的日志无法被即时接收和写入。
- 主库有 N 组 online redo(
SELECT GROUP#, BYTES FROM V$LOG;),备库至少要有(N + 1)组 standby redo - 每组大小必须 ≥ 主库最大 online redo 组大小(常见坑:主库 redo 是 2G,备库建了 100M 的 standby redo,直接报错
ORA-00313) - 路径建议与主库一致,避免
DB_FILE_NAME_CONVERT配置出错引发文件创建失败
示例(主库 3 组 2G online redo):
ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 '/u01/oradata/standby/standby_redo04.log' SIZE 2048M; ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 '/u01/oradata/standby/standby_redo05.log' SIZE 2048M; ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 '/u01/oradata/standby/standby_redo06.log' SIZE 2048M; ALTER DATABASE ADD STANDBY LOGFILE GROUP 7 '/u01/oradata/standby/standby_redo07.log' SIZE 2048M;
LOG_ARCHIVE_DEST_2 的 SERVICE 和 VALID_FOR 必须精确对应角色
参数写错一个词,比如把 ASYNC 写成 SYNC,或 VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) 漏掉括号,都会导致主库无法传输日志,V$ARCHIVE_DEST_STATUS 中显示 ERROR 或 INACTIVE。
关键项检查清单:
-
SERVICE=xxx中的xxx必须是备库tnsnames.ora里定义的服务名,且能tnsping xxx通 -
DB_UNIQUE_NAME在LOG_ARCHIVE_CONFIG和各LOG_ARCHIVE_DEST_n中必须完全一致(区分大小写) -
VALID_FOR不能写成(ALL_LOGFILES,ALL_ROLES)—— 这会让主库尝试把归档也发给备库,引发循环 - 备库端必须设
FAL_SERVER指向主库服务名,否则 gap 出现时无法自动拉取缺失日志
典型主库配置片段:
LOG_ARCHIVE_CONFIG='DG_CONFIG=(primdb,stbydb)' LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=primdb' LOG_ARCHIVE_DEST_2='SERVICE=stbydb LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=stbydb'
真正跑起来之后,最常被忽略的是备库监听状态和密码文件同步。ORACLE_SID 不同但 orapw$ORACLE_SID 文件没复制、或备库密码文件权限不对(非 640)、或监听没 reload,都会触发 ORA-16191 —— 这个错误看起来像网络问题,实际八成是认证失败。
别急着改防火墙,先在备库跑一遍:sqlplus / as sysdba → SELECT STATUS FROM V$INSTANCE; → 再 CONNECT SYS@primdb AS SYSDBA,看能不能连通主库。











