查看原文
其他

Oracle 19c 新特性 |ADG 备库支持 DML 重定向

JiekeXu JiekeXu DBA之路 2024-03-03

作者 | JiekeXu

来源 |公众号 JiekeXu DBA之路(ID: JiekeXu_IT)

如需转载请联系授权 | (个人微信 ID:JiekeXu_DBA)

大家好,我是 JiekeXu,很高兴又和大家见面了,今天和大家一起来学习 Oracle 19c 新特性 |ADG 备库支持 DML 重定向,欢迎点击上方蓝字关注我,标星或置顶,更多干货第一时间到达!

在 Oracle 19c 中有众多的新特性,Oracle 官方上有一个专门收集新特性的网站,从 11g 到 21c 均有涉及,并且每一个新特性都对应了官方文档,仅 19c 新特性就有 118 个。

(https://apex.oracle.com/database-features/)

在 19c 版本中,ADG 中的备库(PS:19c ADG 备库搭建可点击此处链接查看)支持 DML 操作,原理是:是通过将备库上的 DML 重定向到主库上执行,然后备库应用 DML 变化数据,至此完成备库 DML 操作

DML 重定向整体的步骤如下:
1.备库的客户端发起 DML 操作。
2.备库的 DML
操作通过内部的 dblink 被重定向到主库执行。
3.DML
语句在主库被实施。
4.
主库生成更改的 redo log 传到备库。
5.
备库应用此日志完成 DML 重定向,客户端显示修改后的数据信息。

这个新特性的功能是: 将偶然发送到 ADG上的DML操作,自动转发到主库执行,然后通过主库日志传递到备库实时应用,在保证了ACID的前提下,大大增强了备库的实用性,这被称为 DML Redirection 这个功能其实在 18c 就已经支持了,在 18c 是作为隐含参数 _enable_proxy_adg_redirect 调整的,在 19c 中,通过显式参数 ADG_REDIRECT_DML 参数调整。官方文档中描述如下:

您可以在 Active Data Guard 备用数据库上运行 DML 操作。这使您能够在备用数据库上运行以读取为主的应用程序,这些应用程序偶尔会执行 DML。

备用数据库上的 DML 操作可以透明地重定向到主数据库并在其上运行。这包括作为 PL/SQL 块一部分的 DML 语句。Active Data Guard 会话一直等待,直到相应的更改被传送并应用到 Active Data Guard 备用数据库。在 DML 操作期间保持读取一致性,运行 DML 的备用数据库可以查看其未提交的更改。但是,所有其他备用数据库实例只有在事务提交后才能查看这些更改。

避免在 Active Data Guard 备用数据库上运行过多的 DML 操作。因为这些操作实际上是在主节点上执行的,所以过多的 DML 可能会影响主节点的性能。Active Data Guard 备用数据库不支持 Oracle XA 事务中的 DML 操作。

可以在系统级别或会话级别配置 DML 操作到主服务器的自动重定向。会话级别设置覆盖系统级别设置。

要为 Active Data Guard 环境中的所有备用会话配置 DML 操作的自动重定向:

  • ADG_REDIRECT_DML 初始化参数设置为 TRUE

要为当前会话配置 DML 操作的自动重定向,请使用以下命令:

  • ALTER SESSION ENABLE ADG_REDIRECT_DML;

下面一起看看具体的例子:

--19c 实时同步的 ADG 环境sqlplus / as sysdbaSQL*Plus: Release 19.0.0.0.0 - Productionon Fri Jul 29 11:34:04 2022Version 19.15.0.0.0Copyright (c) 1982, 2022, Oracle.All rights reserved.Connected to:Oracle Database 19c Enterprise EditionRelease 19.0.0.0.0 - ProductionVersion 19.15.0.0.0SQL> selectINST_ID,open_mode,LOG_MODE,DATABASE_ROLE,PROTECTION_MODE fromgv$database;INST_ID OPEN_MODE LOG_MODE DATABASE_ROLE PROTECTION_MODE---------- -------------------------------- ---------------- --------------------1 READ ONLY WITH APPLY ARCHIVELOG PHYSICAL STANDBY MAXIMUM PERFORMANCEElapsed: 00:00:00.03SQL> set lin 1000SQL> set pagesize 20;column name format a13;SQL> SQL> column value format a20;column unit format a30;column TIME_COMPUTED format a30;select name,value,unit,time_computed fromv$dataguard_stats where name in ('transport lag','apply lag');SQL> SQL> SQL>NAMEVALUE UNIT DATUM_TIME TIME_COMPUTED------------- -------------------------------------------------- ------------------------------------------------------------transport lag +00 00:00:00 day(2) to second(0) interval 07/29/2022 14:43:21 07/29/2022 14:43:22apply lag +00 00:00:00 day(2) to second(0) interval 07/29/2022 14:43:21 07/29/2022 14:43:22


一、会话级别修改参数

进行 DDL 操作,备库只读,必然会报错。

SQL> create table test1 (id int,namevarchar2(20));create table test1 (id int,namevarchar2(20))*ERROR at line 1:ORA-16000: database or pluggable databaseopen for read-only accessSQL> show parameter ADG_REDIRECT_DMLNAMETYPE VALUE----------------------------------------------- ------------------------------adg_redirect_dmlboolean FALSESQL> show userUSER is "SYS"


前面说了 DML 重定向参数可以有会话级别和实例级别的设置。自动重定向 DML 操作 ADG_REDIRECT_DML 参数支持会话级别和系统级别,会话级别会覆盖系统级别配置。

1)SYS 系统级别

