AFFIRM仅在SYNC传输下生效,配在ASYNC上会被Oracle静默忽略;验证需同时满足TRANSMIT_MODE=SYNC、AFFIRM=YES、STATUS=VALID,否则看似同步实则异步丢数据。
affirm 模式下仍丢数据,根本原因不是 affirm 本身失效,而是你没在 maximum availability 或 maximum protection 模式下用它
Oracle Data Guard 的 AFFIRM 只在同步传输(SYNC)语义下才真正强制主库等待备库落盘。但如果你把 AFFIRM 配在 ASYNC 传输上(比如 LOG_ARCHIVE_DEST_2='SERVICE=stby ASYNC AFFIRM'),Oracle 会静默忽略 AFFIRM —— 它不报错,也不生效,实际行为等同于 NOAFFIRM。这种配置常见于误读文档或复制旧脚本,结果就是“看着像同步,实则异步裸奔”。
为什么 V$ARCHIVE_DEST_STATUS 显示 AFFIRM=YES 却仍丢数据
查询 V$ARCHIVE_DEST_STATUS 确实可能返回 AFFIRM = YES,但这只说明参数里写了 AFFIRM,不代表它正在起作用:
-
TRANSMIT_MODE必须是SYNC,不是ASYNC或空值;否则AFFIRM字段只是个摆设 - RAC 环境中,不同实例的
V$ARCHIVE_DEST_STATUS可能不一致,只查一个实例容易漏判 - 如果主库因网络抖动触发了自动降级(如
NET_TIMEOUT超时),LGWR 会临时切到NOAFFIRM行为,但视图未必实时刷新该状态
MAXIMUM PERFORMANCE 模式下 AFFIRM 是非法且危险的
官方明确:在 PROTECTION_MODE = MAXIMUM PERFORMANCE 下,AFFIRM 唯一合法的用途是配合 SYNC(但该组合实际已在 2026 年 3 月被弃用)。现实中更常见的错误是:
- DBA 为“保险起见”在
ASYNC链路上硬加AFFIRM,以为多一层确认更安全 - 未检查
V$DATAGUARD_STATS中的transport lag和apply lag,误以为日志已传完就等于已保护 - 备库磁盘响应慢(比如 NFS 挂载延迟高),导致
AFFIRM等待超时后 LGWR 强制返回,但应用层已认为事务成功
怎么验证 AFFIRM 真正在工作
不能只看参数,必须查运行时行为:
- 执行
SELECT DEST_NAME, TRANSMIT_MODE, AFFIRM, STATUS FROM V$ARCHIVE_DEST_STATUS WHERE DEST_ID = 2,三者必须同时满足:TRANSMIT_MODE = SYNC、AFFIRM = YES、STATUS = VALID - 检查主库 LGWR trace 文件,搜索
"NSS.*sync"或"waiting for standby ack",有这类日志才说明真在等 - 模拟网络延迟(如 iptables 限速),观察主库
log file sync等待是否明显升高 —— 不升高的AFFIRM就是假的
真正难察觉的是:当 AFFIRM 因底层 I/O 或网络问题退化为“伪同步”,监控和日志都看似正常,但极端故障点(主库崩溃 + 网络中断 + 备库未落盘)下那几秒 redo 就永远消失了。这种边界情况,靠配置检查很难覆盖,得结合压力测试和故障注入验证。


















