利用goldengate進行同步操作測試

lirenquan發表於2011-03-10

1、確認各程式組的狀態:
GGSCI (ora10g) 54> info all

Program     Status      Group       Lag           Time Since Chkpt

MANAGER     RUNNING                                          
EXTRACT     RUNNING     EMP_EXT1    00:00:00      00:00:00   
REPLICAT    RUNNING     EMP_REP1    00:00:00      00:00:05

2、測試最簡單的DDL和DML操作
1)測試建立表並插入記錄同步
源端:
SQL> select instance_name from v$instance;
INSTANCE_NAME
--------------------------------
orcl
SQL> show user      
USER is "SYS"
SQL> conn test/test
Connected.
SQL> create table tb_rep_ddl3(id int primary key,name varchar2(30));

Table created.

SQL> insert into tb_rep_ddl3 values(1,'lirq');

1 row created.

SQL> insert into tb_rep_ddl3 values(2,'liyx');

1 row created.

SQL> insert into tb_rep_ddl3 values(3,'yaocb');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
         1 lirq
         2 liyx
         3 yaocb
目標端:
SQL> select instance_name from v$instance;

INSTANCE_NAME
--------------------------------
ggtarge

SQL> show user
USER is "TEST"
SQL> select * from tb_rep_ddl3;
select * from tb_rep_ddl3
              *
ERROR at line 1:
ORA-00942: table or view does not exist

分析:
奇怪,怎麼沒有複製成功。
看看程式狀態:

GGSCI (ora10g) 59> info all       

Program     Status      Group       Lag           Time Since Chkpt

MANAGER     RUNNING                                          
EXTRACT     RUNNING     EMP_EXT1    00:00:00      00:00:02   
REPLICAT    ABENDED     EMP_REP1    00:32:29      00:03:26

靠,replicat組中止了,再檢視日誌:
GGSCI (ora10g) 60> view ggsevt
...
2010-12-08 08:23:09  ERROR   OGG-00519  Oracle GoldenGate Delivery for Oracle, emp_rep1.prm:  Fatal error executing DDL replication:
 error [Error code [1756], ORA-01756: quoted string not properly terminated, SQL ALTER SESSION SET NLS_CURRENCY=' ' ], no error hand
ler present.
2010-12-08 08:23:09  ERROR   OGG-01668  Oracle GoldenGate Delivery for Oracle, emp_rep1.prm:  PROCESS ABENDING.

最後發現了錯誤,初步確認是在操作DDL語句時,進行隱含DDL語句alter session造成的錯誤。這個是DDL錯誤
查了半天,嘗試了N多方法,包括調整ASSUMETARGETDEFS、HANDLECOLLISIONS和REPERROR引數,但發現還是不奏效。甚至將replicat組重建,依然是沒能解決這個。差不多絕望到要重灌資料庫了。
最後天可見憐,通過關鍵字匹配,找到了如下網頁:
http://gavinsoorma.com/2010/07/goldengate-ddl-synchronization-some-more-examples/comment-page-1/
這位國外的大牛,終於幫我解決了問題,簡單地來說,就是在replicat組的引數中新增如下內容
DDL INCLUDE ALL
DDLERROR DEFAULT IGNORE RETRYOP
以忽略掉一些DDL語句錯誤帶來的
修改內容如下:
GGSCI (ora10g) 61> edit params emp_rep1
REPLICAT emp_rep1
USERID gguser@192.168.0.88:1521/ggtarge, PASSWORD gguser
REPERROR 1756,DISCARD
REPERROR DEFAULT,DISCARD
DDL INCLUDE ALL
DDLERROR DEFAULT IGNORE RETRYOP
discardfile /u01/ora10g/discard/rep1.log,append,megabytes 10
ASSUMETARGETDEFS
HANDLECOLLISIONS
MAP test.*, TARGET test.*;

再次調起replicat組,檢視狀態:
GGSCI (ora10g) 62> start replicat emp_rep1

Sending START request to MANAGER ...
REPLICAT EMP_REP1 starting


GGSCI (ora10g) 63> info all

Program     Status      Group       Lag           Time Since Chkpt

MANAGER     RUNNING                                          
EXTRACT     RUNNING     EMP_EXT1    00:00:00      00:00:06   
REPLICAT    RUNNING     EMP_REP1    00:00:00      00:00:00 

