Oracle Goldengate是如何保證資料有序和確保資料不丟失的?
工作中一直在用Oracle 的中介軟體Oracle GondenGate 是如何保證訊息的有序和不丟失呢?
Oracle GoldenGate邏輯架構
首先,先看一下Oracle GoldenGate 的邏輯架構:
圖中涉及到兩個階段:
- 初始化階段: extract 程序直接抽取源表資訊經網路傳輸到target 端的 replicat程序,replicat 程序獲取到初始化載入資料將其同步到目標資料來源。
- 增量資料抓取階段:extract 程序從源表redo log 或其他增量日誌中解析並獲取增量,然後落地成資料檔案;然後pump程序將資料經網路推送到目標端的collector程序。collector是由manager程序維護的,有新的pump資料過來,它會啟動一個新的collector,這個collector繫結到特定的埠上,通過TCP/IP連線,負責接收特定pump程序推送過來的資料並落地到指定的目錄下生成trail檔案。replicat 程序實時讀取 trail 檔案並將資料推送給kafka。
官方關於 trail檔案的說明如下:
To support the continuous extraction and replication of database changes, Oracle GoldenGate stores records of the captured changes temporarily on disk in a series of files called a trail. A trail can exist on the source system, an intermediary system, the target system, or any combination of those systems, depending on how you configure Oracle GoldenGate. On the local system it is known as an extract trail (or local trail). On a remote system it is known as a remote trail.
By using a trail for storage, Oracle GoldenGate supports data accuracy and fault tolerance (see Section 1.2.6, "Overview of Checkpoints"). The use of a trail also allows extraction and replication activities to occur independently of each other. With these processes separated, you have more choices for how data is processed and delivered. For example, instead of extracting and replicating changes continuously, you could extract changes continuously but store them in the trail for replication to the target later, whenever the target application needs them.
即trail 中儲存的是資料庫中的變化資料。Oracle GoldenGate用trail 做儲存,確保資料的準確性和容錯性。它也允許extract程序和replicat程序可以獨立存在,類似於訊息中介軟體的作用。
checkpoint保證資料不丟失和有序性
下面看一下官方給出的checkpoint 的案例(本來想用專案的真實checkpoint資訊,為避免不必要的麻煩,作罷):
注意這個是Oracle RAC模式下checkpoint資訊。
檢視extract程序checkpoint資訊命令:INFO EXTRACT JC108XT,SHOWCH
extract 程序checkpoint資訊如下:
EXTRACT JC108XT Last Started 2011-01-01 14:15 Status ABENDED Checkpoint Lag 00:00:00 (updated 00:00:01 ago) Log Read Checkpoint File /orarac/oradata/racq/redo01.log 2011-01-01 14:16:45 Thread 1, Seqno 47, RBA 68748800 Log Read Checkpoint File /orarac/oradata/racq/redo04.log 2011-01-01 14:16:19 Thread 2, Seqno 24, RBA 65657408 Current Checkpoint Detail: Read Checkpoint #1 Oracle RAC Redo Log Startup Checkpoint (starting position in data source): Thread #: 1 Sequence #: 47 RBA: 68548112 Timestamp: 2011-01-01 13:37:51.000000 SCN: 0.8439720 Redo File: /orarac/oradata/racq/redo01.log Recovery Checkpoint (position of oldest unprocessed transaction in data source): Thread #: 1 Sequence #: 47 RBA: 68748304 Timestamp: 2011-01-01 14:16:45.000000 SCN: 0.8440969 Redo File: /orarac/oradata/racq/redo01.log Current Checkpoint (position of last record read in the data source): Thread #: 1 Sequence #: 47 RBA: 68748800 Timestamp: 2011-01-01 14:16:45.000000 SCN: 0.8440969 Redo File: /orarac/oradata/racq/redo01.log Read Checkpoint #2 Oracle RAC Redo Log Startup Checkpoint(starting position in data source): Sequence #: 24 RBA: 60607504 Timestamp: 2011-01-01 13:37:50.000000 SCN: 0.8439719 Redo File: /orarac/oradata/racq/redo04.log Recovery Checkpoint (position of oldest unprocessed transaction in data source): Thread #: 2 Sequence #: 24 RBA: 65657408 Timestamp: 2011-01-01 14:16:19.000000 SCN: 0.8440613 Redo File: /orarac/oradata/racq/redo04.log Current Checkpoint (position of last record read in the data source): Thread #: 2 Sequence #: 24 RBA: 65657408 Timestamp: 2011-01-01 14:16:19.000000 SCN: 0.8440613 Redo File: /orarac/oradata/racq/redo04.log Write Checkpoint #1 GGS Log Trail Current Checkpoint (current write position): Sequence #: 2 RBA: 2142224 Timestamp: 2011-01-01 14:16:50.567638 Extract Trail: ./dirdat/eh Header: Version = 2 Record Source = A Type = 6 # Input Checkpoints = 2 # Output Checkpoints = 1 File Information: Block Size = 2048 Max Blocks = 100 Record Length = 2048 Current Offset = 0 Configuration: Data Source = 3 Transaction Integrity = 1 Task Type = 0 Status: Start Time = 2011-01-01 14:15:14 Last Update Time = 2011-01-01 14:16:50 Stop Status = A Last Result = 400
關於Extract的read幾種checkpoint解釋:
1. extract將read checkpoints放置在資料來源中。如果資料來源是Oracle,則檢查點是放在Oracle的日誌中。
2. Startup checkpoint:啟動檢查點是程序啟動時在資料來源中建立的第一個檢查點。
-
Thread #
: 建立檢查點的執行緒數,只有Oracle的RAC模式才會有 -
Sequence #
: 建立檢查點的事務日誌的序列號 -
RBA
: RBA是relative byte address的簡寫,表示建立檢查點的記錄的相對位元組地址 -
Timestamp
: 表示建立檢查點的記錄的時間戳 -
SCN
: SCN是system change number的簡寫,表示系統更改檢查點所在記錄的編號 -
Redo File
: 包含建立檢查點的記錄的事務日誌的路徑名
3. Recovery checkpoint:恢復檢查點表示extract未處理的最早的事務日誌的位置資訊。
4. Current checkpoint:表示extract在資料來源中讀的最近的(注意:此時還沒有寫成功)記錄的位置資訊。它應該和 Log Read Checkpoint
資訊一致。
關於extract的寫的checkpoint解釋:
extract程序將 current checkpoint 放在trail 檔案中。current checkpoint 是指extract 正在寫的trail的位置。
-
Sequence #
: 寫入檢查點的trail檔案的序列號 -
RBA
:trail檔案中建立檢查點的記錄的相對位元組地址 -
Timestamp
: 建立檢查點的記錄的時間戳 -
Extract trail
: trail檔案的相對路徑名稱 -
Trail Type
: 其中在類似於NFS服務上的被認為是local
檢視 replicat 程序 checkpoint 資訊命令:INFO REPLICAT JC108RP, SHOWCH
replicat 程序checkpoint 資訊如下:
REPLICAT JC108RP Last Started 2011-01-12 13:10 Status RUNNING Checkpoint Lag 00:00:00 (updated 111:46:54 ago) Log Read Checkpoint File ./dirdat/eh000000 First Record RBA 3702915 Current Checkpoint Detail: Read Checkpoint #1 GGS Log Trail Startup Checkpoint(starting position in data source): Sequence #: 0 RBA: 3702915 Timestamp: Not Available Extract Trail: ./dirdat/eh Current Checkpoint (position of last record read in the data source): Sequence #: 0 RBA: 3702915 Timestamp: Not Available Extract Trail: ./dirdat/eh Header: Version = 2 Record Source = A Type = 1 # Input Checkpoints = 1 # Output Checkpoints = 0 File Information: Block Size = 2048 Max Blocks = 100 Record Length = 2048 Current Offset = 0 Configuration: Data Source = 0 Transaction Integrity = -1 Task Type = 0 Status: Start Time = 2011-01-12 13:10:13 Last Update Time = 2011-01-12 21:23:31 Stop Status = A Last Result = 400
1. Startup Checkpoint
當程序啟動時在trail檔案中建立的第一個checkpoint
-
Sequence #:
寫入檢查點的trail檔案的序列號 -
RBA:
trail檔案中建立檢查點的記錄的相對位元組地址 -
Timestamp:
表示建立檢查點的記錄的時間戳 -
Extract Trail:
trail 檔案的相對地址
2. Current Checkpoint:current checkpoint 是指replicat 程序讀取trail檔案的最近的記錄的位置。
抽取的最終的日誌格式使得實現冪等性操作成為可能
Oracle GoldenGate的日誌格式是snapshot格式的,試想一下,假設我一條記錄的某個欄位 做累加操作,Oracle GoldenGate給我們的資料是增量資料,在at-least-once語義之上,進行多次傳輸,那麼資料最終會出問題。而snapshot資料,只需要根據主鍵不斷覆蓋即可。這種資料是支援冪等性操作的。
總結
1. 關於資料容錯性。- 其一,日誌格式是snapshot的,使得實現冪等性操作成為可能。
- 其二Oracle GoldenGate的checkpoint機制和消費者儲存消費的offset的機制是一樣的。都支援at-least-once的語義。因為很有可能出現已經寫資料成功,但更新checkpoint資料失敗,即kafka中的資料可能會出現重複的現象。所以在處理Oracle GoldenGate的訊息時,要確保最終落地的操作是冪等性操作,這樣資料至少不會丟。一般冪等性都需要唯一id作為標識,一般選用資料的主鍵做唯一id。如果沒有主鍵可以使用其他方案,切記生成的id要唯一且可重複生成,即同一條記錄根據id生成規則,永遠是相同的id且在一定時間範圍內不衝突。
- 其一資料在Oracle GoldenGate傳輸過程中,同一個extract程序落到一個檔案中,經網路傳輸會被響應的collector接收並把資料放到對應的rmtrail中,其中 local trail 和 remote trail 是一一對應的。相當於資料從一個分割槽傳輸到另外一個固定對應的分割槽,只要資料有序傳輸(它通過讀寫checkpoint來保證),那麼最終remote trail和local trail的順序肯定是一致的(可能會有重複)。
- 其二,replicat落到kafka的資料是單分割槽的,保證了放到kafka的資料的有序性。
參考:
Oracle GoldenGate文件庫:https://docs.oracle.com/goldengate/1212/gg-winux/GWUAD/wu_about_gg.htm#GWUAD117
Oracle官方對 Checkpoint 的術語的解釋:https://docs.oracle.com/goldengate/1212/gg-winux/GWUAD/wu_ogg_checkpts.htm#GWUAD965
&n