暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

Every Day of a DBA,第153期: Oracle 19c Active Data Guard-DML Redirection

原创 ByteHouse 4天前
22

1. 功能概述

Active Data Guard DML 重定向 是 Oracle 19c 引入的一项重要新特性,允许在 物理备库(Physical Standby) 上直接执行 DML 操作(INSERT、UPDATE、DELETE)。当用户在备库上发起 DML 时,操作会被 透明地重定向 到主库执行,产生的 Redo 日志再传回备库应用,最终将结果返回给客户端。

此特性使得备库不再仅限于只读查询,而是可以承载 “偶尔写入” 的混合工作负载,真正实现 Read-Mostly 架构。

适用场景

  • 备库上运行的只读应用程序偶尔需要执行少量 DML(如更新状态、插入日志)
  • 希望减轻主库上大量只读会话的并发压力
  • 应用代码无法修改连接字符串,但需要备库具备有限写入能力
  • 报表系统需要在查询中间结果时写入临时标记

2. 工作原理

img

┌─────────────────────────────────────────────────────────────┐ │ 应用层(客户端) │ │ 连接备库,发出 DML 语句(INSERT/UPDATE/DELETE) │ └──────────────────────┬──────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Active Data Guard 备库 │ │ │ │ ① 接收 DML 请求 │ │ ② 自动检测是否为 DML 操作 │ │ ③ 将 DML 重定向到主库(透明,应用无感知) │ │ ④ 等待主库执行完毕并传回 Redo │ │ ⑤ Redo 应用后,返回结果给客户端 │ └──────────────────────┬──────────────────────────────────────┘ │ 重定向 (ADG_REDIRECT_DML) ▼ ┌─────────────────────────────────────────────────────────────┐ │ 主库(Primary) │ │ │ │ ① 接收来自备库的重定向 DML │ │ ② 在本地执行 DML 操作 │ │ ③ 生成 Redo 日志 │ │ ④ 按 Data Guard 同步策略传送到备库 │ └─────────────────────────────────────────────────────────────┘

详细流程

步骤 说明
1 客户端连接到备库,发起 DML 语句(INSERT / UPDATE / DELETE)
2 备库检测到 DML 操作,通过 ADG_REDIRECT_DML 机制将其 透明重定向 到主库
3 主库执行该 DML,生成 Redo 日志,提交事务
4 主库将 Redo 传输到备库,MRP(Managed Recovery Process)应用 Redo
5 备库应用变更后,返回成功结果给客户端,DML 会话期间保持读一致性

关键特性

  • 透明性:应用无需修改代码或连接字符串
  • 读一致性:DML 会话中的未提交更改,在该会话内可查询到(其他会话需等待提交后)
  • 等待语义:备库会话会 同步等待 直到数据变更被传回并应用到备库后才返回
  • ACID 保障:事务的原子性、一致性、隔离性、持久性完全保持

3. 核心优势

优势 说明
🔄 Read-Mostly 负载分担 备库可同时处理只读查询和偶发写入,分担主库压力
⚡ 减少主库压力 大量的 SELECT 查询转移到备库,主库专注处理写入
🔌 无需修改应用 备库 DML 对应用完全透明,连接字符串无需变更
✅ 完整 ACID 保障 事务特性完全保留,数据一致性有保障
🛡️ 高可用增强 备库在容灾之外获得更多实用价值

4. 前提条件

在启用 DML 重定向之前,必须满足以下条件:

4.1 环境要求

条件 要求
Oracle 版本 19c 或更高版本(19.0.0.0.0 及以上)
Data Guard 配置 已配置 Data Guard Broker(建议)
备库状态 物理备库,处于 READ ONLY WITH APPLY 模式
网络连接 主库和备库之间网络通畅,连接字符串可用

4.2 限制说明

⚠️ 重要限制

  • SYS 用户不支持:SYS 用户连接备库时无法使用 DML 重定向
  • Oracle XA 事务不支持:分布式 XA 事务中的 DML 无法重定向
  • 重定向量建议 < 10%:所有备库 DML 最终在主库执行,过多会冲击主库性能
  • 连接方式限制:必须使用 用户名/密码 方式登录(sqlplus user/pass@standby),不能使用 / as sysdba
  • DDL 不支持:重定向仅限 DML(INSERT/UPDATE/DELETE/MERGE),DDL(CREATE/ALTER/DROP)需要直接在主库执行

