高階複製-7、測試是否非主鍵表的同步
由於高階複製中明確要求複製的表需要有主鍵,那麼如果沒有主鍵複製是否能正常進行,如果不能正常進行那麼有什麼補救措施,這就是本節要測試的內容。
1、在主體定義表中建立不含主鍵的表,試圖將它加入主體組(複製組),看是否能完成複製:
1、1主體定義站點:
SQL> create table tb_test_nokey_rep(id int,name varchar2(10));
Table created.
SQL> declare
2 i int;
3 begin
4 for i in 1..100 loop
5 insert into tb_test_nokey_rep values(i,'liyx');
6 end loop;
7 commit;
8 end;
9 /
PL/SQL procedure successfully completed.
SQL> select count(1) from tb_test_nokey_rep;
COUNT(1)
----------
100
2、非主體定義站點
SQL> select table_name from user_tables;
TABLE_NAME
------------------------------
TB_TEST_CREATE_REP
TB_TEST_CREATE_REP2
TB_TEST_REP
SQL> create table tb_test_nokey_rep as select * from reptest.tb_test_nokey_rep@master.com;
Table created.
SQL> select count(1) from tb_test_nokey_rep;
COUNT(1)
----------
100
2、將測試表加入到複製組
SQL> execute dbms_repcat.create_master_repobject(sname=>'reptest',oname=>'tb_test_nokey_rep', type=>'table',use_existing_object=>true,gname=>'rep_mytest',copy_rows=>false);
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.resume_master_activity('REP_MYTEST',true);
PL/SQL procedure successfully completed.
3、測試在複製物件中修改資料,檢視同步情況:
3.1、主體定義站點:
SQL> select * from reptest.tb_test_nokey_rep where id=100;
ID NAME
---------- --------------------
100 liyx
SQL> insert into reptest.tb_test_nokey_rep values(100,'lirq');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from reptest.tb_test_nokey_rep where id=100;
ID NAME
---------- --------------------
100 liyx
100 lirq
3.2 非主體定義站點:
插入前:
SQL> select * from tb_test_nokey_rep where id=100;
ID NAME
---------- --------------------
100 liyx
SQL> reptest.tb_test_nokey_rep where id=100;
SP2-0734: unknown command beginning "reptest.tb..." - rest of line ignored.
插入後:
SQL> select * from reptest.tb_test_nokey_rep where id=100;
ID NAME
---------- --------------------
100 liyx
看來,沒有主建的主體複製物件,是無法同步的。
4、補救措施:
4.1、依據:
Q:如果一張表沒有主鍵,又確實需要複製,怎麼辦?
A:不建議在高階複製的環境中出現這樣的情況,應該確保每張表都有主鍵。如果確實存在這種情況,那麼需要用DBMS_REPCAT.SET_COLUMNS 來生成代用主鍵。
execute DBMS_REPCAT.SET_COLUMNS(sname => test', name => 'tabel', column_list =>'col1,col2,col3,col4');
其中column_list 是用逗號隔開的欄位列表,不能有空格。
注意:不要在執行set_columns 之前生成對於沒有主鍵的物件的複製支援,也就是不要執行generate_replication_support,否則會導致all_repobject 檢視中該物件狀態變為ERROR,而無法再次set_columns。
如果誤執行了複製支援而又沒有成功,那麼需要刪除掉這個複製物件再重新生成。也就是在對沒有主鍵的表生成複製的時候,必須遵循以下順序:
create_master_repobject -> set_columns -> generate_replication_support
4.2、刪除複製物件組:
SQL> execute dbms_repcat.drop_master_repobject(sname=>'reptest',oname=>'tb_test_nokey_rep',type=>'table');
PL/SQL procedure successfully completed.
4.3、再次建立物件組
SQL> execute dbms_repcat.create_master_repobject(sname=>'reptest',oname=>'tb_test_nokey_rep', type=>'table',use_existing_object=>true,gname=>'rep_mytest',copy_rows=>true);
PL/SQL procedure successfully completed.
SQL> exec dbms_repcat.SET_COLUMNS(sname=>'reptest',oname=>'tb_test_nokey_rep',column_list=>'id,name');
PL/SQL procedure successfully completed.
SQL> exec dbms_repcat.resume_master_activity('rep_mytest',true);
PL/SQL procedure successfully completed.
SQL> select * from reptest.tb_test_nokey_rep where id=100;
ID NAME
---------- --------------------
100 liyx
100 lirq
在非主體定義站點測試:
SQL> select * from reptest.tb_test_nokey_rep where id=100;
ID NAME
---------- --------------------
100 liyx
還是沒有同步.
檢視dba_repobject發現複製物件並沒有產生複製支援,暈:
SQL> col sname for a10;
SQL> col oname for a10;
SQL> col gname for a10;
SQL> select gname,sname,oname,status from dba_repobject;
GNAME SNAME ONAME STATUS
---------- ---------- ---------- --------------------
REP_MYTEST REPTEST TB_TEST_CR VALID
EATE_REP
REP_MYTEST REPTEST TB_TEST_CR ERROR
EATE_REP2
REP_MYTEST REPTEST TB_TEST_NO VALID
KEY_REP
REP_MYTEST REPTEST TB_TEST_RE VALID
P
GNAME SNAME ONAME STATUS
---------- ---------- ---------- --------------------
REP_MYTEST REPTEST TB_TEST_RE VALID
P$RP
REP_MYTEST REPTEST TB_TEST_RE VALID
P$RP
6 rows selected.
再次回頭使複製物件產生複製支援:
SQL> execute dbms_repcat.suspend_master_activity('rep_mytest');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.GENERATE_REPLICATION_SUPPORT(sname=>'reptest',oname=>'tb_test_nokey_rep',type=>'table');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.GENERATE_REPLICATION_SUPPORT(sname=>'reptest',oname=>'tb_test_create_rep',type=>'table');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.resume_master_activity('rep_mytest',true);
PL/SQL procedure successfully completed.
SQL> select gname,sname,oname,status from dba_repobject;
GNAME SNAME ONAME STATUS
---------- ---------- ---------- --------------------
REP_MYTEST REPTEST TB_TEST_CR VALID
EATE_REP
REP_MYTEST REPTEST TB_TEST_CR VALID
EATE_REP$R
P
REP_MYTEST REPTEST TB_TEST_CR VALID
EATE_REP$R
P
GNAME SNAME ONAME STATUS
---------- ---------- ---------- --------------------
REP_MYTEST REPTEST TB_TEST_CR ERROR
EATE_REP2
REP_MYTEST REPTEST TB_TEST_NO VALID
KEY_REP
REP_MYTEST REPTEST TB_TEST_NO VALID
KEY_REP$RP
REP_MYTEST REPTEST TB_TEST_NO VALID
KEY_REP$RP
GNAME SNAME ONAME STATUS
---------- ---------- ---------- --------------------
REP_MYTEST REPTEST TB_TEST_RE VALID
P
REP_MYTEST REPTEST TB_TEST_RE VALID
P$RP
REP_MYTEST REPTEST TB_TEST_RE VALID
P$RP
10 rows selected.
但是在向tb_test_nokey_rep表插入資料時,還是報錯:
SQL> delete from reptest.tb_test_nokey_rep where id=100;
delete from reptest.tb_test_nokey_rep where id=100
*
ERROR at line 1:
ORA-04067: ????stored procedure "REPTEST.TB_TEST_NOKEY_REP$RP" ???
ORA-01085: ?? rpc ? "REPTEST.TB_TEST_NOKEY_REP$RP.REP_DELETE" ?????
ORA-02063: preceding 2 lines from SNAP
這個錯誤就是報儲存過程不存在的問題,算了,還是重新註冊一次。
SQL> execute dbms_repcat.suspend_master_activity('rep_mytest');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.drop_master_repobject(sname=>'reptest',oname=>'tb_test_nokey_rep',type=>'table');
PL/SQL procedure successfully completed.
SQL> select sname,oname,status from dba_repobject;
SNAME ONAME STATUS
---------- ---------- --------------------
REPTEST TB_TEST_CR VALID
EATE_REP
REPTEST TB_TEST_CR VALID
EATE_REP$R
P
REPTEST TB_TEST_CR VALID
EATE_REP$R
P
SNAME ONAME STATUS
---------- ---------- --------------------
REPTEST TB_TEST_CR ERROR
EATE_REP2
REPTEST TB_TEST_RE VALID
P
REPTEST TB_TEST_RE VALID
P$RP
REPTEST TB_TEST_RE VALID
P$RP
SNAME ONAME STATUS
---------- ---------- --------------------
7 rows selected.
SQL> execute dbms_repcat.drop_master_repobject(sname=>'reptest',oname=>'tb_test_create_rep',type=>'table');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.drop_master_repobject(sname=>'reptest',oname=>'tb_test_create_rep',type=>'table');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.create_master_repobject(sname=>'reptest',oname=>'tb_test_nokey_rep', type=>'table',use_existing_object=>true,gname=>'rep_mytest',copy_rows=>true);
PL/SQL procedure successfully completed.
SQL> exec dbms_repcat.SET_COLUMNS(sname=>'reptest',oname=>'tb_test_nokey_rep',column_list=>'id,name');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.GENERATE_REPLICATION_SUPPORT(sname=>'reptest',oname=>'tb_test_nokey_rep',type=>'table');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.create_master_repobject(sname=>'reptest',oname=>'tb_test_create_rep', type=>'table',use_existing_object=>true,gname=>'rep_mytest',copy_rows=>true);
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.GENERATE_REPLICATION_SUPPORT(sname=>'reptest',oname=>'tb_test_create_rep',type=>'table');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.drop_master_repobject(sname=>'reptest',oname=>'tb_test_create_rep2',type=>'table');
PL/SQL procedure successfully completed.
SQL> select sname,oname,status from dba_repobject;
SNAME ONAME STATUS
---------- ---------- --------------------
REPTEST TB_TEST_CR VALID
EATE_REP
REPTEST TB_TEST_CR VALID
EATE_REP$R
P
REPTEST TB_TEST_CR VALID
EATE_REP$R
P
SNAME ONAME STATUS
---------- ---------- --------------------
REPTEST TB_TEST_NO VALID
KEY_REP
REPTEST TB_TEST_NO VALID
KEY_REP$RP
REPTEST TB_TEST_NO VALID
KEY_REP$RP
REPTEST TB_TEST_RE VALID
P
SNAME ONAME STATUS
---------- ---------- --------------------
REPTEST TB_TEST_RE VALID
P$RP
REPTEST TB_TEST_RE VALID
P$RP
9 rows selected.
檢視資料同步的情況:
主體定義節點:
SQL> select count(1) from reptest.tb_test_create_rep;
COUNT(1)
----------
3
SQL> select * from reptest.tb_test_create_rep;
ID NAME
---------- --------------------
4 lirq
1 ???
2 ???
SQL> select count(1) from reptest.tb_test_nokey_rep;
COUNT(1)
----------
101
SQL> select * from reptest.tb_test_nokey_rep where id=100;
ID NAME
---------- --------------------
100 liyx
100 lirq
非主體定義節點:
SQL> select count(1) from reptest.tb_test_create_rep;
COUNT(1)
----------
3
SQL> select * from reptest.tb_test_create_rep;
ID NAME
---------- ----------
4 lirq
1 ???
2 ???
SQL> select count(1) from reptest.tb_test_nokey_rep;
COUNT(1)
----------
100
SQL> select count(1) from reptest.tb_test_nokey_rep;
COUNT(1)
----------
100
SQL> select * from reptest.tb_test_nokey_rep where id=100;
ID NAME
---------- --------------------
100 liyx
對於不含有主鍵的表複製,還是沒有做成功。
檢視錯誤
select source,status,timestamp,master,sname,oname,message from dba_repcatlog
order by timestamp desc
;
發現最近的幾次錯誤都是23308或23309
在網上找了下關於23308和23309的錯誤,摘錄如下:
在維護主備庫的高階複製時,發現有一張表始終無法複製,複製時,總是報以下錯誤:
ORA-23309: object TEST.RECORD_DETAIL of type TABLE exists
ORA-23308: object TEST.RECORD_DETAIL does not exist or is invalid
ORA-23419: regenerate replication support before resuming master activity
解決:
偶然的機會,在比較主備庫的表結構時,發現主庫此表的user_id欄位有非空約束,而備庫沒有此約束。
在給備庫此表的user_id欄位加上非空約束後,重新執行高階複製成功。
從內容上來看,說明兩邊表結構不一致時可能會出現這上錯誤。
回到開頭,記得在非主體站點建表是通過CTAS建立的,這確實可能會造成表結構不一致,果然發現兩表的NAME的欄位型別上一個為varchar2(10),另一個為varchar2(20)。下面的調整就很簡單了:
接下來要做的事情就簡單了,請看下流程:
主體定義站點:
SQL> exec dbms_repcat.suspend_master_activity('rep_mytest');
PL/SQL procedure successfully completed.
非主體定義站點:
SQL> drop table reptest.tb_test_nokey_rep;
Table dropped.
SQL> create table reptest.tb_test_nokey_rep(id number(38),name varchar2(20));
Table created.
主體定義站點:
SQL> execute dbms_repcat.create_master_repobject(sname=>'reptest',oname=>'tb_test_nokey_rep', type=>'table',use_existing_object=>true,gname=>'rep_mytest',copy_rows=>true);
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.set_columns(sname=>'reptest',oname=>'tb_test_nokey_rep',column_list=>'id,name');
PL/SQL procedure successfully completed.
SQL> execute dbms_repcat.GENERATE_REPLICATION_SUPPORT(sname=>'reptest',oname=>'tb_test_nokey_rep',type=>'table');
PL/SQL procedure successfully completed.
SQL>
SQL> execute dbms_repcat.resume_master_activity('rep_mytest',true);
PL/SQL procedure successfully completed.
SQL>
SQL> select count(1) from reptest.tb_test_nokey_rep;
COUNT(1)
----------
101
SQL> select * from reptest.tb_test_nokey_rep where id=100;
ID NAME
---------- ----------------------------------------
100 liyx
100 lirq
非主體定義站點:
SQL> select count(1) from reptest.tb_test_nokey_rep;
COUNT(1)
----------
101
SQL> select * from reptest.tb_test_nokey_rep where id=100;
ID NAME
---------- --------------------
100 liyx
100 lirq
總算是對不含主鍵的複製物件成功進行了複製。
5、順便測試truncate操作是否可以同步:
5.1、操作前:
5.1.1、主體定義站點:
SQL> select count(1) from reptest.tb_test_create_rep;
COUNT(1)
----------
3
5.1.2、非主體定義站點:
SQL> select count(1) from reptest.tb_test_create_rep;
COUNT(1)
----------
0
5.2 、操作
SQL> truncate table reptest.tb_test_create_rep;
Table truncated.
5.3、操作後:
5.3.1、主體定義站點:
SQL> select count(1) from reptest.tb_test_create_rep;
COUNT(1)
----------
0
5.3.2、非主體定義站點:
SQL> select count(1) from reptest.tb_test_create_rep;
COUNT(1)
----------
3
從測試結果來看,同步的是DML操作,並不能對DDL操作進行同步,要想將TRUNCATE這種操作進行同步,必須通過重新註冊複製物件來完成
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12350275/viewspace-683780/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 高階複製-6、測試是否可同步建表
- 高階複製-5、測試是否可同步DML操作
- 高階複製-4、非主體定義站點上的操作
- MySQL 的主從複製(高階篇)MySql
- MySQL的主從複製、半同步複製、主主複製詳解MySql
- MySQL主從複製、半同步複製和主主複製MySql
- MySQL進階:主主複製+Keepalived高可用MySql
- MySQL主從複製、半同步複製和主主複製概述MySql
- 主體複製概念和體系結構——高階複製
- 配置mysql5.5主從複製、半同步複製、主主複製MySql
- 主從複製、雙主複製及半同步複製、以及基於SSL的複製
- mongoDB的主從複製簡單測試MongoDB
- 關於高階複製的一些資料同步
- oracle 高階複製Oracle
- Oracle高階複製Oracle
- MySQL主從複製之半同步複製MySql
- MySQL主從複製之非同步複製MySql非同步
- 高階複製主站點主表新增欄位操作
- 高階複製-3、主體定義站點上的操作
- 高階複製總結
- 主從複製--非同步篇非同步
- MySQL 5.5 Semi-sync 半同步複製測試MySql
- MySQL5.7主從複製-半同步複製搭建MySql
- MySQL(二):主從複製結構、半同步複製、雙主複製結構、利用SSL實現安全的MySQL主從複製MySql
- oracle 表結構的非完全複製Oracle
- MySQL主從雙向同步複製MySql
- Oracle高階複製Step by StepOracle
- oracle高階複製(轉載)Oracle
- oracle 高階複製簡介Oracle
- 複製管理工具介紹——高階複製
- 關於Oracle 高階複製的概念Oracle
- Oracle 高階複製的概念及配置Oracle
- MySQL 5.7的安裝及主從複製(主從同步)MySql主從同步
- 改變複製物件結構對高階複製的影響物件
- [zt] 高階複製、流複製(Streams)、備庫區別
- MySQL的非同步複製和半同步複製MySql非同步
- MySQL的主從複製與MySQL的主主複製MySql
- 高階複製-2、準備工作