SYNC和ASYNC是LOG_ARCHIVE_DEST_n中控制日志传输行为的关键属性,本质区别在于事务提交前是否等待备库AFFIRM确认写入SRL:SYNC阻塞提交以实现RPO=0,ASYNC不等待以保主库性能。
同步(sync)和异步(async)不是独立的“模式”,而是 log_archive_dest_n 参数中决定日志传输行为的关键属性,必须配合保护模式(maximum availability / maximum protection / maximum performance)使用。直接改 sync 或 async 而不调保护模式,数据库会拒绝生效或行为不可预期。
SYNC 和 ASYNC 的本质区别在哪
它们控制的是主库事务提交前,是否等待备库确认收到并写入 Standby Redo Log:
-
SYNC:主库用LGWR进程实时推送 redo,并阻塞提交,直到至少一个备库返回AFFIRM(即已落盘到 standby redo log)。RPO = 0,但网络抖动或备库 IO 慢会拖慢主库 TP99。 -
ASYNC:主库用ARCH或LGWR异步发送归档/redo,事务提交不等待备库响应。主库性能几乎无损,但故障时可能丢失未传完的 redo(RPO > 0)。
注意:SYNC 必须搭配 AFFIRM;ASYNC 必须搭配 NOAFFIRM。混搭如 SYNC NOAFFIRM 是非法组合,Oracle 启动时会报错 ORA-16025。
如何根据业务容忍度选对保护模式 + 传输属性
别只盯着 SYNC/ASYNC —— 真正起作用的是保护模式,它强制绑定了传输行为和故障策略:
- 要 RPO=0 且能接受主库可能挂(比如核心账务系统双机房强一致)→ 用
MAXIMUM PROTECTION,它隐含要求LGWR SYNC AFFIRM,且备库必须有 standby redo log。 - 要 RPO=0 但主库绝不能停(比如电商主站,备库断了也得继续卖)→ 用
MAXIMUM AVAILABILITY,它默认走LGWR SYNC AFFIRM,但备库失联时自动降级为ASYNC行为,不 shutdown 主库。 - 主库性能敏感、允许丢几分钟数据(比如报表库、日志分析库)→ 用默认的
MAXIMUM PERFORMANCE,对应ARCH ASYNC NOAFFIRM或LGWR ASYNC NOAFFIRM。
执行切换前,必须确保:STANDBY REDO LOG 在备库已创建(ALTER DATABASE ADD STANDBY LOGFILE),否则 SYNC 类模式启动即报 ORA-01271。
实操:修改主库日志传输参数与保护模式
以从 MAXIMUM PERFORMANCE 升级到 MAXIMUM AVAILABILITY 为例(最常用升级路径):
- 在主库上确认当前状态:
SELECT DATABASE_ROLE, PROTECTION_MODE FROM V$DATABASE; - 停备库的 MRP 进程:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; - 主库修改归档目标(示例):
ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=standby_db LGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby_db'; - 主库切保护模式(需 MOUNT 状态):
SHUTDOWN IMMEDIATE; STARTUP MOUNT; ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE AVAILABILITY; ALTER DATABASE OPEN; - 重启备库 MRP:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;
关键陷阱:LOG_ARCHIVE_DEST_2 中的 SERVICE 名必须与 TNSNAMES.ORA 里定义的服务名完全一致(大小写敏感),拼错会导致 ORA-12514,且错误日志只出现在 ALERT.LOG,不会报给 SQL*Plus。
为什么改完参数后 V$DATABASE.PROTECTION_MODE 没变
常见原因有三个:
- 没在
MOUNT状态下执行ALTER DATABASE SET STANDBY DATABASE TO ...—— Oracle 会静默忽略该语句,不报错也不生效; - 备库还没启动到
MANAGED RECOVERY状态,主库检测不到有效备库,保护模式无法进入 SYNC 分支; -
LOG_ARCHIVE_DEST_n中的VALID_FOR值设错了,例如写成VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE),主库角色下该目标被跳过。
验证是否真生效:查 V$ARCHIVE_DEST_STATUS,看目标状态是否为 VALID 且 TRANSMISSION_MODE 显示 SYNC 或 ASYNC;再查 V$DATAGUARD_STATS 中的 transport lag 和 apply lag,SYNC 模式下 transport lag 应长期稳定在几秒内,突增说明链路已退化。











