當前位置:
首頁 > 知識 > Oracle CDC簡介及非同步在線日誌CDC部署示例

Oracle CDC簡介及非同步在線日誌CDC部署示例

摘要

最近由於工作需要,花時間研究了一下Oracle CDC功能和LogMiner工具,希望能找到一種穩定、高效的技術來實現Oracle增量數據抽取功能。以下是個人的部分學習總結和部署實踐。

1. Oracle CDC 簡介

很多人都認為,只要是涉及到資料庫數據複製和增量數據抽取,都是需要購買收費軟體的。實際上,我們通過Oracle提供的CDC和LogMiner等免費工具也能實現資料庫數據複製和增量數據抽取,各種數據複製軟體只是使得獲取增量數據更加便捷,或者是可以支持更多的擴展功能(例如:異構資料庫之間的同步,ETL過程的數據清洗、裝換),但實際Oracle本身是支持CDC機制,只是很少有人關注,操作起來也有些複雜,而且據傳言並不穩定,常常見到論壇上爆出一些莫名其妙的問題。

Oracle11gR2提供給我們以下幾種CDC機制:

1.1 Synchronous Change Data Capture Configuration(同步複製)

Oracle CDC簡介及非同步在線日誌CDC部署示例

原理很簡單,原表、目標表必須是同一個庫,採用觸發器的機制(設置同步CDC後,並看不到觸發器,但實際運行機理還是觸發器的機制)將原表內容複製到另一個目標表。這個機制就不多說了,和自己給表建觸發器沒什麼太大差別。

1.2 Asynchronous HotLog Configuration(非同步在線日誌CDC)

Oracle CDC簡介及非同步在線日誌CDC部署示例

這個過程已經沒有觸發器了,而是使用Redo Log,但是使用在線日誌,並不是歸檔日誌。並且原表、目標表仍然必須是同一個庫。這種模式是相對簡單的,同時這種模式是在Oracle 10以上才產生的,9i是沒有這個機制的。

1.3 Asynchronous Distributed HotLog Configuration(非同步分布式CDC)

Oracle CDC簡介及非同步在線日誌CDC部署示例

實際這個模式是對非同步在線日誌CDC的一種優化,也比較容易理解,就是加入了DB-LINK機制,使原表、目標表不在同一個資料庫。實際是和非同步在線日誌CDC沒有什麼本質區別。

1.4 Asynchronous Autolog Online Change Data Capture Configuration(非同步在線日誌複製CDC)

Oracle CDC簡介及非同步在線日誌CDC部署示例

非同步在線日誌複製CDC模式就要高級很多了,使用Standby Redo Log(熱備資料庫日誌),實際就是使用Oracle的熱備機制,將日誌寫入了熱備資料庫,目標表就可以建立在熱備庫上,這對主資料庫性能影響就進一步降低。

1.5 Asynchronous AutoLog Archive Change Data Capture Configuration(歸檔日誌CDC)

Oracle CDC簡介及非同步在線日誌CDC部署示例

歸檔日誌CDC模式是最完美的模式,但是需要有機制可以獲取歸檔日誌(並行文件系統技術),然後在目標端分析歸檔日誌進行變化數據處理,這種模式理論上來講,幾乎可以完全不影響原資料庫的性能。

