利用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$$
為U
,OLD_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程式碼思路:
- 增量遷移啟動時,為目標表建立物化檢視日誌;
- 遷移過程中,啟動一個執行緒,定時去查詢物化檢視日誌中的記錄;
- 如果有記錄,則獲取記錄,拼成對應操作的SQL語句,並在目標表中執行,並記下最新的
DML_ID
為lastID
,刪除物化檢視日誌中小於等於lastID
的記錄; - 執行緒執行一段時間後,如10秒內都沒有獲取到增量資料,則判定增量遷移結束,刪除物化檢視日誌。