Oracle Goldengate是如何保證資料有序和確保資料不丟失的?

輪子媽發表於2019-07-11

工作中一直在用Oracle 的中介軟體Oracle GondenGate 是如何保證訊息的有序和不丟失呢?

Oracle GoldenGate邏輯架構

首先,先看一下Oracle GoldenGate 的邏輯架構:

 

圖中涉及到兩個階段:

  1. 初始化階段: extract 程式直接抽取源表資訊經網路傳輸到target 端的 replicat程式,replicat 程式獲取到初始化載入資料將其同步到目標資料來源。
  2. 增量資料抓取階段: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. 關於資料容錯性。
  1. 其一,日誌格式是snapshot的,使得實現冪等性操作成為可能。
  2. 其二Oracle GoldenGate的checkpoint機制和消費者儲存消費的offset的機制是一樣的。都支援at-least-once的語義。因為很有可能出現已經寫資料成功,但更新checkpoint資料失敗,即kafka中的資料可能會出現重複的現象。所以在處理Oracle GoldenGate的訊息時,要確保最終落地的操作是冪等性操作,這樣資料至少不會丟。一般冪等性都需要唯一id作為標識,一般選用資料的主鍵做唯一id。如果沒有主鍵可以使用其他方案,切記生成的id要唯一且可重複生成,即同一條記錄根據id生成規則,永遠是相同的id且在一定時間範圍內不衝突。
2. 關於有序性。
  1. 其一資料在Oracle GoldenGate傳輸過程中,同一個extract程式落到一個檔案中,經網路傳輸會被響應的collector接收並把資料放到對應的rmtrail中,其中 local trail 和 remote trail 是一一對應的。相當於資料從一個分割槽傳輸到另外一個固定對應的分割槽,只要資料有序傳輸(它通過讀寫checkpoint來保證),那麼最終remote trail和local trail的順序肯定是一致的(可能會有重複)。
  2. 其二,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

 

 

 

相關文章