OGG資料庫遷移方案(四)

pingdanorcale發表於2023-03-14

監控

源庫

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.8

2. 停止replicat 程式

cd $GG_HOME

  ggsci

  GGSCI> stop r_tbcs

3. 檢查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/r1

4. 修改新建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_1

6. 刪除舊的replicat 程式 

GGSCI>dblogin userid ggadmin,password ***

GGSCI>delete r_tbcs

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10201716/viewspace-2939530/,如需轉載,請註明出處,否則將追究法律責任。

相關文章