OGG数据库迁移方案(四)

来源:这里教程网 时间:2026-03-03 18:29:43 作者:

监控

源库

3 个进程:mgr, ext1, dp1

ps -ef | grep mgr | grep oracle | grep -v grep ps -ef | grep ext1 | grep -v grep ps -ef | grep dp1 | grep -v grep

 

新营业库

3 个进程:mgr, rep1,rep2

ps -ef | grep mgr | grep oracle | grep -v grep

ps -ef | grep   rep1 | grep -v grep

ps -ef | grep  rep2 | grep -v grep

将以上进程的监控放在监控程序里,若进程异常及时报警。 层面,使用ggsci 命令监控 执行info all 查看各进程运行情况,命令输出说明如下:

Group 表示进程的名称(MGR 进程不显示名字);Lag 表示进程的延时;Status 表示进程的状态。有四种状态:

STARTING: 表示正在启动过程中 RUNNING :表示进程正常运行 STOPPED :表示进程被正常关闭 ABENDED :表示进程非正常关闭,需要进一步调查原因

正常情况下,所有进程的状态应该为RUNNING ,且Lag 应该在10 分钟以内。

 

l   监控进程状态,若发现状态为‘ABENDED ’,及时告警。

l   监控lag 信息,‘Lag at Chkpt ’的值大于某一个值(比如1 小时,阀值可以调整)时告警。

l   监控checkpoint 信息,‘Time Since Chkpt ’值过大表示当前执行的sql 较慢,可以设置一个阀值(比如30 分钟),超过阀值告警。

 ggserr.log ggserr.log 中可以查看到的内容如下:

GGSCI 命令的历史记录。

GoldenGate 进程的启动与停止。

已执行的处理。

发生的错误。

信息和警告消息Ggserr.log 位置:$GG_HOME

l   监控‘ABENDED ’、‘ ERROR ’、‘ORA- ’关键字。

在源库上的应用不停止的情况下,为判断GoldenGate 是否将源库的更新都复制到了目标端,一种可实施的做法是: n   将表分为三部分:静态表,小表和大表。通过数据库链接,执行select minus 语句执行对比。静态表只需比对一次,对小表进行全量对比,大表根据时间或按分区对比历史数据,即对比今天零点之前的数据(假定零点之后不再更新)。 n   应用方面从业务角度对数据进行校验。  割接时在停止了应用后,源与目标端的数据应该为静止的。此时将数据分为三类: n   大的分区表 n   关键业务表 n   非分区表 分区表通过比较各个分区的数据rowcount number 类型字段的数据和,对于使用时间分区的数据,历史分区中的数据理论上基本不再发生变化,历史分区的数据rowcount 相等即可认定数据一致。对于使用数字分区的分区表,历史分区的数据还可能被修改的情况,对于最核心的表再加一个比对number 字段的sum 的过程。另外由于Goldengate 的同步也有一致性的检查,Goldengate 通过中没有发生大量update 的冲突,即可认为这些历史分区的数据也是一致的。 比对分区的rowcount 的脚本,该脚本需在源库和目标库上都执行,源库的数据插入到system.source_table_count 中,目标库的数据插入到system.target_table_count 中,以下对比sum 的步骤类似:

getcount.sql:

