MAXIMUM PROTECTION模式下必须配置SYNC AFFIRM、启用STANDBY REDO LOG且大小组数≥主库、使用PHYSICAL STANDBY并开启REAL-TIME APPLY,缺一不可,否则无法实现真正零数据丢失。
MAXIMUM PROTECTION 模式必须配 SYNC AFFIRM,否则不是真零丢失
很多人误以为只要选了 maximum protection 就自动零丢失,其实 oracle 不会强制你配对的传输参数。关键看 log_archive_dest_2 是否显式写了 sync affirm —— 缺一不可。
-
SYNC NOAFFIRM表示备库收到 redo 后只写进内存缓冲区就返回 ACK,主库 COMMIT 不等磁盘落盘,断电即丢 -
AFFIRM才要求备库把 redo 写入磁盘(standby redo log文件),再发确认;没这个,MAXIMUM PROTECTION会自动降级为MAXIMUM AVAILABILITY - 检查命令:
SELECT DEST_NAME, STATUS, TRANSMIT_MODE, AFFIRM FROM V$ARCHIVE_DEST WHERE DEST_ID = 2;,AFFIRM列必须是YES
备库必须启用 STANDBY REDO LOG,且大小/组数 ≥ 主库 ONLINE REDO LOG
这是 AFFIRM 能生效的硬性前提。如果 standby redo log 不足或缺失,LGWR 在主库提交时会卡住,报 ORA-16072 或直接降级传输模式。
- 每组 standby redo log 至少和主库 online redo log 单组大小一致(例如主库是 2GB,备库不能用 512MB)
- 组数不能少于主库(比如主库有 4 组,备库至少也要 4 组)
- 创建语句示例:
ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 '/u01/oradata/stdby/redo04.log' SIZE 2G; - 验证:
SELECT GROUP#, THREAD#, SEQUENCE#, BYTES, STATUS FROM V$STANDBY_LOG;,确保状态不是UNASSIGNED
必须是 PHYSICAL STANDBY + REAL-TIME APPLY,LOGICAL STANDBY 不支持
Logical standby 基于 SQL Apply,解析、转换、执行都是异步的,无法满足物理块层面的同步写磁盘原子性要求 —— 它连 MAXIMUM PROTECTION 都不被允许启用。
- 启动实时应用命令必须带
USING CURRENT LOGFILE:ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT; - 缺了
USING CURRENT LOGFILE,MRP 进程只会拉归档日志,延迟从秒级变成分钟甚至小时级 - 检查是否真在实时应用:
SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY WHERE PROCESS = 'MRP0';,STATUS应为APPLYING_LOG,SEQUENCE#和主库V$LOG_HISTORY最新序号差 ≤ 1
网络与存储链路必须满足“双写确认”的确定性,否则会超时挂起
SYNC AFFIRM 不是 Oracle 单方面能兜底的。它依赖整个链路:主库 LGWR → 网络传输 → 备库 RFS → 写入 standby redo log 磁盘 → 返回 ACK。任一环节抖动,都会触发等待或降级。
- 常见错误现象:
ORA-16198(网络超时)、ORA-16057(心跳中断)、LGWR wait for redo transport等待事件飙升 - 网络建议万兆光纤直连,避免跨交换机或 NAT;TCP keepalive 时间调小(如
net.ipv4.tcp_keepalive_time=30) - 备库存储必须本地直连(不能走远端 NAS 或低性能 SAN),且 I/O 延迟稳定
- 禁用
STANDBY DATABASE GUARD NONE,必须保持DATABASE GUARD ALL,防止意外在备库执行 DML 破坏一致性
金融级容灾真正难的不是配置开关,而是让 SYNC AFFIRM 在真实生产网络和存储条件下持续稳定返回 ACK —— 这个链路没有冗余,也没有妥协空间。


















