转 OGG add trandata 到底做了什么

本文详细解析了Oracle GoldenGate (OGG) 中addtrandata命令的工作原理及其可能引起的阻塞问题,尤其针对如何避免在开启附加日志时出现异常情况进行了深入探讨。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

有的时候我们做OGG的时候add trandata会出现异常。
 这里就剖析一下add trandata到底做了什么
GGSCI (yjfora81 as ggs_admin@testdb) 2> add trandata ppzhu1.test3
2016-03-08 11:47:36  WARNING OGG-00706  Failed to add supplemental log group on table PPZHU1.TEST3 due to ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired SQL ALTER TABLE “PPZHU1″.”TEST3″ ADD SUPPLEMENTAL LOG GROUP “GGS_87926″ (“USER_ID”) ALWAYS  /* GOLDENGATE_DDL_REPLICATION */.
然后一直hang住

使用OGG用户登陆我的用户GGS_ADMIN

GGSCI (yjfora81) 1> dblogin userid ggs_admin,password test;
 Successfully logged into database.

SQL> select SID , SERIAL# ,PADDR  from v$session where USERNAME=’GGS_ADMIN';
        SID    SERIAL# PADDR
———- ———- —————-
       145         15 00000001BE185360
 SQL> select pid,spid from v$process where addr=’00000001BE185360′;
        PID SPID
———- ————————
        37 40986
         
找到SPID和pid  OS PID是40986数据库的pid是37
我们用37 进行ORADEBUG

SQL> oradebug SETORAPID 37
Oracle pid: 37, Unix process pid: 40986, image: oracle@yjfora81 (TNS V1-V3)
 SQL> oradebug tracefile_name
 /home/oracle/oracle/diag/rdbms/testdb/testdb/trace/testdb_ora_40986.trc

10046事件可以设置以下四个级别:
1 – 启用标准的SQL_TRACE功能,等价于sql_trace
 4 – Level 1 加上绑定值(bind values)
 8 – Level 1 + 等待事件跟踪
12 – Level 1 + Level 4 + Level 8

找到语句使用LEVEL 1即可

SQL> oradebug event 10046 trace name context forever ,level 1;
 Statement processed.

在ggsci中

GGSCI (yjfora81 as ggs_admin@testdb) 3> add trandata ppzhu1.test4

Logging of supplemental redo data enabled for table PPZHU1.TEST4.
 TRANDATA for scheduling columns has been added on table ‘PPZHU1.TEST4′.
 TRANDATA for instantiation CSN has been added on table ‘PPZHU1.TEST4′.

SQL> Oradebug event 10046 trace name context off;
 Statement processed.

然后我们查看trace文件

LOCK TABLE “PPZHU1″.”TEST6″ IN SHARE MODE  NOWAIT 
 LOCK TABLE “PPZHU1″.”TEST6″ IN EXCLUSIVE MODE  NOWAIT 
 ALTER TABLE “PPZHU1″.”TES

可以看到是要加锁的所以add trandata可能造成堵塞
 由于ALTER TABLE 看不全,我做了审计发现如下:
 ALTER TABLE “PPZHU1″.”TEST8″ ADD SUPPLEMENTAL LOG GROUP “GGS_87937″ (“USER_ID”) ALWAYS  /* GOLDENGATE_DDL_REPLICATION */
  ALTER TABLE “PPZHU1″.”TEST8″ ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE, FOREIGN KEY) COLUMNS  /* GOLDENGATE_DDL_REPLICATION */
在结合我们的报错信息

GGSCI (yjfora81 as ggs_admin@testdb) 2> add trandata ppzhu1.test3
 2016-03-08 11:47:36  WARNING OGG-00706  Failed to add supplemental log group on table PPZHU1.TEST3 due to ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired SQL ALTER TABLE “PPZHU1″.”TEST3″ ADD SUPPLEMENTAL LOG GROUP “GGS_87926″ (“USER_ID”) ALWAYS  /* GOLDENGATE_DDL_REPLICATION */.
 2016-03-08 11:53:00  WARNING OGG-00706  Failed to add supplemental log group on table PPZHU1.TEST3 due to ORA-03113: end-of-file on communication channel
 Process ID: 23575
 Session ID: 80 Serial number: 2709 SQL BEGIN DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(table_name => ‘”PPZHU1″.”TEST3″‘, supplemental_logging => ‘none’); END;.