4.3 验证备库状态

-- 在备库执行SELECT OPEN_MODE, DATABASE_ROLE, SWITCHOVER_STATUS, PROTECTION_MODE, FLASHBACK_ON FROM V$DATABASE;

预期输出:

  • OPEN_MODE = READ ONLY WITH APPLY
  • DATABASE_ROLE = PHYSICAL STANDBY

5. 启用配置

参数 ADG_REDIRECT_DML 默认值为 FALSE。需要在 主库和备库两端 都设置为 TRUE

5.1 主库配置

SQL> show parameter adg_redirect_dml NAME TYPE VALUE ———————————— ———– —————————— adg_redirect_dml boolean FALSE SQL> alter system set adg_redirect_dml=true scope=both; System altered. SQL> show parameter adg_redirect_dml NAME TYPE VALUE ———————————— ———– —————————— adg_redirect_dml boolean TRUE

5.2 备库配置

SQL> show parameter adg_redirect_dml NAME TYPE VALUE ———————————— ———– —————————— adg_redirect_dml boolean FALSE SQL> alter system set adg_redirect_dml=true scope=both; System altered. SQL> show parameter adg_redirect_dml NAME TYPE VALUE ———————————— ———– —————————— adg_redirect_dml boolean TRUE

5.3 会话级别控制(可选)

若仅需单个会话启用,而非全局启用:

-- 在当前会话启用 DML 重定向(会覆盖系统级设置) ALTER SESSION ENABLE ADG_REDIRECT_DML; -- 在当前会话禁用 DML 重定向 ALTER SESSION DISABLE ADG_REDIRECT_DML;

优先级:会话级设置 > 系统级设置

6. 功能测试

6.1 在主库创建测试表

-- 连接主库(用户名/密码方式) sqlplus sys/oracle@primary as sysdba -- 创建测试表 CREATE TABLE oracle_dml_test ( name VARCHAR2(50), testdate TIMESTAMP ); -- 插入测试数据 INSERT INTO oracle_dml_test VALUES ('主库写入测试', SYSDATE); INSERT INTO oracle_dml_test VALUES ('初始数据', SYSDATE); COMMIT; -- 验证 SELECT * FROM oracle_dml_test;

6.2 在备库验证数据已同步

-- 连接备库(必须使用用户名/密码方式,不可用 / as sysdba) sqlplus sys/oracle@standby as sysdba -- 查看主库创建的表和数据是否已同步(可能在备库需要完全路径或等待 apply 延迟) SELECT * FROM oracle_dml_test; -- 确认备库状态 SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE; SELECT STATUS, INSTANCE_NAME, DATABASE_ROLE, PROTECTION_MODE FROM V$DATABASE, V$INSTANCE;

预期输出:

DATABASE_ROLE         OPEN_MODE
-------------------- --------------------
PHYSICAL STANDBY     READ ONLY WITH APPLY

6.3 在备库执行 DML 重定向测试

-- 连接备库(用户名/密码,非 SYS 用户优先) sqlplus test_user/test_pass@standby -- 在备库执行 DELETE 操作(将会被透明重定向到主库) DELETE FROM oracle_dml_test WHERE name = '初始数据'; -- 显示受影响行数 -- 输出: 1 row deleted. -- 提交事务 COMMIT; -- 再次查询,确认读一致性 SELECT * FROM oracle_dml_test;

6.4 在主库验证变更已生效

-- 连接主库 sqlplus sys/oracle@primary as sysdba -- 验证数据已从备库删除 SELECT * FROM oracle_dml_test; -- 预期:'初始数据' 行已不存在,DML 重定向成功

7. 高级测试场景

7.1 PL/SQL 块中的 DML 重定向

备库上的 PL/SQL 块中包含的 DML 同样会被重定向:

-- 在备库执行 BEGIN INSERT INTO oracle_dml_test VALUES ('PL/SQL 插入测试', SYSDATE); UPDATE oracle_dml_test SET name = 'PL/SQL 已更新' WHERE name = 'PL/SQL 插入测试'; COMMIT; END; /