坦白來說,我對Oracle理解並不深,只是為了解決特定的幾個問題多看了一點,在現實工作中遇到類似問題需要解決的,或對技術痴狂的同學可以研究一下,我貼上了4種模式具體的設置步驟,雖然是英文的,但是還是非常明確的。(我比較推薦使用第二種,因為設置比較簡單,性能上也屬於中規中矩,如果沒有什麼特別要求,可以採用非同步在線日誌CDC。

以下是我對非同步在線日誌CDC環境的部署測試。

2. 非同步在線日誌CDC環境部署2.1 環境配置準備

(1)確認資料庫版本

  1. SQL> select * from v$version;
  2. BANNER
  3. --------------------------------------------------------------------------------
  4. Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
  5. PL/SQL Release 11.2.0.1.0 - Production
  6. CORE 11.2.0.1.0 Production
  7. TNS for Linux: Version 11.2.0.1.0 - Production
  8. NLSRTL Version 11.2.0.1.0 - Production

(2)配置資料庫參數

  1. SQL> alter system set streams_pool_size=50m;
  2. System altered.
  3. SQL> alter system set java_pool_size=50m;
  4. System altered.
  5. SQL> alter system set undo_retention=3600;
  6. System altered.
  7. SQL> show parameter streams_pool
  8. NAME TYPE VALUE
  9. ------------------------------------ ----------- ------------------------------
  10. streams_pool_size big integer 52M
  11. SQL> show parameter java_pool
  12. NAME TYPE VALUE
  13. ------------------------------------ ----------- ------------------------------
  14. java_pool_size big integer 52M
  15. SQL> show parameter undo_re
  16. NAME TYPE VALUE
  17. ------------------------------------ ----------- ------------------------------
  18. undo_retention integer 3600

(3)開啟歸檔及補充日誌

  1. SQL> archive log list
  2. Database log mode Archive Mode
  3. Automatic archival Enabled
  4. Archive destination USE_DB_RECOVERY_FILE_DEST
  5. Oldest online log sequence 487
  6. Next log sequence to archive 489
  7. Current log sequence 489
  8. SQL> alter database force logging;
  9. Database altered.
  10. SQL> alter database add supplemental log data;
  11. Database altered.
  12. SQL> select LOG_MODE,FORCE_LOGGING,SUPPLEMENTAL_LOG_DATA_MIN from v$database;
  13. LOG_MODE FOR SUPPLEME
  14. ------------ --- --------
  15. ARCHIVELOG YES YES

(4)準備測試表employee_info

  1. SQL> create table employee_info(n number,name varchar(20),address varchar(150),department varchar(120),organization varchar(150)) tablespace datafile1;
  2. Table created.
  3. SQL> insert into employee_info values(1, "bendsha", "lianhang road, shanghai, China", "AnyBackup", "EISOO");
  4. 1 row created.
  5. SQL> insert into employee_info values(2, "bendsha", "lianhang road, shanghai, China", "AnyBackup", "EISOO");
  6. 1 row created.

2.2 創建發布者和訂閱者

(1)創建發布者並授權

  1. SQL> create tablespace cdc_datafile datafile "/u01/app/oracle/orcl/cdc_datafile.dbf" size 1G;
  2. Tablespace created.
  3. SQL> create user cdc_publisher identified by cdc_publisher default tablespace cdc_datafile temporary tablespace temp;
  4. User created.
  5. SQL> grant create session TO cdc_publisher;
  6. Grant succeeded.
  7. SQL> grant create table TO cdc_publisher;
  8. Grant succeeded.
  9. SQL> grant create sequence TO cdc_publisher;
  10. Grant succeeded.
  11. SQL> grant create procedure TO cdc_publisher;
  12. Grant succeeded.
  13. SQL> grant create any job TO cdc_publisher;
  14. Grant succeeded.
  15. SQL> grant execute_catalog_role TO cdc_publisher;
  16. Grant succeeded.
  17. SQL> grant select_catalog_role TO cdc_publisher;
  18. Grant succeeded.
  19. SQL> grant execute ON dbms_cdc_publish TO cdc_publisher;
  20. Grant succeeded.
  21. SQL> grant execute ON dbms_lock TO cdc_publisher;
  22. Grant succeeded.
  23. SQL> grant unlimited tablespace TO cdc_publisher;
  24. Grant succeeded.
  25. SQL> execute dbms_streams_auth.grant_admin_privilege("CDC_PUBLISHER");
  26. PL/SQL procedure successfully completed.
  27. SQL> grant all on backupuser.employee_info to cdc_publisher;
  28. Grant succeeded.

(2)創建訂閱者並授權

  1. SQL> create user cdc_subscriber identified by cdc_subscriber default tablespace cdc_datafile temporary tablespace temp;
  2. User created.
  3. SQL> grant create session TO cdc_subscriber;
  4. Grant succeeded.

2.3 發布/訂閱具體數據

(1)發布:準備源表(Source Table)

  1. SQL>
  2. conn cdc_publisher/cdc_publisher
  3. BEGIN
  4. DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(TABLE_NAME => "backupuser.employee_info");
  5. END;
  6. Connected.
  7. SQL> 2 3 4 /
  8. PL/SQL procedure successfully completed.

(2)發布:創建變更集(Data Set)

  1. SQL>
  2. conn cdc_publisher/cdc_publisher
  3. BEGIN
  4. DBMS_CDC_PUBLISH.CREATE_CHANGE_SET(
  5. change_set_name => "cdc_employee_info_cs",
  6. description => "Change set for backupuser.employee_info info",
  7. change_source_name => "HOTLOG_SOURCE",
  8. stop_on_ddl => "y"
  9. );
  10. END;
  11. Connected.
  12. SQL> 2 3 4 5 6 7 8 9 /
  13. PL/SQL procedure successfully completed.

(3)發布:創建變更表(Change Table)

  1. SQL>
  2. conn cdc_publisher/cdc_publisher
  3. BEGIN
  4. DBMS_CDC_PUBLISH.CREATE_CHANGE_TABLE(
  5. owner => "cdc_publisher",
  6. change_table_name => "employee_info_ct",
  7. change_set_name => "cdc_employee_info_cs",
  8. source_schema => "backupuser",
  9. source_table => "employee_info",
  10. column_type_list =>"n number,name varchar(20),address varchar(150)",
  11. capture_values => "both",
  12. rs_id => "y",
  13. row_id => "n",
  14. user_id => "n",
  15. timestamp => "n",
  16. object_id => "n",
  17. source_colmap => "n",
  18. target_colmap => "y",
  19. options_string =>"");
  20. END;
  21. 19 /
  22. PL/SQL procedure successfully completed.

(4)發布:激活變更集(Data Set)

  1. SQL>
  2. conn cdc_publisher/cdc_publisher
  3. BEGIN
  4. DBMS_CDC_PUBLISH.ALTER_CHANGE_SET(
  5. change_set_name => "cdc_employee_info_cs",
  6. enable_capture => "y");
  7. END;
  8. Connected.
  9. SQL> 2 3 4 5 6 /
  10. PL/SQL procedure successfully completed.

(5)授權給訂閱者

  1. SQL>
  2. conn cdc_publisher/cdc_publisher
  3. GRANT SELECT ON cdc_publisher.employee_info_ct TO cdc_subscriber;
  4. conn / as sysdba
  5. GRANT CREATE TABLE TO cdc_subscriber;
  6. GRANT CREATE SESSION TO cdc_subscriber;
  7. GRANT CREATE VIEW TO cdc_subscriber;
  8. GRANT UNLIMITED TABLESPACE TO cdc_subscriber;
  9. Grant succeeded.

(6)訂閱:創建訂閱集

  1. SQL>
  2. conn cdc_subscriber/cdc_subscriber
  3. BEGIN
  4. DBMS_CDC_SUBSCRIBE.CREATE_SUBSCRIPTION(
  5. change_set_name => "cdc_employee_info_cs",
  6. description => "Change data for employee_info",
  7. subscription_name => "employee_info_sub");
  8. END;
  9. Connected.
  10. SQL> 2 3 4 5 6 7 /
  11. PL/SQL procedure successfully completed.

(7)訂閱:開始訂閱表信息

  1. SQL>
  2. conn cdc_subscriber/cdc_subscriber
  3. BEGIN
  4. DBMS_CDC_SUBSCRIBE.SUBSCRIBE(
  5. subscription_name => "employee_info_sub",
  6. source_schema => "backupuser",
  7. source_table => "employee_info",
  8. column_list => "n,name,address",
  9. subscriber_view => "employee_info_view");
  10. END;
  11. Connected.
  12. SQL> 2 3 4 5 6 7 8 9 /
  13. PL/SQL procedure successfully completed.

(8)訂閱:激活訂閱

  1. SQL>
  2. conn cdc_subscriber/cdc_subscriber
  3. BEGIN
  4. DBMS_CDC_SUBSCRIBE.ACTIVATE_SUBSCRIPTION(
  5. subscription_name => "employee_info_sub");
  6. END;
  7. Connected.
  8. SQL> 2 3 4 5 /
  9. PL/SQL procedure successfully completed.

(9)訂閱:擴展訂閱窗口

  1. SQL>
  2. conn cdc_subscriber/cdc_subscriber
  3. BEGIN
  4. DBMS_CDC_SUBSCRIBE.EXTEND_WINDOW(
  5. subscription_name => "employee_info_sub");
  6. END;
  7. Connected.
  8. SQL> 2 3 4 5 /
  9. PL/SQL procedure successfully completed.

(10)訂閱:查看訂閱視圖內容

  1. SQL>
  2. conn cdc_subscriber/cdc_subscriber
  3. Connected.
  4. SQL> select * from employee_info_view;
  5. no rows selected

2.4 測試發布/訂閱

(1)源表employee_info變更

  1. SQL>
  2. conn backupuser/backupuser123
  3. insert into employee_info values(1, "bendsha", "lianhang road, shanghai, China", "SmartData", "SmartDB");
  4. insert into employee_info values(2, "bendsha", "lianhang road, shanghai, China", "SmartData", "SmartDB");
  5. insert into employee_info values(3, "bendsha", "lianhang road, shanghai, China", "SmartData", "SmartDB");
  6. update employee_info set name = "zhuzi" where n = 2;
  7. delete from employee_info where n = 1;
  8. Connected.
  9. SQL>
  10. 1 row created.
  11. SQL>
  12. 1 row created.
  13. SQL>
  14. 1 row created.
  15. SQL>
  16. 1 row updated.
  17. SQL>
  18. 1 row deleted.
  19. SQL> commit;
  20. Commit complete.

(2)查看數據發布情況

  1. SQL>
  2. conn cdc_publisher/cdc_publisher
  3. Connected.
  4. SQL> select OPERATION$,n,name,address from employee_info_ct;
  5. OP N NAME
  6. -- ---------- --------------------
  7. ADDRESS
  8. --------------------------------------------------------------------------------
  9. I 1 bendsha
  10. lianhang road, shanghai, China
  11. I 2 bendsha
  12. lianhang road, shanghai, China
  13. I 3 bendsha
  14. lianhang road, shanghai, China
  15. OP N NAME
  16. -- ---------- --------------------
  17. ADDRESS
  18. --------------------------------------------------------------------------------
  19. UO 2 bendsha
  20. lianhang road, shanghai, China
  21. UN 2 zhuzi
  22. lianhang road, shanghai, China
  23. D 1 bendsha
  24. lianhang road, shanghai, China
  25. 6 rows selected.

(3)查看數據訂閱情況

  1. SQL>
  2. conn cdc_subscriber/cdc_subscriber
  3. BEGIN
  4. DBMS_CDC_SUBSCRIBE.EXTEND_WINDOW(
  5. subscription_name => "employee_info_sub");
  6. END;
  7. Connected.
  8. SQL> 2 3 4 5 /
  9. PL/SQL procedure successfully completed.
  10. SQL> select OPERATION$,n,name,address from employee_info_view;
  11. OP N NAME
  12. -- ---------- --------------------
  13. ADDRESS
  14. --------------------------------------------------------------------------------
  15. I 1 bendsha
  16. lianhang road, shanghai, China
  17. I 2 bendsha
  18. lianhang road, shanghai, China
  19. I 3 bendsha
  20. lianhang road, shanghai, China
  21. OP N NAME
  22. -- ---------- --------------------
  23. ADDRESS
  24. --------------------------------------------------------------------------------
  25. UO 2 bendsha
  26. lianhang road, shanghai, China
  27. UN 2 zhuzi
  28. lianhang road, shanghai, China
  29. D 1 bendsha
  30. lianhang road, shanghai, China
  31. 6 rows selected.

(4)清除變更數據集

  1. SQL>
  2. conn cdc_subscriber/cdc_subscriber
  3. BEGIN
  4. DBMS_CDC_SUBSCRIBE.PURGE_WINDOW(
  5. subscription_name => "employee_info_sub");
  6. END;
  7. Connected.
  8. SQL> 2 3 4 5 /
  9. PL/SQL procedure successfully completed.
  10. SQL> select OPERATION$,n,name,address from employee_info_view;
  11. no rows selected

(5)刪除發布數據

  1. SQL> conn cdc_publisher/cdc_publisher
  2. Connected.
  3. SQL> truncate table employee_info_ct;
  4. Table truncated.
  5. SQL> select OPERATION$,n,name,address from employee_info_ct;
  6. no rows selected

3. 常見問題解決方法3.1 ORA-31466: 未找到發布內容

執行訂閱表信息時,提示ORA-31466:未找到發布內容,排查發現是沒有將變更表cdc_employee_info的查詢許可權賦予訂閱者用戶cdc_subscriber導致。

解決方法:

  1. SQL> conn cdc_publisher/cdc_publisher
  2. Connected.
  3. SQL> grant select on cdc_employee_info to cdc_subscriber;
  4. Grant succeeded.

3.2 激活訂閱之後,對源表進行操作,捕獲不到數據

我一開始遇到這個問題是監控系統用戶SYS用戶的employee_info表,沒有出現任何異常,就是捕獲不到數據,後來我替換給backupuser用戶的employee_info表,按照以上步驟操作,就能正常捕獲到數據了,官網也沒查到相關的文檔說明,很奇怪,還需要進一步研究。

4. 參考文檔
喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

關於微信和支付寶自動退款介面的接入總結
Amazing ASP.NET Core 2.0
多線程編程——part 2 線程的生命周期和優先順序
Swift和Javascript的神奇魔法

TAG:達人科技 |

您可能感興趣

ASP.NET Core MVC+EF Core從開發到部署
OCS Inventory NG部署
德國Media Broadcast將於今秋完成DVB-T2服務部署
Linux部署Nginx+Mysql+PHP+PHPMyAdmin4環境
Aruba OnConnect 方案部署
Linux 小白的 .NET Core 部署之路
BM推出了AIOpenScale和Multi-cloud Manager,以簡化AI和雲部署
快思聰:新的Crestron DM XiODirector網路設備簡化DMNVX網路視音頻系統的部署
愛立信助力Verizon CBRS頻段的LTE部署
ASDK系列2:在Azure新的Region上安裝部署Azure Stack開發工具包的第二種方法
LNMP環境下部署個人博客WordPress
教你如何在CentOS 6.5下部署Open-Falcon監控系統
記WEBLOGIC部署BUG(WEBSOCKET)
Lazarus Group在C Hack中部署其首個Mac惡意軟體
Chrome部署Material Design:標籤欄類似於Firefox早期版本
索尼為Xperia XA1/Plus和Ultra部署Android Oreo推送
Chrome部署Material Design:似Firefox早期版本
Semtech與Comcast旗下的machineQ宣布已在美國的10座城市部署LoRaWAN網路
塔吉特計劃與Electrify America、特斯拉、ChargePoint部署EV充電站
部署Rsyslog+LogAnalyzer+MySQL日誌伺服器