可以确定 add trandata 至少做了如下操作

1、ALTER TABLE “PPZHU1″.”TEST8″ ADD SUPPLEMENTAL LOG GROUP “GGS_87937″ (“USER_ID”) ALWAYS
 2、ALTER TABLE “PPZHU1″.”TEST8″ ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE, FOREIGN KEY) COLUMNS 
 3、DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(table_name => ‘”PPZHU1″.”TEST3″‘, supplemental_logging => ‘none’

其中这几部中第三步会加锁并且不是NOWAIT的方式,如果表上有事物正在运行,那么这个语句会等待,因为他需要一个MODE 4的锁在表级S锁
 如下:
SQL> select * from v$lock;
 ADDR             KADDR                   SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
—————- —————- ———- —- ———- ———- ———- ———- ———- ———-
00000001BD52BC80 00000001BD52BCF8         80 TX       655363       1685          6          0        122          0
 00007F716C65A908 00007F716C65A968         80 TM        87926          0          0          4        122          0

而DML会在表级别上一个SX级别的3级锁,所以不兼容一直卡着,并且它还会影响随后的DML因为DML需要表级别的SX锁,这样对生产系统的影响
 很大。解决方式就是KILL掉OGG登陆的会话。
而1,2两部都是NOWAIT方式,可以及时报错出来及ORA-00054: resource busy,不会堵塞

实际上1,2两部做完后,我们可以再ORACLE数据库中查看视图
dba_log_group_columns
 dba_log_groups
其中的含义不在给出,可以看看官方手册。 


2.

 
Q:  SQL>alter database add supplemental log data; 将数据库附加日志打开后还需要对每张表执行 add trandata 吗?
谁知道啊?

A:需要! 如果不执行add trandata,insert同步没有问题(ORACLE数据库),但是在同步update或delete操作时,就会因为丢失主键报同步错误。不开启表级的最小附加日志,update的redo信息不记录没有进行更新的字段信息,如主键不更新的话主键不记录在redo中,所以会导致同步失败。
 亲自实践过,不信你也可以试试。

 SQL> alter session set events '10046 trace name context forever,level 12';

Session altered.

SQL> /

Session altered.



SQL> alter session set events '10046 trace name context off';

Session altered.

SQL>select * from v$diag_info;

 

 

案例可以参考 http://blog.mchz.com.cn/?p=4047

 

 

->

alter session set statistics_level=all;

select /*+ gathe_plan_statistics */ * from ts.ts_record t where system_name='人员小车闸口' order by pass_datetime desc;

 

select sql_text,sql_id from v$sql where sql_text like 'select%*%人员小车闸口%';

 

spool D:\dba\tmp\sql_dev.log

select * from table(dbms_xplan.display_cursor('36tvbv2uth9j9',0,'runstats_last')); 

spool off

 

 set pages 100 heading off pause on

select * from table(dbms_xplan.display_cursor(null,0,'allstats last'));

select * from table(dbms_xplan.display_cursor(null,null,'advanced'));      

 

 

 

-->

SET LONG 1000000 SET FEEDBACK OFF

spool monitor_sql.html

SELECT DBMS_SQLTUNE.report_sql_monitor(sql_id =>'20wfgydukawbw',type=> 'HTML') AS report FROM dual;  

spool off    

                   

 

->

 SQL> alter session set events '10046 trace name context forever,level 12';

Session altered.

SQL> /

Session altered.



SQL> alter session set events '10046 trace name context off';

Session altered.

SQL>select * from v$diag_info;

 

转载于:https://www.cnblogs.com/feiyun8616/p/6019768.html

<think>我们正在讨论Oracle GoldenGate中的`ADD SCHEMATRANDATA`命令的实现原理。根据之前的上下文,我们已经知道该命令用于为整个模式(schema)启用附加日志(supplemental logging)。现在,我们需要深入探讨其背后的工作原理。 ### 实现原理分析 1. **附加日志的作用**: - 在Oracle数据库中,默认情况下,redo log只记录足够用于恢复的数据(如被修改的列值)。但对于数据同步工具(如OGG),需要额外的信息来唯一标识行(例如主键、唯一键等),以便在目标端准确应用变更。 - 附加日志就是在redo log中添加额外的信息,确保OGG能够捕获到足够的信息来识别和重放变更。 2. **`ADD SCHEMATRANDATA`与`ADD TRANDATA`的关系**: - `ADD TRANDATA`:为单个表启用附加日志。它会为指定的表添加一个日志组(log group),该日志组包含主键列、唯一键列或其他指定的列。这样,在redo log中就会记录这些列的旧值(用于UPDATE和DELETE操作)[^2]。 - `ADD SCHEMATRANDATA`:为整个模式下的所有表(包括未来创建的表)启用附加日志。它实际上是通过批量操作,为当前模式中所有表执行类似`ADD TRANDATA`的操作,并且还会设置一个数据库级别的属性,使得该模式下新创建的表自动启用附加日志。 3. **数据库层面的实现**: - 在Oracle数据库中,附加日志是通过`ALTER DATABASE`或`ALTER TABLE`命令来启用的。例如,启用数据库最小附加日志: ```sql ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; ``` 然后,对于表级附加日志,通常使用: ```sql ALTER TABLE owner.table_name ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS; ``` - `ADD SCHEMATRANDATA`命令在内部会执行以下操作: - 检查数据库是否已启用最小附加日志(如果没有,会先启用)。 - 遍历指定模式下的所有表,并为每个表创建一个日志组(通常包含主键列、唯一键列等)。如果表没有主键或唯一键,则使用所有非空列(或者根据OGG的配置)来创建日志组。 - 在数据库的系统表中注册该模式的附加日志属性,使得该模式下新建的表自动继承附加日志设置。 4. **系统表与视图**: - Oracle通过数据字典视图来管理附加日志信息,例如: - `DBA_LOG_GROUPS`:显示所有表的日志组定义。 - `DBA_LOG_GROUP_COLUMNS`:显示日志组中包含的列。 - 当执行`ADD SCHEMATRANDATA`后,可以在这些视图中查询到对应模式下的所有表的日志组信息。 5. **自动应用于新表**: - 实现自动应用于新表的关键在于Oracle数据库的触发器或事件机制。但实际并非使用触发器,而是通过设置数据库属性(在系统表中标记该模式需要自动启用附加日志)。当在该模式下创建新表时,OGG的元数据层会检测到该事件,并自动为新表执行`ADD TRANDATA`(通过后台进程或数据库事件触发)。 6. **OGG内部机制**: - OGG的Manager进程负责元数据管理。当执行`ADD SCHEMATRANDATA`时,OGG会将该命令化为对数据库的系统调用(DDL语句),同时将模式级别的附加日志设置记录到OGG自己的元数据存储中(如磁盘文件或数据库表)。 - 当OGG的抽取进程(Extract)启动时,它会检查每个表的附加日志状态。如果发现某个表没有启用附加日志,它会尝试自动启用(如果模式设置为自动启用)。但这一行为依赖于数据库版本和配置。 ### 性能与影响 - **存储开销**:附加日志会增加redo log的大小,因为每条变更记录都需要记录额外的列信息。这可能会对I/O和存储产生压力。 - **性能影响**:启用附加日志可能会轻微影响数据库性能,因为需要写入更多的redo数据。但在大多数OLTP系统中,这种影响是可接受的。 ### 总结 `ADD SCHEMATRANDATA`的实现原理可以概括为: 1. 确保数据库级别的最小附加日志已启用。 2. 遍历指定模式下的所有表,为每个表创建必要的日志组(通过执行`ALTER TABLE ... ADD SUPPLEMENTAL LOG DATA ...`)。 3. 在数据库的系统表中注册该模式的属性,使得该模式下新建的表自动启用附加日志。 4. OGG记录该模式的附加日志状态到其元数据中,以便后续管理。 通过这种方式,OGG能够确保整个模式中的表(包括未来创建的表)都能提供足够的日志信息,以支持可靠的数据同步[^1][^2][^5]。 §§相关问题§§ 1. OGG 如何自动为新创建的表启用附加日志? 2. 启用附加日志对数据库性能有哪些具体影响? 3. 如何监控和管理 Oracle 数据库中的附加日志设置?</think>### OGG `ADD SCHEMATRANDATA` 实现原理详解 `ADD SCHEMATRANDATA` 是 Oracle GoldenGate (OGG) 的核心命令,其实现原理涉及数据库日志机制、数据字典操作和事务管理三个关键层面。以下是技术原理分析: #### 1. **数据库日志层增强** - **核心机制**:通过修改数据库的 redo log 结构,强制记录**完整行标识信息**(主键/唯一键)[^5]。 - **实现方式**: ```sql ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS; -- 数据库级最小日志 ALTER SCHEMA schema_name ADD SUPPLEMENTAL LOG GROUP log_group_id (col1, col2...); -- 模式级增强 ``` - **数据变化**: | 操作类型 | 默认日志内容 | 启用后日志内容 | |----------|--------------|----------------| | `UPDATE` | 仅修改列值 | 修改列值 + 主键值 | | `DELETE` | 无行标识 | 完整主键值 + 旧值 | | `INSERT` | 新列值 | 新列值 + 主键值 | #### 2. **数据字典操作** OGG 通过更新 Oracle 数据字典实现持久化配置: - 在 `SYS.SUPPLEMENTAL_LOGING$` 系统表注册模式级日志组 - 在 `DBA_LOG_GROUPS` 视图标记状态为 `ENABLED`[^5] - **事务一致性**:使用 DDL 事务确保原子性,避免部分表启用失败 #### 3. **事务数据捕获优化** - **日志挖掘**:Extract 进程读取 redo log 时,通过附加的键值信息精准定位变更行 - **冲突解决**: - 使用主键值解决 `UPDATE` 歧义(如无主键则记录所有列) - 通过 `BEFORE/AFTER` 映像实现行级数据对比[^1] - **数据流优化**: $$ \text{Redo Log} \xrightarrow{\text{键值增强}} \text{Trail文件} \xrightarrow{\text{精确映射}} \text{目标表} $$ #### 4. **多租户环境特殊处理** 在 CDB/PDB 架构中: - 在根容器(CDB)执行 `ALTER DATABASE` 启用基础日志 - 在 PDB 容器执行模式级操作: ```sql ALTER SESSION SET CONTAINER = pdb_name; ADD SCHEMATRANDATA schema_name; -- 每个PDB独立配置[^4] ``` #### 5. **错误处理机制** - **权限验证**:检查 OGG 用户是否有 `ALTER ANY TABLE` 权限[^3] - **兼容性检查**:验证数据库补丁状态(如 OGG-02912 错误需 Patch 17030189)[^3] - **自动回滚**:单表失败时触发事务回滚,保证模式级一致性 #### 原理验证方法 1. 查询日志状态: ```sql SELECT supplemental_log_data_min, supplemental_log_data_pk FROM v$database; -- 验证数据库级[^5] ``` 2. 检查模式级配置: ```sql SELECT * FROM dba_log_groups WHERE owner = 'SCHEMA_NAME'; ``` > **关键结论**:`ADD SCHEMATRANDATA` 本质是通过数据库级 DDL 操作,在 redo log 中注入行标识信息,使 OGG 能精准重建事务逻辑。其实现依赖 Oracle 的日志增强接口,而非应用层模拟[^1][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值