从根本上讲,OGG复制性能和要复制的表是否存在主键和唯一索引有很大关系,所以从应用系统开发商对表结构的规范更为有效。OGG调优通常采用拆分进行的方式,拆分方法如下所述。
Extract拆分方法
1) 停止extract进程
2) 停止datapump、进程
GGSCI> INFO datapump_name
EXTRACT DPEF Last Started 2011-01-28 12:34 Status RUNNING
Checkpoint Lag 00:00:00 (updated 00:00:05 ago)
Log Read Checkpoint File ./dirdat/ef000010
2011-01-28 12:47:45.000000 RBA 148645
直至RBA号不变化,才能停止
3) 停止replicat进程
GGSCI> INFO replicat_name
REPLICAT RPEF Last Started 2011-01-28 12:30 Status RUNNING
Checkpoint Lag 00:00:00 (updated 00:00:05 ago)
Log Read Checkpoint File ./dirdat/ef000006
2011-01-28 12:47:45.000000 RBA 149258
直至RBA号不变化,才能停止
4) 记录extract检查点
Extract检查点包括:Recovery Checkpoint和Current Checkpoint
GGSCI> INFO extract_name, SHOWCH
EXTRACT EXEE Last Started 2011-01-28 09:58 Status STOPPED
Checkpoint Lag 00:00:00 (updated 00:01:02 ago)
Log Read Checkpoint Oracle Redo Logs
2011-01-28 10:02:16 Seqno 26, RBA 7090688
Current Checkpoint Detail:
Read Checkpoint #1
Oracle Redo Log
Startup Checkpoint (starting position in the data source):
Sequence #: 26
RBA: 289296
Timestamp: 2011-01-28 09:27:31.000000
Redo File: C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG
Recovery Checkpoint (position of oldest unprocessed transaction in the data source):
Sequence #: 26
RBA: 7088144
Timestamp: 2011-01-28 10:02:16.000000
Redo File: C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG
Current Checkpoint (position of last record read in the data source):
Sequence #: 26
RBA: 7090688
Timestamp: 2011-01-28 10:02:16.000000
Redo File: C:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\REDO02.LOG
Write Checkpoint #1
GGS Log Trail
Current Checkpoint (current write position):
Sequence #: 11
RBA: 31609
Timestamp: 2011-01-28 10:02:19.072000
Extract Trail: ./dirdat/ee
Header:
Version = 2
Record Source = A
Type = 4
# Input Checkpoints = 1
# Output Checkpoints = 1
File Information:
Block Size = 2048
Max Blocks = 100
Record Length = 2048
Current Offset = 0
Configuration:
Data Source = 3
Transaction Integrity = 1
Task Type = 0
Status:
Start Time = 2011-01-28 09:58:34
Last Update Time = 2011-01-28 10:02:19
Stop Status = G
Last Result = 400
5) 修改原有相应的参数文件,将拆分出的表从参数文件中删除
6) 增加新的extract,datapump和replicat
--source--------------------------------------------------
GGSCI (win2k364) 15> add ext exef, tranlog, begin now
EXTRACT added.
GGSCI (win2k364) 16> add exttrail ./dirdat/ef, ext exef, megabytes 50
EXTTRAIL added.
GGSCI (win2k364) 17> add ext dpef, exttrailsource ./dirdat/ef
EXTRACT added.
GGSCI (win2k364) 18> add rmttrail ./dirdat/ef, ext dpef, megabytes 50
RMTTRAIL added.
--target--------------------------------------------------
GGSCI (win2k364) 21> add rep rpef, exttrail ./dirdat/ef
REPLICAT added.
7) 修改新增extract进程的检查点
检查点为上面记录的两个检查点:
current read checkpoint and recovery checkpoint
--修改current read checkpoint
GGSCI (win2k364) 30> alter exef extseqno 26, extrba 7090688 [, thread n]
EXTRACT altered.
--修改recovery checkpoint
GGSCI (win2k364) 4> alter exef ioextseqno 26, ioextrba 7088144 [, thread n]
2011-01-28 10:46:18 INFO OGG-00989 WARNING: Unsupported operation. This might cause transactional inconsistency. Modifying iocheckpoint: ioseq = 26 iorba = 7088144.
Are you sure you want to continue? y
EXTRACT altered.
8) 确认所有参数文件正确,启动进程即可
Datapump和replicat拆分方法
下面以拆分replicat为例,datapump拆分方法相同。
1) 停止replicat进程
2) 查看检查点
GGSCI> INFO replicat_name, SHOWCH
REPLICAT RPEF Last Started 2011-01-28 12:30 Status RUNNING
Checkpoint Lag 00:00:00 (updated 00:00:03 ago)
Log Read Checkpoint File ./dirdat/ef000006
2011-01-28 12:47:45.000000 RBA 149258
Current Checkpoint Detail:
Read Checkpoint #1
GGS Log Trail
Startup Checkpoint (starting position in the data source):
Sequence #: 4
RBA: 1845
Timestamp: 2011-01-28 11:32:10.556000
Extract Trail: ./dirdat/ef
Current Checkpoint (position of last record read in the data source):
Sequence #: 6
RBA: 149258
Timestamp: 2011-01-28 12:47:45.000000
Extract Trail: ./dirdat/ef
Header:
Version = 2
Record Source = A
Type = 1
# Input Checkpoints = 1
# Output Checkpoints = 0
File Information:
Block Size = 2048
Max Blocks = 100
Record Length = 2048
Current Offset = 0
Configuration:
Data Source = 0
Transaction Integrity = -1
Task Type = 0
Database Checkpoint:
Checkpoint table = GGS.GGSCHKPT
Key = 746337239 (0x2c7c33d7)
Create Time = 2011-01-28 10:20:18
Status:
Start Time = 2011-01-28 12:30:23
Last Update Time = 2011-01-28 13:25:34
Stop Status = A
Last Result = 400
3) 修改原有参数文件,将拆分出的表删除
4) 新增replicat,和拆分前的进程读取相同的队列文件
5) 修改检查点
6) GGSCI>alter replicat_new extseqno 6, extrba 149258
7) 确认所有参数文件无误,启动进程即可
OGG的Replicat进程性能调优
OGG的Replicat负责将队列文件中的数据读取出来然后按照原来的顺序一条条投递到目标数据库,当数据变化量较大时可能无法跟上队列的产生速度,此时需要进行调优。
OGG提供几个参数用于调节Replicat的性能,如batchsql/ MAXTRANSOPS /GROUPTRANSOPS等。
Replicat的性能问题除去数据变化量的大小,还跟数据库本身执行SQL的速度有关。例如,表是否有主键或者唯一索引,是否有普通索引等,也可以通过这些方面进行调优。
确认Replicat进程运行正常
可以使用stats myrep来查看进程的统计信息,或者使用send myrep,report强制执行一个报告,然后使用view report查看报告里面的各表的统计信息,观察数据变化量是否比较大。
如果replicat长时间不动,可以尝试重启该进程,观察是否正常响应,有可能该进程正在处理一个长事务,会报告正在处理长交易和已经处理了多少条。
Replicat进程的拆分
拆分原则
Replicat如需拆分,按照schema、业务所涉及表范围、表名称前缀、表名等方法进行依次拆分。
拆分进程的评估
可以在extract运行几天后,查看源端extract的报告或者使用stats命令找出变化最为频繁的表,为一个或几个这些大数量级表单独配置投递进程;也可根据数据库定期收集的统计信息将变化较多的表拆分出来;无主键表往往性能较差,对于单个或多个频繁变化的无主键表一般也需要拆分为独立的进程;同时也可以根据Trail产生的速度和实际Replicat的速度来估算需要多少个进程。Repliat的拆分一般很难一次到位,经常需要多次拆分方能达到最佳效果。
进程拆分的目标
进程拆分一般以表为单位,当对某一个进程进行拆分后,其所负责的全部表应当被分布到各个拆分后的进程去,既要保证全部被包含到这些进程,又要确保不会有表被重复包含在多个进程中。例如,对原来一个Schema进行拆分,将其中一个大表拆分为一个单独进程:
拆分之前的Replicat中的map:
map UCR_UIF1.*, target UCR_UIF1.*;
拆分后的两个Replicat中的map:
第一个replicat,只包含拆分出来的大表(需要新加一个replicat,可以copy原有replicat创建的命令和参数,注意替换掉所有与进程名有关的参数):
Map UCR_UEC.TF_O_SELFSERVICE_STATE, target UCR_UEC.TF_O_SELFSERVICE_STATE;
第二个replicat,将该大表排除出去后的所有该schema下的表(可以直接用旧的replicat,只需添加mapexclude参数即可):
MAPEXCLUDE UCR_UEC.TF_O_SELFSERVICE_STAT
map UCR_UEC.*, target UCR_UEC.*;
拆分的步骤
以下为一个replicat进行拆的步骤:
1) 停止所要拆分的replicat;
2) 使用info myrep查看该replicat的检查点,将该检查点所有内容记录下来。如下示例,记住当前的队列号seqno和RBA:
Last Started 2006-01-21 11:40 Status RUNNING
00:00:00 (updated 232:39:41 ago)
C:\GGS\DIRDAT\RT000123
2006-01-11 18:54:33.000000 RBA 4735245
3) 根据评估决定要拆分为几个进程,为每个进程准备创建命令和参数文件,务必要仔细检查,确保其正确性;
4) 执行ggsci命令创建replicat进程,通过edit param myrep编辑参数文件或直接将参数文件放到dirprm目录下;
5) 针对新增的replicat(原有的replicat就不用动了),逐个修改其检查点到原replicat指定的extseqno和extrba。例如,针对上面的示例:
ALTER REPLICAT mynewrep, EXTSEQNO 123, EXTRBA 4735245
6) 检查各replicat的参数和进程信息,确保表已经被散步到各个进程,确保各进程检查点已经与原有replicat保持一致;
7) 启动replicat,观察是否正常。
说明:进程的拆分需要对replicat的检查点进行操作,一定要特别注意,如有可能需求技术支持。
针对单个表的拆分
如果某些表特别大,拆分到一个单独进程依然无法满足要求,可以根据主键将该表拆分为多个进程。
注意:单个表的拆分是依据某个字段的值做hash进行拆分的(默认为主键,但也可以自定义为其它列,前提是该列必须被记录在附加日志里面),所以必须要保证该字段日常是固定不变的。否则,作为拆分依据的这些字段的变化将会引起记录在不同的replicat中处理,有可能各进程之间的不同不会引起数据修改顺序的紊乱,导致replicat出错。
下面是一个拆分后的replicat参数示例,原有进程被拆分为2个进程:
原来的replicat:
MAP sales.acct, TARGET sales.acct;
拆分后的Replicat1(可使用原有的replicat):
MAP sales.acct, TARGET sales.acct, FILTER (@RANGE (1, 2));
拆分后的replcat2(新增):
MAP sales.acct, TARGET sales.acct, FILTER (@RANGE (2, 2));
具体拆分步骤与依据表的拆分相同,不再详述。
单个Replicat进程的调优
OGG提供了几个参数可以对单个的replicat进行调优,如下所示:
1) 使用操作合并 - BATCHSQL
BATCHSQL
该参数可以将类似的SQL放在一起进行批量提交。该参数适用的条件:
ü Replicat进程里面只有一张或者几张表;
ü 这些表没有BLOB/CLOB/LONG等大对象;
ü 这些表的列定义长度在1K以下,例如如果有几个varchar(4000)则不合适;
更多信息请参考OGG的参考手册,如需使用请联系技术支持。
2) 对大交易使用交易分拆 - MAXTRANSOPS
MAXTRANSOPS 1200
将超过指定的记录变化数的交易拆分为多个小一些的交易进行提交,可以不必等待OGG读完全部的交易记录,能够看到检查点的持续前进。
如果有时候Replicat很长时间不往前移动,可以考虑调整该参数。
3) 对于密集小交易使用交易合并 - GROUPTRANSOPS
GROUPTRANSOPS 1200
该参数的作用是将小交易合并为一个大一些的交易,示例是将若干小交易拼在一起直到所有的记录超过500个则将这些交易一起提交。可以有效降低密集小交易带来的密集IO,提升投递性能。对于大交易不起作用,一般性能调优在IO有瓶颈时使用。
数据库及SQL的调优
OGG的复制机制是将源端发生的变化拼装为SQL在目标端重现,其执行的速度与本身sql的速度有关。尤其是对于update和delete,对于执行计划的优化可以极大的提高sql执行的速度。
一个典型的问题是无主键表,当执行一个update或这delete时,无主键表会执行全表扫描去定位一条记录,速度非常慢。因此,当无主键表拆分为一个进程依然无法满足其性能要求时,其最佳方法就是给该表加入主键或唯一索引。
其它对于目标库的sql执行效率优化也同样能提高OGG replicat的性能。
申请技术支持
如经过以上排查仍然无法解决性能问题,可以联系Oracle予以协助。
OGG进程拆分与交易一致性说明
1) 问题描述
国网部分网省对于OGG进程拆分会不会影响交易一致性比较关心,特在此予以说明。
2) 问题说明
OGG的extract/data pump/replicat进程均可以拆分为多个进程同时并发执行,以提高数据复制的性能和处理能力。在Oracle提供的《国家电网网省数据级灾备GoldenGate设计原则》一文中对于进程的拆分原则进行了详细的规定。下面对于各个进程的拆分及其交易一致性的影响进行分析:
ü 主Extract的拆分
在前期提供的OGG链路设计原则中提到,OGG的主Extract进程处理能力较强,一般依据硬件平台不同可以处理约每小时20-40G以上的日志,对于中小型应用无需拆分;而如果数据量较大,确实需要拆分的话,优先选择的是以业务或schema作为拆分的依据,即按照不同的业务所设计的表范围拆分extract进程。
按照业务拆分完成后,各extract进程之间没有交互,相互独立运行,之间可能会有时间差,但是由于各进程是以业务为依据进行拆分的,只会在不同的业务之间产生时间上的短暂差异,并不影响交易的一致性;
如果拆分时打破了业务界限,同一个业务被拆分到了不同的extract进程里面,则出现灾难时可能会出现不同进程之间的数据不平衡。如果确有这种情况,可以通过OGG的logdump工具对最后的几条数据进行检验,人工处理掉这几条不一致的数据。需要说明的是OGG处理日志速度很快,这种几率是非常低的。
总而言之,当extract没有拆分或者按照业务进行拆分,则不会带来交易的不一致性;如果打破了业务范围进行拆分,则有可能会带来交易不一致性,可通过logdump找出不一致的数据进行人工处理,而实际发生的概率是非常低的。
ü Data pump的拆分
Data Pump是跟extract严格一对一的,目前不针对data pump进行拆分,对于它们没有该问题。
ü Replicat的拆分
由于单个replicat相对于extract处理能力较慢,当前大部分网省都对replicat进行了拆分。拆分后的replicat单独运行,相互不进行交互,彼此之间同样可能存在不同步现象,依据extract的拆分情况分析如下:
当extract不拆分或者按照业务拆分时,能够保证交易的一致性,其对应的trail文件所包含数据均是一致的,而被传输到目标端后,replicat虽然彼此之间速度稍有差异(一般在几秒或者零点几秒之内),但是在接管过程中,由于切换需要至少几分钟或者几十分钟时间,此过程中由于trail已经停止增长,各replicat已经完全可以处理完队列中的数据,这样虽然入库时间稍有差异,但最终数据是全部队列中数据均已进入数据库,而队列中数据的交易一致性已经由extract进行保证,不会带来交易不一致;
只有当源端extract没有按照业务拆分时,目标的多个trail可能会有短暂的数据差异,replicat会把这些交易全部提交到目标端。此时可以通过logdump查看队列中最后的几笔交易,确认其scn号是否一致,如确有不一致可以人工进行处理,该情况只在极端情况下出现。
OGG延迟lag较大的说明
1) 问题描述
对于有lag的进程,显示为running,属于正常状态。但是如果lag时间过长,是否还正常,多长时间的范围属于正常。这个需要oracle工程师做出解释。
2) 问题说明
OGG的lag指的是数据复制的延迟,对于不同的进程lag较长时分析如下:
ü 主Extract的lag较大
主Extract负责对于数据库的日志做解析获取数据变化,只要正常运行时其延迟一般都在秒一级左右。如果出现了较大的延迟,首先排查是否存在大交易,可能进程正在处理中;如果没有大交易,但是延迟却非常大,请联系技术支持予以调查。
ü Data Pump的lag较大
Data Pump负责数据的传输,如果出现较大延迟可能是因为网络出现问题,首先可以观察网络带宽是否被占满,也有可能短时间内产生了较多的数据变化。
ü Replicat的lag较大
Replicat负责数据的入库,一般速度相对于主extract和data pump较慢,容易产生较大延迟。当replicat出现延迟后,需要对进程进行调优或者拆分,具体步骤参照本文档上一节。
一般调优完成后,在日常业务状态下应当不存在较大延迟(一般几秒到一分钟以内);当出现批处理时,可以允许一定的延迟,一般以不影响第二天的正常业务为准 – 例如,如果批处理每天早上4点前结束,可以控制延迟在2小时以内。
因此,首先需要确定OGG复制所允许的最大延迟在日常业务和批处理时的目标是什么,然后一旦达不到此目标就要依据上一节的方法进行性能的调优。