7.2 事务一致性验证

-- 备库:插入后未提交,本会话可看到 INSERT INTO oracle_dml_test VALUES ('未提交数据', SYSDATE); SELECT * FROM oracle_dml_test; -- 可以看到新行 -- 另开一个备库会话(同一事务未提交前),看不到新行

7.3 多表联合 DML

-- 备库执行多表操作 INSERT INTO oracle_dml_test VALUES ('多表测试A', SYSDATE); UPDATE oracle_dml_test SET testdate = SYSDATE WHERE name LIKE '多表%'; DELETE FROM oracle_dml_test WHERE name = '多表测试A'; COMMIT;

8. 监控与诊断

8.1 查看 DML 重定向状态

-- 当前会话是否启用 DML 重定向 SELECT SYS_CONTEXT('USERENV', 'ADG_REDIRECT_DML') AS adg_redirect_enabled FROM DUAL;

8.2 查询重定向相关的等待事件

-- 查看 DML 重定向相关等待事件 SELECT event, total_waits, time_waited, average_waitFROM V$SYSTEM_EVENTWHERE event LIKE '%ADG%' OR event LIKE '%redirect%';

8.3 重定向错误诊断

常见错误代码:

错误码 说明 解决方案
ORA-16397 从备库到主库的语句重定向失败 检查主库连通性和 ADG_REDIRECT_DML 参数
ORA-00604 递归 SQL 级别 1 发生错误 通常因使用 / as sysdba 连接导致,改用用户名/密码
ORA-16000 备库上不支持的操作 确认操作类型为 DML(非 DDL)

9. 最佳实践与注意事项

✅ 最佳实践

实践 说明
控制重定向占比 < 10% 备库 DML 最终在主库执行,过多 DML 会冲击主库性能
使用非 SYS 用户 创建专用应用用户执行备库 DML,避免 SYS 限制
监控主库负载 关注主库的 DB TIME 和 Redo 生成速率
设置合理的网络延迟阈值 重定向对网络延迟敏感,建议主备之间延迟 < 5ms
优先使用会话级别启用 默认关闭,仅对需要的会话启用,减少意外 DML 风险
测试环境中充分验证 上线前模拟备库 DML 压力,确认主库可承受

❌ 注意事项

  1. DDL 不会重定向 — 表结构变更仍需在主库执行
  2. 序列(Sequence)不重定向 — 在备库访问序列需在主库预先处理
  3. 临时表 — 全局临时表在备库行为可能不同,需仔细测试
  4. 主备延迟影响 — 如果主备之间有较大 Redo 应用延迟,DML 操作等待时间会增加
  5. Data Guard Broker — 建议使用 Broker 管理,Broker 故障切换后参数会自动同步
  6. 版本兼容性 — 主备库必须同为 19c,且版本补丁级别一致

10. 故障排除

问题 1:ORA-16397 错误

ORA-16397: statement redirection from Oracle Active Data Guard standby database to primary database failed

排查步骤:

  1. 检查主库和备库的 ADG_REDIRECT_DML 参数是否都为 TRUE
  2. 确认备库处于 READ ONLY WITH APPLY 模式
  3. 测试主备之间数据库连接是否正常
  4. 确认未使用 / as sysdba 连接备库

问题 2:备库 DML 无反应

-- 检查备库是否启用了 DML 重定向 ALTER SESSION ENABLE ADG_REDIRECT_DML; -- 检查连接方式 SELECT SYS_CONTEXT('USERENV', 'AUTHENTICATION_METHOD') FROM DUAL; -- 应返回非 SYSDBA 认证方式

问题 3:DML 性能缓慢

  • 检查主备之间的 网络延迟 和 带宽
  • 检查备库的 Redo Apply 速率
  • 使用 V$ADG_STATS 视图诊断同步延迟
-- 查看 ADG 同步状态 SELECT NAME, VALUE, TIME_COMPUTED, DATUM_TIME FROM V$ADG_STATS WHERE NAME LIKE '%lag%';
最后修改时间:2026-07-18 18:05:16
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论