select 'insert into system.target_table_count select /*+ full(t) parallel (16) */''' || table_name ||

       ''' table_name  , ''' || partition_name ||

       ''' partition_name ,count(*) from 复制用户名称.' || table_name ||

       ' partition(' || partition_name || ') t;'

  from dba_tab_partitions

 where table_owner = ' 复制用户名称'

   and table_name in (select distinct table_name

                        from system.ggrep_table

                       where partationed = 'YES')

 order by table_name, partition_name;

 

到/oracle/tmp目录下: sqlplus '/as sysdba' set linesize 300 set pagesize 0 set heading off spool count.sql @getcount.sql spool off

 

请先去掉第一行和最后几行,然后进行切分

 

sed -n '1,20000p' count.sql >count_1.sql sed -n '20001,40000p' count.sql >count_2.sql sed -n '40001,60000p' count.sql >count_3.sql sed -n '60001,80000p' count.sql >count_4.sql sed -n '80001,100000p' count.sql >count_5.sq1 sed -n '100001,120000p' count.sql >count_5.sq1

 

count_1.sh

sqlplus '/as sysdba' <<!

set time on

@/oracle/tmp/count_1.sql

commit;

set time off

exit

!

count_2.sh

sqlplus '/as sysdba' <<!

set time on

@/oracle/tmp/count_2.sql

commit;

set time off

exit

!

count_3.sh

sqlplus '/as sysdba' <<!

set time on

commit;

@/oracle/tmp/count_3.sql

set time off

exit

!

count_4.sh

sqlplus '/as sysdba' <<!

set time on

@/oracle/tmp/count_4.sql

commit;

set time off

exit

!

count_5.sh

sqlplus '/as sysdba' <<!

set time on

@/oracle/tmp/count_5.sql

commit;

set time off

exit

!

count_6.sh

sqlplus '/as sysdba' <<!

set time on

@/oracle/tmp/count_6.sql

commit;

set time off

exit

!

nohup /oracle/tmp/count_1.sh >/oracle/tmp/count_1.log & nohup /oracle/tmp/count_2.sh >/oracle/tmp/count_2.log & nohup /oracle/tmp/count_3.sh >/oracle/tmp/count_3.log & nohup /oracle/tmp/count_4.sh >/oracle/tmp/count_4.log & nohup /oracle/tmp/count_5.sh >/oracle/tmp/count_5.log & nohup /oracle/tmp/count_6.sh >/oracle/tmp/count_6.log &number 字段的sum 的脚本:

getsum.sql

select 'insert into system.target_table_sum select /*+ full(t) parallel (16) */''' || table_name ||

       ''' table_name ,' || '''' || column_name ||

       ''' column_name,to_char(sum(' || column_name || ')) SUM from 复制用户名称.' || table_name ||' t;'

  from dba_tab_columns a

 where a.owner = ' 复制用户名称'

   and a.table_name in ('ACCOUNT','ACCOUNT_PRIVILEGE','ACCOUNT_RATEPLAN',

                  'ACC_SETTLE_TYPE','CS_CU_SUBSEXTATTR','CUSTOMER',

                  'GROUP_ACCOUNT','GROUP_CUSTOMER','PERSON_CUSTOMER',

                  'RECEPTION','SUBSCRIBER','SUBS_APPDSTATUS','SUBS_BILLMAIL',

                  'SUBS_CUSTRELATION','SUBS_DEPOSIT','SUBS_FORBID','SUBS_IMEI',

  'SUBS_PAYPLAN','SUBS_PRESENT_DATA','SUBS_PRESENT_DUMMY','SUBS_PRESENT_REAL',

                  'SUBS_PRIVATTR','SUBS_PRIVILEGE','SUBS_PRODUCT','SUBS_RATEPLAN',                  'SUBS_RELATION','SUBS_RESOURCE','SUBS_REWARD_LOG_ATTR','SUBS_REWARD_LOG',

                  'SUBS_SERVICEATTR','SUBS_SERVICE','SUBS_SPSERVICEATTR','SUBS_SPSERVICE',

                  'USER_PASSWORD_LOG','RECEPTION')

   and a.DATA_TYPE='NUMBER'

 order by table_name, column_name;

 

到/oracle/tmp目录下: sqlplus '/as sysdba' set linesize 300 set pagesize 0 set heading off spool sum.sql @getsum.sql spool off

 

sum.sh

sqlplus '/as sysdba' <<!

set time on

@/oracle/tmp/sum.sql

commit;

set time off

exit

!

 

nohup /oracle/tmp/sum.sh >/oracle/tmp/sum.log &  通过一个连接到源库上的dblink yy3a 对比rowcount sum 的结果,得到结果之后对比compare_table_count compare_table_sum 的第三、第四列数据是否都一致。 

目标库上执行:

create table compare_table_count as

select a.table_name,

       a.partition_name,

       a.count          source_count,

       b.count          target_count

  from system.target_table_count a, system.source_table_count@yy3a b

 where a.table_name = b.table_name

   and a.partition_name = b.partition_name;

 

create table compare_table_sum as

select a.table_name,

       a.column_name,

       a.sum          source_sum,

       b.sum          target_sum

  from system.target_table_sum a, system.source_table_sum@yy3a b

 where a.table_name = b.table_name

   and a.column_name = b.column_name;  非分区表直接通过源和目标的相应表minus 得到结果,为了准确该minus 需要取双向的结果。脚本如下: 

target-source.sql

 

select 'select * from 复制用户名称.' || table_name ||

       ' a minus select * from 复制用户名称.' || table_name || '@to_source b;'

  from ggrep_table

 where partitioned = 'NO';

 

souce-target.sql

select 'select * from 复制用户名称.@to_target ' || table_name ||

       ' a minus select * from 复制用户名称.' || table_name || 'b;'

  from ggrep_table

 where partitioned = 'NO';

 

在/oracle/tmp目录下执行:

sqlplus '/as sysdba'

set linesize 300

set pagesize 0

set heading off

spool st_compare.sql

@/oracle/tmp/source-target.sql

spool off

spool ts_compare.sql

@/oracle/tmp/target-source.sql

spool off  

应用人员停应用; 确认数据库没有应用用户连接,并将应用用户锁定

col username for a10

col program for a30

col machine for a10

col sql_id for a15

col event for a30

select username,count(*) from gv$session group by username;

 

alter user xxx    account lock; extract pump 进程 向源端数据库测试表中插入验证数据

insert into xxx.ogg_test values(1,sysdate);

 

commit; 到新系统查询数据是否同步成功

在新系统数据库查询

select * from xxx.test; 若确认数据同步完成,停止extract pump 进程

stop ext1

stop dp1 replicat 进程

stop rep1 在 操作 执行下面的SQL ,生成用于 用外键约束的脚本文件:

set echo off verify off trim on heading off feedback off

set pagesize 2000 linesize 150

 

spool enable_foreign_constraints.sql

select 'alter table '||owner||'.'||table_name|| ' enable constraint '||constraint_name||';'

from dba_constraints

where constraint_type = 'R' and owner in('PRDABPPVMI1','PRDSPUSERVMI1');

spool off  在新数据库执行enable_foreign_constraints.sql 脚本启用外键约束。 然后执行以下语句确认所有的外键约束都已经启用:

Col owner for a10

Col table_name for a30

Col constraint_name for a30

select owner, table_name, constraint_name, status

from dba_constraints

where constraint_type='R' and owner in('PRDABPPVMI1','PRDSPUSERVMI1');  执行下面的SQL ,生成用于启用级联删除的脚本文件:

set echo off verify off trim on heading off feedback off

set pagesize 2000 linesize 150

 

spool ensable_cascade_delete_constraints.sql

 

select 'alter table '||owner||'.'||table_name||'  enable constraint '||constraint_name||';'

from dba_constraints

where owner in('PRDABPPVMI1','PRDSPUSERVMI1') and constraint_type = 'R' and delete_rule = 'CASCADE';

 

spool off 在新数据库执行enable_cascade_delete_constraints.sql 脚本禁用级联删除。 然后执行以下语句确认所有的级联删除都已经禁用:

select owner, table_name, constraint_name, status

from dba_constraints

where delete_rule = 'CASCADE'and owner in('PRDABPPVMI1','PRDSPUSERVMI1');  使用以下命令将新数据库的job 队列修改为 1000 (默认值,可根据具体情况设置) ,从而达到启用目标库job 的目的:

alter system set job_queue_processes =1000 scope = both sid = '*';  修改为以后使用以下命令确认当前的修改已经生效,job 队列为1000

show parameter job; 执行下面的语句,生成启用触发器的脚本文件enable_triggers.sql

set echo off verify off trim on heading off feedback off

set pagesize 2000 linesize 150

 

spool  enable_triggers.sql

select 'alter trigger '||owner||'.'||trigger_name|| ' enable;'

from dba_triggers

where owner in('PRDABPPVMI1','PRDSPUSERVMI1');

 

spool off  执行脚本enable_triggers.sql 启用触发器。然后执行以下语句确认所有的触发器都已经被启用:

sqlplus / as sysdba

@ enable_triggers.sql

 

select owner, trigger_name, status

from dba_triggers

where owner in('PRDABPPVMI1','PRDSPUSERVMI1')  由于数据库上sequence 较多,建议用数据泵将源库上的sequence 导入到新库 建议用数据泵将源库上的物化视图导入到新库 

慢排查方法 查看进程延迟信息

GGSCI (db1) 8> info all

 

Program     Status      Group       Lag at Chkpt  Time Since Chkpt

 

MANAGER     RUNNING                                          

REPLICAT    RUNNING     R_TBCS        18:20:00      00:10:07   

REPLICAT    RUNNING     R_TBCS2       00:00:00      00:00:00    Lag at Chkpt ’较大说明进程延迟较大,数据还没追平,可以考虑拆分进程 Time Since Chkpt ’较大说明replicat 进程正在执行的sql 比较慢,可以通过以下方法排查

1. 查找当前复制进程的pid

ps -ef | grep r_tbcs

2. 根据r_tbcs 的进程号找到连接数据库进程的pid

ps -ef | grep <r_tbcs pid>

3. 根据连接数据库进程的pid 找到数据库中session sid

4. 查找数据库session 正在执行的sql 分析sql 的执行计划看是否可以优化(例如:添加索引,更新统计信息等)。 replicat 进程的方法1. 添加新的replicate 进程和配置文件 略,具体步骤参考3.8.82. 停止replicat 进程

cd $GG_HOME

  ggsci

  GGSCI> stop r_tbcs3. 检查replicat 进程的checkpoint 信息  

  GGSCI>info r_tbcs, showch

-- 记录下Current Checkpoint信息中的sequence和RBA值。

  Current Checkpoint (position of last record read in the data source):

    Sequence #: 2157

    RBA: 2856752

    Timestamp: 2014-09-03 08:13:58.035316

    Extract Trail: /oracle/goldengate/ggs/dirdat/r14. 修改新建replicat 进程的read checkpoint 信息 根据step 3 中得到的Current checkpoint 信息修改新建replicat 进程的checkpoint 信息,之后新建的replicat 进程就会从旧replicat 进程停止的位置开始抓取新的信息

GGSCI> alter r_tbcs_0, extseqno <sequence>, extrba <RBA>

GGSCI> alter r_tbcs_1,, extseqno <sequence>, extrba <RBA>5. 启动新建的replicat 进程

GGSCI>start r_tbcs_0

GGSCI>start r_tbcs_16. 删除旧的replicat 进程 

GGSCI>dblogin userid ggadmin,password ***

GGSCI>delete r_tbcs 

相关推荐