首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Every Day of a DBA,第153期: Oracle 19c Active Data Guard-DML Redirection

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

作者头像
用户3107127
发布2026-07-20 21:15:57
发布2026-07-20 21:15:57
280
举报

1. 功能概述

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

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

适用场景

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

2. 工作原理

代码语言:javascript
复制
┌─────────────────────────────────────────────────────────────┐
│                      应用层(客户端)                          │
│         连接备库,发出 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 验证备库状态

代码语言:javascript
复制
-- 在备库执行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 主库配置

代码语言:javascript
复制
SQL>show parameter adg_redirect_dml
 NAME                     TYPE          VALUE
 ———————————— ———– ——————————
 adg_redirect_dml            boolean       FALSE

SQL>altersystemset adg_redirect_dml=true scope=both;
System altered.

SQL>show parameter adg_redirect_dml

NAME            TYPE          VALUE
 ———————————— ———– ——————————
 adg_redirect_dml  boolean        TRUE

5.2 备库配置

代码语言:javascript
复制
SQL>show parameter adg_redirect_dml
 NAME                     TYPE          VALUE
 ———————————— ———– ——————————
 adg_redirect_dml            boolean       FALSE

SQL>altersystemset adg_redirect_dml=true scope=both;
System altered.

SQL>show parameter adg_redirect_dml

NAME            TYPE          VALUE
 ———————————— ———– ——————————
 adg_redirect_dml  boolean        TRUE

5.3 会话级别控制(可选)

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

代码语言:javascript
复制
-- 在当前会话启用 DML 重定向(会覆盖系统级设置)
ALTERSESSIONENABLE ADG_REDIRECT_DML;
-- 在当前会话禁用 DML 重定向
ALTERSESSIONDISABLE ADG_REDIRECT_DML;

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

6. 功能测试

6.1 在主库创建测试表

代码语言:javascript
复制
-- 连接主库(用户名/密码方式)
sqlplus sys/oracle@primaryas sysdba

-- 创建测试表
CREATETABLE oracle_dml_test (
    name    VARCHAR2(50),
    testdate TIMESTAMP
);

-- 插入测试数据
INSERTINTO oracle_dml_test VALUES('主库写入测试', SYSDATE);
INSERTINTO oracle_dml_test VALUES('初始数据', SYSDATE);

COMMIT;

-- 验证
SELECT*FROM oracle_dml_test;

6.2 在备库验证数据已同步

代码语言:javascript
复制
-- 连接备库(必须使用用户名/密码方式,不可用 / as sysdba)
sqlplus sys/oracle@standbyas sysdba

-- 查看主库创建的表和数据是否已同步(可能在备库需要完全路径或等待 apply 延迟)
SELECT*FROM oracle_dml_test;

-- 确认备库状态
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;

SELECTSTATUS, INSTANCE_NAME, DATABASE_ROLE, PROTECTION_MODE 
FROM V$DATABASE, V$INSTANCE;

预期输出:

代码语言:javascript
复制
DATABASE_ROLE         OPEN_MODE
-------------------- --------------------
PHYSICAL STANDBY     READ ONLY WITH APPLY

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

代码语言:javascript
复制
-- 连接备库(用户名/密码,非 SYS 用户优先)
sqlplus test_user/test_pass@standby

-- 在备库执行 DELETE 操作(将会被透明重定向到主库)
DELETEFROM oracle_dml_test WHERE name ='初始数据';

-- 显示受影响行数
-- 输出: 1 row deleted.

-- 提交事务
COMMIT;

-- 再次查询,确认读一致性
SELECT*FROM oracle_dml_test;

6.4 在主库验证变更已生效

代码语言:javascript
复制
-- 连接主库
sqlplus sys/oracle@primaryas sysdba

-- 验证数据已从备库删除
SELECT*FROM oracle_dml_test;

-- 预期:'初始数据' 行已不存在,DML 重定向成功

7. 高级测试场景

7.1 PL/SQL 块中的 DML 重定向

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

代码语言:javascript
复制
-- 在备库执行
BEGIN
    INSERTINTO oracle_dml_test VALUES('PL/SQL 插入测试', SYSDATE);
    UPDATE oracle_dml_test SET name ='PL/SQL 已更新'WHERE name ='PL/SQL 插入测试';
    COMMIT;
END;
/

7.2 事务一致性验证

代码语言:javascript
复制
-- 备库:插入后未提交,本会话可看到
INSERTINTO oracle_dml_test VALUES('未提交数据', SYSDATE);
SELECT*FROM oracle_dml_test;  -- 可以看到新行

-- 另开一个备库会话(同一事务未提交前),看不到新行

7.3 多表联合 DML

代码语言:javascript
复制
-- 备库执行多表操作
INSERTINTO oracle_dml_test VALUES('多表测试A', SYSDATE);
UPDATE oracle_dml_test SET testdate = SYSDATE WHERE name LIKE'多表%';
DELETEFROM oracle_dml_test WHERE name ='多表测试A';
COMMIT;

8. 监控与诊断

8.1 查看 DML 重定向状态

代码语言:javascript
复制
-- 当前会话是否启用 DML 重定向
SELECT SYS_CONTEXT('USERENV','ADG_REDIRECT_DML')AS adg_redirect_enabled FROMDUAL;

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

代码语言:javascript
复制
-- 查看 DML 重定向相关等待事件
SELECTevent, total_waits, time_waited, average_waitFROM V$SYSTEM_EVENTWHERE eventLIKE'%ADG%'OReventLIKE'%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 错误

代码语言:javascript
复制
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 无反应

代码语言:javascript
复制
-- 检查备库是否启用了 DML 重定向
ALTERSESSIONENABLE ADG_REDIRECT_DML;

-- 检查连接方式
SELECT SYS_CONTEXT('USERENV','AUTHENTICATION_METHOD')FROMDUAL;
-- 应返回非 SYSDBA 认证方式

问题 3:DML 性能缓慢

  • 检查主备之间的 网络延迟 和 带宽
  • 检查备库的 Redo Apply 速率
  • 使用 V$ADG_STATS 视图诊断同步延迟
代码语言:javascript
复制
-- 查看 ADG 同步状态
SELECT NAME,VALUE, TIME_COMPUTED, DATUM_TIME 
FROM V$ADG_STATS 
WHERE NAME LIKE'%lag%';
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ByteHouse 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 功能概述
    • 适用场景
  • 2. 工作原理
    • 详细流程
    • 关键特性
  • 3. 核心优势
  • 4. 前提条件
    • 4.1 环境要求
    • 4.2 限制说明
    • 4.3 验证备库状态
  • 5. 启用配置
    • 5.1 主库配置
    • 5.2 备库配置
    • 5.3 会话级别控制(可选)
  • 6. 功能测试
    • 6.1 在主库创建测试表
    • 6.2 在备库验证数据已同步
    • 6.3 在备库执行 DML 重定向测试
    • 6.4 在主库验证变更已生效
  • 7. 高级测试场景
    • 7.1 PL/SQL 块中的 DML 重定向
    • 7.2 事务一致性验证
    • 7.3 多表联合 DML
  • 8. 监控与诊断
    • 8.1 查看 DML 重定向状态
    • 8.2 查询重定向相关的等待事件
    • 8.3 重定向错误诊断
  • 9. 最佳实践与注意事项
    • ✅ 最佳实践
    • ❌ 注意事项
  • 10. 故障排除
    • 问题 1:ORA-16397 错误
    • 问题 2:备库 DML 无反应
    • 问题 3:DML 性能缓慢
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档