gold,終於回到了久違的RUNNING狀態。
去目標端檢視結果:
SQL> select * from tb_rep_ddl3;
        ID NAME
---------- ------------------------------------------------------------
         1 lirq
         2 liyx
         3 yaocb
謝天謝地,終於見到了夢寐以求的結果
2)測試簡單的delete操作
源端:
SQL> select * from tb_rep_ddl3;
        ID NAME
---------- ------------------------------------------------------------
         1 lirq
         2 yaocb
         3 liyx
         4 lirq2

SQL> delete from tb_rep_ddl3;

4 rows deleted.
SQL> commit;

Commit complete.
目標端:
SQL> select * from tb_rep_ddl3;

no rows selected

SQL>

簡單的delete操作完全沒問題

3)測試簡單的update操作
源端:
SQL> select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
         1 lirq

SQL> update tb_rep_ddl3 set name='liyx';

1 row updated.

SQL> commit;

Commit complete.

SQL>  select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
         1 liyx
目標端:
SQL> select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
         1 lirq
為啥這麼簡單的update操作都沒有同步?
但是有個奇怪的現象是,針對數值型的更新,是可以同步的,如下示意:
源端:
SQL> alter table tb_rep_ddl3 add value number(1) default 3;

Table altered.

SQL> select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
     VALUE
----------
         1 liyx
         3


SQL> update tb_rep_ddl3 set value=4 where id=1;

1 row updated.

SQL> commit;

Commit complete.

SQL> select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
     VALUE
----------
         1 liyx
         4
目標端:

SQL> select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
     VALUE
----------
         1 lirq
         3


SQL> select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
     VALUE
----------
         1 lirq
         4
肯定又是哪個引數沒加好,經查reference文件,發現需要在replicat引數中新增GETUPDATEBEFORES
修改後如下:
REPLICAT emp_rep1
USERID gguser@192.168.0.88:1521/ggtarge, PASSWORD gguser
REPERROR 1756,DISCARD
REPERROR DEFAULT,DISCARD
DDL INCLUDE ALL
DDLERROR DEFAULT IGNORE RETRYOP
discardfile /u01/ora10g/discard/rep1.log,append,megabytes 10
ASSUMETARGETDEFS
HANDLECOLLISIONS
GETUPDATEBEFORES
MAP test.*, TARGET test.*;
再測試:
源端:
SQL>  select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
     VALUE
----------
         1 liyx
         4


SQL> update tb_rep_ddl3 set name='yaocb' where id=1;

1 row updated.

SQL> commit;

Commit complete.

SQL> select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
     VALUE
----------
         1 yaocb
         4
目標端:

SQL>  select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
     VALUE
----------
         1 liyx
         4


SQL> select * from tb_rep_ddl3;

        ID NAME
---------- ------------------------------------------------------------
     VALUE
----------
         1 yaocb
         4

4)測試truncate操作

3、測試ctas操作的同步
源端:
SQL> create table tb_rep_ctas as
  2  select * from dba_objects;

Table created.

SQL> desc tb_rep_ctas
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OWNER                                              VARCHAR2(30)
 OBJECT_NAME                                        VARCHAR2(128)
 SUBOBJECT_NAME                                     VARCHAR2(30)
 OBJECT_ID                                          NUMBER
 DATA_OBJECT_ID                                     NUMBER
 OBJECT_TYPE                                        VARCHAR2(19)
 CREATED                                            DATE
 LAST_DDL_TIME                                      DATE
 TIMESTAMP                                          VARCHAR2(19)
 STATUS                                             VARCHAR2(7)
 TEMPORARY                                          VARCHAR2(1)
 GENERATED                                          VARCHAR2(1)
 SECONDARY                                          VARCHAR2(1)

SQL> select bytes from user_segments where segment_name='TB_REP_CTAS';

     BYTES
----------
   6291456

SQL> select count(1),count(distinct object_id) from tb_rep_ctas;

  COUNT(1) COUNT(DISTINCTOBJECT_ID)
---------- ------------------------
     50746                    50746

SQL> select count(1),count(distinct object_id) from dba_objects;

  COUNT(1) COUNT(DISTINCTOBJECT_ID)