然后先在 SYS、SYSTEM 用户上尝试会话级别的 DML 重定向功能。

--当前会话启用 DML 重定向ALTER SESSION ENABLE ADG_REDIRECT_DML;

DDL 语句不支持


DML 语句报错 ORA-16397


System 进行测试,DDL 还是和预想的一样不能执行,但 DML 语句是支持的,insert 一条数据已经插入到 test 用户下。


2)普通用户级别

在普通用户上尝试


SQL> insert into T_TMP_USER_JIEKE values(2,'jieke','select 1 from dual;','DML');insert into T_TMP_USER_JIEKE values(2,'jieke','select 1 from dual;','DML')*ERROR at line 1:ORA-01157: cannotidentify/lock data file 2049 - see DBWR trace fileORA-01110: data file 2049: '/data/jiekedbstb/tempfile/temp.280.1104593777

此错误是由于备库刚搭建完成,临时表空间文件没有在备库生成,建立相应的目录,重启备库则会自动生成临时表空间文件。

$ ll/data/jiekedbstb/tempfile/temp.280.1104593777ls: cannot access/data/jiekedbstb/tempfile/temp.280.1104593777: No such file or directory$ cd /data/jiekedbstb/tempfile-bash: cd: /data/jiekedbstb/tempfile: Nosuch file or directorymkdir -p /data/jiekedbstb/tempfile15:34:27 SQL> shu immediateDatabase closed.Database dismounted.ORACLE instance shut down.15:34:58 SQL> startupORACLE instance started.Total System Global Area 1.2885E+10 bytesFixed Size13629520 bytesVariable Size3858759680 bytesDatabase Buffers8992587776 bytesRedo Buffers19922944 bytesDatabase mounted.Database opened.SQL> ALTER DATABASE RECOVER MANAGEDSTANDBY DATABASE DISCONNECT;SQL> select name,value,unit,datum_time,time_computed from v$dataguard_stats where name in('transport lag','apply lag');

普通用户 DML 可以正常插入。


二、系统级别修改参数

在备库上启用 DML 重定向将初始化参数 ADG_REDIRECT_DML 设置为 true。

ALTER SYSTEM SET ADG_REDIRECT_DML=true SCOPE=BOTH;

登录普通用户可以进行数据插入的操作。

17:23:34 SQL> conn test/TESTConnected.17:23:39 SQL>17:23:40 SQL> select * from tab;TNAME TABTYPE CLUSTERID--------------------------------------------------------------------------------------------------------------------------------------------- ----------T_TMP_USER_JIEKE TABLEElapsed: 00:00:00.0117:23:49 SQL> insert intoT_TMP_USER_JIEKE values (5,'jieke','select 5 from dual;','DML');1 row created.Elapsed: 00:00:00.1017:25:43 SQL> commit;Commit complete.

现在来试试  sys 系统用户,执行 DML 操作。

先在主库创建一张 test.t1表,然后到备库去做 DML 操作。

SQL> create table test.t1 as select *from dba_objects;Table created.SQL> select count(*) from test.t1;COUNT(*)----------138662SQL> select min(OBJECT_ID) from test.t1;MIN(OBJECT_ID)--------------2

然后在备库 SYS 用户执行报错  ORA-16397

SQL> select min(OBJECT_ID) from test.t1;MIN(OBJECT_ID)--------------2Elapsed: 00:00:00.04SQL> show userUSER is "SYS"SQL> delete from test.t1 where OBJECT_ID=2;delete from test.t1 where OBJECT_ID=2*ERROR at line 1:ORA-16397: statement redirection fromOracle Active Data Guard standby database to primary database failed

报错原因:不支持 SYS 用户会话级别启用 DML 重定向,当然 19c 本身 SYS 用户下新建表也不会同步到备库,那么来试试 SYSTEM.

那么使用 system 用户主库建个表测试一下

SQL> conn system/OracleSQL> Connected.SQL> create table system.test1 (idint,name varchar2(20));Table created.SQL> select * from system.test1;no rows selectedSQL> insert into system.test1values(1,'jiekexu');1 row created.SQL> commit;Commit complete.SQL>select * from system.test1;ID NAME---------- --------------------1 jiekexu

备库:

SQL> show userUSER is "SYSTEM"SQL>SQL> select INST_ID,open_mode,LOG_MODE,DATABASE_ROLE,PROTECTION_MODEfromgv$database;INST_ID OPEN_MODE LOG_MODE DATABASE_ROLE PROTECTION_MODE---------- -------------------------------- ---------------- --------------------1 READ ONLY WITH APPLY ARCHIVELOG PHYSICAL STANDBY MAXIMUM PERFORMANCESQL> insert into system.test1values(2,'jieke');1 row created.Elapsed: 00:00:00.13SQL> commit;


三、跟踪 10046 trace 查看具体过程

--主库:grant alter session to test;--备库:alter session set events '10046 trace name context forever ,level 12';insert into TEST.T_TMP_USER_JIEKE values(7,'dba','select 7 from dual;','DML');alter session set events '10046 trace name context off';
select distinct(m.sid),p.pid,p.tracefile from v$mystat m,v$session s,v$process p where m.sid=s.sid and s.paddr=p.addr;--有可能这样没有找到对应的 trace,使用下面的方法。alter session set tracefile_identifier='10046TEST';alter session set events '10046 trace name context forever ,level 12';insert into TEST.T_TMP_USER_JIEKE values(7,'dba','select 7 from dual;','DML');alter session set events '10046 trace name context off';


通过后台的跟踪日志,可以看到,DML 操作是通过 DB Link 来重定向到主库执行的,这个DB Link 是内部的,在服务名等配置正常情况下,Oracle 能够自动完成内部操作。

=====================PARSING IN CURSOR#140321356468712 len=78 dep=0 uid=108 oct=2 lid=108 tim=1559487590897hv=406207236 ad='ff8871b0' sqlid='13fa7w4c3cfs4'insert into TEST.T_TMP_USER_JIEKEvalues(8,'dba','select 8 from dual;','DML')END OF STMTPARSE #140321356468712:c=4647,e=5629,p=0,cr=2,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=1559487590896WAIT#140321356468712: nam='SQL*Net message to dblink' ela= 2 driver id=1413697536#bytes=1 p3=0 obj#=-1 tim=1559487591138WAIT#140321356468712: nam='SQL*Net message from dblink' ela= 3224 driverid=1413697536 #bytes=1 p3=0 obj#=-1 tim=1559487594416EXEC#140321356468712:c=500,e=3530,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=0,tim=1559487594523WAIT#140321356468712: nam='PGA memory operation' ela= 60 p1=0 p2=0 p3=0 obj#=-1tim=1559487594671WAIT#140321356468712: nam='SQL*Net message to client' ela= 3 driver id=1650815232#bytes=1 p3=0 obj#=-1 tim=1559487594720WAIT#140321356468712: nam='SQL*Net message from client' ela= 479 driverid=1650815232 #bytes=1 p3=0 obj#=-1 tim=1559487595229PARSE#140321356505176:c=50,e=50,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=1559487595377BINDS#140321356505176:



tkprof 格式化输出

tkprof /u01/app/oracle/diag/rdbms/jiekedbstb/jiekedbstb/trace/jiekedbstb_ora_4372.trc ./adg_dml.log


通过格式化输出后可以明显看到 insert 后调用了 dblink,DML 操作通过内部的 DBLink 到主库执行后应用日志到备库再将结果返回到备库客户端。

除了常规表之外,Oracle 还支持在备库创建全局临时表,执行 PL/SQL 等操作,可以在 Active Data Guard 备用数据库上创建和删除全局临时表。这些操作的 DDL 被透明地重定向到主数据库。然后,Active Data Guard 会话将等待相应的更改发送并应用到 Active Data Guard 备用服务器。在 19c 中,隐含参数 _alter_adg_redirect_behavior 可以用于定义允许重定向的级别,例如当设置为 disallow_gtt 将不允许重定向全局临时表。


全文完,希望可以帮到正在阅读的你,如果觉得有帮助,可以分享给你身边的朋友,同事,你关心谁就分享给谁,一起学习共同进步~~~


❤️ 欢迎关注我的公众号,一起学习新知识!!!

————————————————————————————
公众号:JiekeXu DBA之路
墨天轮:https://www.modb.pro/u/4347
CSDN :https://blog.csdn.net/JiekeXu
腾讯云:https://cloud.tencent.com/developer/user/5645107
————————————————————————————



Oracle 表碎片检查及整理方案

OGG|Oracle GoldenGate 基础

2021 年公众号历史文章合集整理

2020 年公众号历史文章合集整理

我的 2021 年终总结和 2022 展望

Oracle 19c RAC 遇到的几个问题

利用 OGG 迁移 Oracle11g 到 19C

OGG|Oracle GoldenGate 微服务架构

Oracle 查询表空间使用率超慢问题一则

国产数据库|TiDB 5.4 单机快速安装初体验

Oracle ADG 备库停启维护流程及增量恢复

Linux 环境搭建 MySQL8.0.28 主从同步环境

继续滑动看下一个

Oracle 19c 新特性 |ADG 备库支持 DML 重定向

JiekeXu JiekeXu DBA之路
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存