1. 程式人生 > >利用Oracle物化檢視日誌訂閱增量

利用Oracle物化檢視日誌訂閱增量

物化檢視的快速重新整理需要先構造物化檢視日誌,而物化檢視日誌中會記錄表的dml操作,因此可以通過物化檢視日誌訂閱Oracle增量。
1.物化檢視日誌名
物化檢視日誌名為MLOG$_表名。當表名長度超過20時,只取前20位;當出現截短後名稱重複時,會自動在物化檢視日誌名後面新增數字。
2.物化檢視日誌結構
基本欄位:
SNAPTIME$$:資料重新整理的時間;當該物化檢視日誌僅供一張物化檢視使用時,為4000-01-01 00:00:00;當其供多張物化檢視使用時,該欄位會記錄dml操作的時間。

DMLTYPE$$: 表示DML操作型別,I表示INSERT,D表示DELETE,U表示UPDATE。

OLD_NEW$$

:表示這個值是新值還是舊值。N表示新值,O表示舊值,U表示UPDATE操作。

CHANGE_VECTOR$$:表示修改向量,用來表示被修改的是哪個或哪幾個欄位。
特殊欄位:
(1)構建物化檢視日誌時添加了rowid,因此物化檢視日誌中會包含欄位:
M_ROW$$:儲存增量記錄的ROWID。

create materialized view log on student with rowid including new values;

(2)構建物化檢視日誌時添加了primary key,因此物化檢視日誌中會包含主鍵欄位

create materialized view log on
student with primary key including new values;

(3)構建物化檢視日誌時添加了SEQUENCE,因此物化檢視日誌中會包含欄位:
SEQUENCE$$:每個操作的SEQUENCE號,從而保證重新整理時按照順序進行重新整理。

CREATE MATERIALIZED VIEW LOG ON STUDENT WITH 
sequence ( C_ID, C_NAME ) including new VALUES;

(4)構建物化檢視日誌時添加了表的欄位名,因此物化檢視日誌中會包含這些欄位

CREATE MATERIALIZED VIEW
LOG ON STUDENT WITH C_ID, C_NAME including new VALUES;

3.注意點

(1)基於主鍵的物化檢視日誌,如果更新主鍵時,DML操作會轉為一條DELETE記錄和一條INSERT記錄。即更新主鍵操作被轉換為先插入新記錄,然後刪除舊記錄;
(2)當建立物化檢視日誌時包含INCLUDING NEW VALUES語句時,每條UPDATE操作會在物化檢視日誌中生成兩條記錄。一條對應UPDATE操作的原記錄DMLTYPE$$OLD_NEW$$都為U;一條對應UPDATE操作後的新記錄,DMLTYPE$$UOLD_NEW$$N

4.通過Oracle物化檢視日誌+Java程式碼實現Oracle增量遷移功能。
目標表結構:

CREATE TABLE STUDENT(
  C_ID NUMBER PRIMARY KEY,
  C_NAME VARCHAR(255) 
)

(1)實現該功能所需SQL語句:
(1.1) 建立物化檢視日誌

CREATE MATERIALIZED VIEW LOG ON STUDENT WITH ROWID,
sequence ( C_ID, C_NAME ) including new VALUES;

(1.2) 獲取增量記錄

SELECT C_ID, C_NAME, DMLTYPE$$ AS OPERATION, SEQUENCE$$ AS DML_ID FROM MLOG$_STUDENT ORDER BY SEQUENCE$$;

(1.3) 提交增量資料後,刪除已經提交的增量資料

 DELETE FROM MLOG$_STUDENT WHERE SEQUENCE$$ > lastID

(1.4) 增量完成後,刪除物化檢視日誌

DROP MATERIALIZED VIEW LOG ON STUDENT;

Java程式碼思路:

  1. 增量遷移啟動時,為目標表建立物化檢視日誌;
  2. 遷移過程中,啟動一個執行緒,定時去查詢物化檢視日誌中的記錄;
  3. 如果有記錄,則獲取記錄,拼成對應操作的SQL語句,並在目標表中執行,並記下最新的DML_IDlastID,刪除物化檢視日誌中小於等於lastID的記錄;
  4. 執行緒執行一段時間後,如10秒內都沒有獲取到增量資料,則判定增量遷移結束,刪除物化檢視日誌。