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

OGG复制进程延迟高问题处理

原创 杨卓 2021-11-17
7626

一、文章概述

本篇文章是针对Ogg19.1集成模式复制进程延迟高问题进行分析并处理的过程。
备注:常规的OGG复制进程慢基本上也可以按照这个套路。

二、问题分析

2.1 SQL执行慢

2.1.1.问题现象

巡检发现进程存在延迟

GGSCI>info all
Program     Status      Group       Lag at Chkpt  Time Since Chkpt
REPLICAT    RUNNING     REPAP01     00:12:56      00:19:34  

复制

OGG Time Since Chkpt代表OGG这个进程有19分钟没有commit提交数据,也代表了这个进程同步Dml操作时间很长,可能存在性能问题。
–备注有需要了了解两个Chkpt的说明可以看看如下博客链接

https://www.cnblogs.com/lvcha001/p/13469500.html


复制

2.1.2.定位问题

可以使用查询session脚本定位OGG会话执行什么SQL?

replicat@xxxdb1 (TN   403   14281 C##OGG       
oracle   0ajv7pxmcjduc  xxdb1         ACTIVE 15 15:42:02  CPU

复制

多次执行session.sql脚本,发现这个replicat OGG复制进程,一直在执行SQL_ID 0ajv7pxmcjduc ,当查询多次也就是同一个SQL执行>3s的复制,需要关注!!!

这个脚本也没啥特殊的,就是查询active session exec sql_id or event,如果大家需要排查OGG的问题,加上username=’$OGG_USER’这样更快

2.1.3.查询SQL执行计划

select * from table(dbms_xplan.display_cursor(‘0ajv7pxmcjduc’));
image.png
通过执行计划,可以看到这个OGG执行delete操作,执行计划全表扫描!执行效率非常低!!!

2.1.4.优化SQL

当遇到是OGG复制进程执行的SQL性能问题时,优化思路与优化SQL类似!

1.收集统计信息;

EXEC dbms_stats.gather_table_stats
(ownname=>'Cxx',TABNAME=>'Nxx',
CASCADE=>TRUE,DEGREE=>16,ESTIMATE_PERCENT=>3,NO_INVALIDATE=>false);

复制

2.添加主键字段

select
 b.INDEX_OWNER,b.INDEX_NAME,b.INVALID,
a.COLUMN_NAME,b.CONSTRAINT_TYPE,
b.STATUS,b.CONSTRAINT_NAME
 from dba_cons_columns a,dba_constraints b
 where
 a.owner=b.owner and a.owner='Cxx'
 and b.TABLE_NAME=a.TABLE_NAME
 and a.table_name='Nxx'
  and a.CONSTRAINT_NAME=b.CONSTRAINT_NAME;
------------------------------------
&OWNER                 
&NAME  
ROW_ID                   
C
ENABLED
SYS_C00135314
复制

–这个表是ROWID字段同步的表,但是没有主键或唯一约束,但是实际知道这个ROW_ID字段记录的是源库rowid值是唯一的,可以放心添加主键约束!

alter table Cxx.NGLxxNCES
 add constraint pk_rowid_xxES unique (row_id) enable Novalidate;

复制

#注意生产环境使用默认enable添加主键需要慎重! enable Novalidate能极大加速添加主键的时间,而非默认会锁很长时间的表,影响业务。
添加主键成功后,检查

select b.INDEX_OWNER,b.INDEX_NAME,b.INVALID,
a.COLUMN_NAME,b.CONSTRAINT_TYPE,b.STATUS,
b.CONSTRAINT_NAME
 from dba_cons_columns a,dba_constraints b
 where a.owner=b.owner and a.owner='Cxx' 
     and b.TABLE_NAME=a.TABLE_NAME and a.table_name='NGLxx'
     and a.CONSTRAINT_NAME=b.CONSTRAINT_NAME and b.CONSTRAINT_TYPE='U';

复制

image.png

3.细粒度对表DDL操作

–收集统计信息后,OGG复制执行的SQL执行计划没有改变,对表DDL,让SQL硬解析

comment on table  xx.xx is 'ogg_big_tab';
select owner,to_char(LAST_DDL_TIME,'yyyy-mm-dd hh24:mi:ss')
 from dba_objects where object_name='xx';
------------------------------------------------------------
xx                  2021-11-14 02:54:45

复制

由于只是修改表的注释,所以实际操作是毫秒级别,不会像其它DDL操作执行几分钟、甚至几个小时阻塞业务正常DML操作。

4.使用参数keycols

这个套路一般使用在目标端没有主键字段的情况下,直接使用选择性好的字段修改ogg参数配置

MAP FPxx.xxxL.xxxx,TARGET OGxx.GxxxS
,colmap (usedefaults , ROW_ID= @token ('TKN-ROWID')),keycols(ROW_ID);


复制

5.手工设置加大全表扫描Cost

一般普通的SQL性能慢导致的OGG延迟高,使用上述套路基本上都解决了,但是本次这个问题比较有意思上述套路都没解决,那么统计信息是准确的,有主键字段Oracle还是不走索引! 那么思路就是说Oracle对rowid_id字段的Cost成本计算我认为可能不准确。 那么既然Oracle已经没有办法使用正常的Cost成本计算出正确的执行计划,走rowid对应的主键列索引,那么我们手工修改表的cost成本,让Oracle统计到走索引cost更低!

--手工修改统计信息
begin 
 dbms_stats.set_table_stats(ownname=>'CxxL',
     tabname=>'NGLxx',
	 numrows=>999999999999999999999,
	 numblks=>8,
	 avgrlen=>'800');
 end;
/
SQL> select NUM_ROWS,BLOCKS,EMPTY_BLOCKS,
to_char(LAST_ANALYZED,'yyyy-mm-dd hh24:mi:ss')
 from dba_tables where TABLE_NAME='NGxx';
  NUM_ROWS     BLOCKS EMPTY_BLOCKS TO_CHAR(LAST_ANALYZ
---------- ---------- ------------ -------------------
1.0000E+21          8            0 2021-11-15 16:06:42

复制

image.png
建议手工收集统计信息后,对该表统计信息进行Lock,否则下一次再次收集统计信息会刷出手工设置的值,那么OGG进程执行的SQL下一次解析可能会再次选择慢的执行计划!!!

exec dbms_stats.lock_table_stats('Cxx','NGL_FAxx');
col table_name for a20 
select table_name,stattype_locked
 from dba_tab_statistics where  table_name='xxS';
TABLE_NAME                        STATT
---------------------------------------------
NGxxx                              ALL

复制

!!!注意:建议这种优化套路,只针对OGG同步的表,因为本次优化设计的表dba_indexes没有查询到索引,这种情况下,手工修改cost没什么影响!
反之,如果业务表存在多个索引,手工修改加大表 cost,那么Oracle可能会走效率很低的索引,而不选择全表扫描!!!
另一种思路,只针对rowid同步的字段表,可以减小rowid字段索引的cost成本,因为rowid 字段只是为了OGG进行目标端数据同步,修改表会影响表的所有相关cost对比,但是你只修改rowid字段的影响更小。但是我们本次遇到的场景直接改表就行了。

2.1.5.优化后效果

image.png

2.2 同步的数据多

也就是OGG现有的进程模式无法快速处理所有的OGG Trail的日志同步,这个和服务器IO内存CPU也有一定关系,和OGG版本模式也有关系,但是这个都不是本次讨论的重点。现在的问题是OGG单个复制进程处理数据忙不过来? 怎么处理!

2.2.1.问题现象

巡检发现进程存在延迟

GGSCI>info all
Program     Status      Group       Lag at Chkpt  Time Since Chkpt
REPLICAT    RUNNING     RExx1     00:50:06      00:00:00  

复制

巡检发现Time Since Chkpt的延迟很低,可以说明OGG一直在同步数据,但是整体的执行效率低,导致OGG同步的最后时间和源库延迟了50分钟!!!
这个延迟的时间对大部分业务来说可能并不能接受,需要关注并处理。

2.2.2.问题分析

select
 to_char(SAMPLE_TIME,'yyyy-mm-dd hh24') as "date",
 event,count(*)
 from v$active_session_history
 where SAMPLE_TIME
    between to_date('20211115 13:00','yyyymmdd hh24:mi') 
         and to_date('20211115 18:00','yyyymmdd hh24:mi') 
         and CON_ID='3' and user_id=108
         and PROGRAM like '%oracle@ebxxx1%' 
   group by to_char(SAMPLE_TIME,'yyyy-mm-dd hh24'),event
     having(count(*))>10
       order by 1,3,2;

复制

image.png

通过对OGG进程的几个小时汇总,可以发现 null =on cpu sql exec的执行占比最高,没有异常的等待事件!

select sql_id,count(*)
 from v$active_session_history
 where SAMPLE_TIME
       between to_date('20211115 13:00','yyyymmdd hh24:mi')
           and to_date('20211115 18:00','yyyymmdd hh24:mi') 
           and CON_ID='3' and user_id=108
           and PROGRAM like '%oracle@ebxxb1%' 
    group by sql_id
  having(count(*))>10
  order by 2;

复制

image.png
SQL维护汇总,并没有看到什么慢的SQL,唯一一个捕获200次统计的SQL还是修改数据字典,可以忽略!
image.png
汇总:通过上述信息汇总得到的结果,就是说OGG复制进程并没有慢的SQL或者异常的等待事件导致进程延迟。 纯粹是OGG单个进程需要读取同步的数据多,导致单个进程忙不过来!!!

2.2.3.问题处理

如何提升单个进程的处理速度,或者降低单个进程的延迟?
1.进程拆分,让OGG一个复制进程需要处理的trail日志变少,从而降低延迟;
2.进程设置并行参数,让原本一个session处理的工作,提高到多个session一起处理,从而提升单个进程处理的能力,降低单个进程的执行时间;
3.*本次处理效果不明显,使用OGG参数,对小事务进行合并成大事务,从而降低commit时间,提高进程处理速度,本次场景效果不大!

批处理参数,如下都尝试无效果
BATCHSQL BATCHESPERQUEUE 20,OPSPERBATCH 8000
BATCHSQL BATCHESPERQUEUE 800,OPSPERBATCH 80000
BATCHSQL BATCHESPERQUEUE 100, BATCHTRANSOPS 10000
, OPSPERBATCH 10000, OPSPERQUEUE 100000


复制

2.2.3.1.进程拆分

找到DML变换多的表清单

思路就是找到DML变换最多的top 表,从里面选择几个top表放到新的复制进程,这样原来延迟高的复制进程减少了几个变换最多的表数据从而加快,而全新的复制进程由于只同步几个所以整体来看速度都加快了,延迟问题得到解决。
ggsci >/tmp/stats_20211115.log <<EOF
info REPAP01
stats REPAP01
exit
EOF

将DML操作汇总变换大于1w的进行汇总,实际情况就是选择top 选择几个对象!将这些经常变换的表,迁移到新的进程中,原来的延迟高的进程对这些迁移的表进行删除不在同步。

举例如下:
Replicating from PROD.GL.GL_JE_LINES to Fxx.CxxL.NGL_FxxS:
    Total operations                           45827.00


复制
进程参数编辑
>edit param REPAP02
REPLICAT repap02
USERIDALIAS ExxOGG
ASSUMETARGETDEFS
GETTRUNCATES
DBOPTIONS NOSUPPRESSTRIGGERS
DBOPTIONS DEFERREFCONST
report at 1:59
reportrollover at 2:00
reperror default,abend
ALLOWNOOPUPDATES
INSERTMISSINGUPDATES
DISCARDFILE ./dirrpt/discard_repap02.dsc, PURGE
MAP Pxx,TARGET CxxS,FILTER (@GETENV('TRANSACTION','CSN') > 894300384284);
复制
进程添加
--add
NEW_OGGPRO=repap02
NEW_OGG_FILE=repap01/pa
ggsci <<EOF
dblogin USERIDALIAS ExxG
add checkpointtable C##OGG.${NEW_OGGPRO}_ckp_tab2
add replicat $NEW_OGGPRO ,integrated
,exttrail ./dirdat/${NEW_OGG_FILE},CHECKPOINTTABLE C##OGG.${NEW_OGGPRO}_ckp_tab2
register replicat ${NEW_OGGPRO} database
exit
EOF
复制
新建进程启动

关闭原延迟高的复制进程

GGSCI>stop repap01
--确认进程stop
REPLICAT    STOPPED     REPAP01     00:57:40      00:03:49    
REPLICAT    STOPPED     REPAP02     00:00:00      00:00:06  
复制

–查询延迟高的复制进程最后一个时间点rba

GGSCI (xxb1) 2> info REPAP01
REPLICAT   REPAP01   Last Started 2021-11-15 17:21   Status STOPPED
INTEGRATED
Checkpoint Lag       00:57:40 (updated 00:03:58 ago)
Log Read Checkpoint  File ./dirdat/repap01/pa000000015
                     2021-11-15 16:37:10.851420  RBA 46286994
复制

–修改新的复制进程,从延迟高的进程最后一个rba开始进行同步

alter REPLICAT REPAP02 ,extseqno 15,extrba 46286994
复制

–检查

GGSCI (ebsfiproddb1) 5> info REPAP02
REPLICAT   REPAP02   Initialized   2021-11-15 17:39   Status STOPPED
INTEGRATED
Checkpoint Lag       00:00:00 (updated 00:00:05 ago)
Log Read Checkpoint  File ./dirdat/repap01/pa000000015
                     First Record  RBA 46286994

复制

–启动新建的复制进程

GGSCI (exx1) 3> start REPAP02
复制
延迟高进程启动

延迟高的复制进程,在确认新建的复制进程正常同步后,删除新的复制进程同步的表,避免重复同步!!!

$ cat repap01.prm |grep GL_xx
$ cat repap02.prm |grep GL_xx
确认新建的复制进程正常复制后,删除延迟高的复制进程对应拆分的表后,启动之前stop的复制进程
--删除后,启动复制进程
GGSCI (ebsfiproddb1) > start REPAP01
复制

2.2.3.2.进程启用并行

参考OGG Parallel
Parallelism Off
● Offers maximum safety – works like Classic Replicat
– Does not start a following transaction before committing the current transaction
– Always using the “parallel style” checkpoint table 
-– Even when working with just 1 apply session
– Used for “large transactions”
● Integrated Replicat:
– DBOPTIONS INTEGRATEDPARAMS (PARALLELISM 1)
– Automatically sets: GROUPTRANSOPS 25
● Parallel Nonintegrated Replicat:
– APPLY_PARALLELISM 1
– or: COMMIT_SERIALIZATION
● Parallel Integrated Replicat:
– APPLY_PARALLELISM 1

复制

本次选用● Integrated Replicat

编辑参数

复制进程添加参数

DBOPTIONS INTEGRATEDPARAMS(parallelism 24)
复制

巡检发现OGG复制进程还是存在2分钟左右的延迟,生产环境不太建议延迟较高。并且考虑到后续月结等导致OGG同步数据更多导致延迟加剧,最终影响性能。

优化后效果
REPLICAT    RUNNING     REPAP01     00:00:09      00:00:00    
REPLICAT    RUNNING     REPAP02     00:00:00      00:00:04
复制
处理之后OGG在下午业务高峰期观察延迟,只有短时间内有2分钟,随后延迟降低到10s内,可以接受。
复制
优化对数据库影响

image.png

后续给客户看了之后,客户担心月结或者年结再次出现问题,后续就是找到OGG历史的stats的记录,对复制进程拆分新增4个,更进一步的进行了拆分。 本次OGG可以认为源端抽取投递是一个进程,复制一个进程拆分为5个!
这个OGG是支持的,但是需要注意可能产生的另一个问题,之前有客户环境遇到一次多个复制进程同时应用投递过来的一个trail文件;其中一个OGG进程由于某些问题hang住了,recover ckpt不往前走,虽然看起来current ckpt向前,但是recover ckpt不往前走,导致MGR不删除trail文件,最终导致OGG trail文件对应的操作系统空间满,所有进程受到影响! 每次手工删除费时费力!最后对有问题的进程重建后问题解决。

三、结论及建议

1.使用监控软件等方式,实现邮件或者短信、微信等实时告警。
当OGG进程ABEND; 或者OGG延迟达到一定时间,例如10分钟、30分钟、60分钟实现监控告警,运维人员及时处理。
2.如何从源头避免OGG产生性能问题呢???
对所有同步OGG的表,在源库就改造都有主键或者唯一约束的字段情况,好处多多
对于主键或者唯一字段的OGG同步的表,源端添加表最小补充日志不在是全列添加!减少了trail文件的记录;目标库OGG 复制执行dml操作使用主键或唯一约束列对应的索引更快的执行update or delete效率有保障,以及由于传输过来的trail日志变少,执行效率理论上更快。
在数据初始化后,及时收集统计信息,否则大表非常容易全表扫描导致OGG复制进程慢!

最后修改时间:2021-11-17 10:49:50
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

tnan1986
暂无图片
2年前
评论
暂无图片 1
记得有篇文章说集成模式的并行比较鸡肋,ogg 12.3有个集成并行模式可以真的开多个并行,平常拆分表算是一个好的解决办法
2年前
暂无图片 1
评论
墨天轮福利君
暂无图片
3年前
评论
暂无图片 1
您好,您的文章已入选合格奖,10墨值奖励已经到账请查收! ❤️我们还会实时派发您的流量收益。
3年前
暂无图片 1
评论