---------- ------------------------
     50746                    50746
目標端:
SQL> desc tb_rep_ctas
 Name                                                                                                              Null?    Type
 ----------------------------------------------------------------------------------------------------------------- -------- ----------------------------------------------------------------------------
 OWNER                                                                                                                      VARCHAR2(30)
 OBJECT_NAME                                                                                                                VARCHAR2(128)
 SUBOBJECT_NAME                                                                                                             VARCHAR2(30)
 OBJECT_ID                                                                                                                  NUMBER
 DATA_OBJECT_ID                                                                                                             NUMBER
 OBJECT_TYPE                                                                                                                VARCHAR2(19)
 CREATED                                                                                                                    DATE
 LAST_DDL_TIME                                                                                                              DATE
 TIMESTAMP                                                                                                                  VARCHAR2(19)
 STATUS                                                                                                                     VARCHAR2(7)
 TEMPORARY                                                                                                                  VARCHAR2(1)
 GENERATED                                                                                                                  VARCHAR2(1)
 SECONDARY                                                                                                                  VARCHAR2(1)
SQL> select bytes from user_segments where segment_name='TB_REP_CTAS';

     BYTES
----------
   6291456
SQL> select count(1),count(distinct object_id) from tb_rep_ctas;

  COUNT(1) COUNT(DISTINCTOBJECT_ID)
---------- ------------------------
     50083                    50083
SQL> select count(1),count(distinct object_id) from dba_objects;

  COUNT(1) COUNT(DISTINCTOBJECT_ID)
---------- ------------------------
     50083                    50083

兩邊表結構佔用空間大小完全一樣,但是資料結果不一樣。
分析原因,發現GOLDENGATE在預設情況下在處理DDL語句時,在TRAIL檔案中生成的是同步的SQL語句,不是資料內容。對於這種同步的方式,因為兩邊在操作ctas語句時,對應的源表是各自的dba_objects,因此結果可能會不一樣。

4、測試複雜的DML操作
1)insert into ... select操作
源端:
SQL> alter table tb_rep_ctas add constraint pk_object_id primary key(object_id);

Table altered.
SQL> select constraint_name,table_name from user_constraints where table_name='TB_REP_CTAS';

CONSTRAINT_NAME
------------------------------------------------------------
TABLE_NAME
------------------------------------------------------------
PK_OBJECT_ID
TB_REP_CTAS
SQL> insert into TB_REP_CTAS select * from dba_objects;

50747 rows created.

SQL> commit;

Commit complete.

SQL> select count(1),count(distinct object_id) from tb_rep_ctas;

  COUNT(1) COUNT(DISTINCTOBJECT_ID)
---------- ------------------------
     50750                    50750
目標端:
SQL> select count(1),count(distinct object_id) from tb_rep_ctas;

  COUNT(1) COUNT(DISTINCTOBJECT_ID)
---------- ------------------------
     50750                    50750
注:根據插入記錄的多少,處理記錄會有或多或少的延時。
2)關聯更新語句
源端:
SQL> update tb_rep_ctas set object_name='LIRQ'
  2  where object_id in
  3  (select object_id from dba_objects where rownum<=10);

10 rows updated.

SQL> commit;

Commit complete.

SQL> select count(1) from tb_rep_ctas where object_name='LIRQ';

  COUNT(1)
----------
        10

目標端:
SQL> select count(1) from tb_rep_ctas where object_name='LIRQ';

  COUNT(1)
----------
        10
3)rowid進行去重刪除
源端:
SQL> delete from tb_rep_ctas t1
  2  where rowid  3  ;

20420 rows deleted.

SQL> commit;

Commit complete.

SQL>  select count(1),count(distinct object_id) from tb_rep_ctas;

  COUNT(1) COUNT(DISTINCTOBJECT_ID)
---------- ------------------------
     30330                    30330
目標端:
SQL> select count(1),count(distinct object_id) from tb_rep_ctas;

  COUNT(1) COUNT(DISTINCTOBJECT_ID)
---------- ------------------------
     30330                    30330

強大,以rowid進行的刪除,居然都可以實現同步。不過由於刪除大量記錄,加上虛擬機器資源有限,所以整個延時比較明顯。

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

相關文章