天天看點

PgSQL · PostgreSQL 邏輯流複制技術的秘密

自 postgresql 9.4 ,終于支援了邏輯流複制。本篇文章為大家帶來這部分的技術細節的分析。

postgresql 9.4 對邏輯流複制的支援具有相當的意義。我們可以用該技術完成很多企業級的需求。

postgresql 的大版本更新,由于可以使用流複制做增量資料同步,是以停機服務時間會非常短。

postgresql 自定義邏輯拆庫。由于是邏輯資料,是以很容易自定義分發規則。例如按表拆,邏輯分表,白名單,黑名單等等。

postgresql 增量同步到其他異構資料庫,例如 pg 同步到 mysql;pg 同步到 oracle。

邏輯主備同步,邏輯多節點同時可寫叢集。

logical decoding

postgresql 的邏輯日志來源于解析實體 wal 日志。

解析 wal 成為邏輯資料的過程叫 logical decoding。

replication slots

儲存邏輯或實體流複制的基礎資訊。類似 mysql 的位點資訊。

一個 邏輯 slot 建立後,它的相關資訊可以通過 pg_replication_slots 系統視圖擷取。

如果它在 active 狀态,則可以通過系統視圖 pg_stat_replication 看到一些 slot 的實時的狀态資訊。

output plugins

postgresql 的邏輯流複制協定開放一組可程式設計接口,用于自定義輸資料到用戶端的邏輯資料的格式。

這部分實作使用插件的方式被核心內建和使用,稱作 output plugins。

exported snapshots

當一個邏輯流複制 slot 被建立時,系統會産生一個快照。用戶端可以通過它訂閱到資料庫任意時間點的資料變化。

logical decoding 是把 wal 日志解析成邏輯日志的過程。這個過程輸出的是資料格式可以描述為:

事物開始 任何的變化總是在一個事物中,是以訂閱的資料變化的開始是是一個事物被啟動的消息,他包括了事物 id,lsn,開始時間等資訊。

資料的變化 包括目前事物中修改的資料。即對某些表的 insert update delete 操作來帶的資料變化。

一個事物内可以包含任意個表和任意行資料的變化。

輸出的資料的格式和對應表的定義和索引相關,詳細資訊看後面文章的描述。

事物的送出 包括事物送出的 lsn,時間等相關資訊。

上一節的内容提到的資料需要通過 output plugins 确定最終的資料格式,再發送給用戶端。

這部分的接口表現為下列回調函數:

logicaldecodestartupcb startup_cb;

logicaldecodebegincb begin_cb;

logicaldecodechangecb change_cb;

logicaldecodecommitcb commit_cb;

logicaldecodeshutdowncb shutdown_cb;

函數 1,5 是配置設定和清理插件所需的記憶體結構。此外的 2,3,4 三個回調函數完全對應上一節中的三個部分。

開發者可以根據需求實作這一組函數。

毫無疑問,定制邏輯資料格式成為了 output plugins 的關鍵。根據不同的需求産生的資料也會有顯著的不同。

發送的資料可以是普通字元串,也可以是二進制字元串。為了用戶端解析資料更容易,通常使用二進制字元串表達資料。

如果做同構資料庫資料同步,傳輸的資料可以比較簡單。原因是可以使用内部資料直接表達變化的資料。

如果要做異構資料庫同步,情況會複雜一些。目前的方案是把增量資料組合成通用 sql,再寫入到異構資料庫中。這樣就需要給出轉換資料成 sql 語句的所有資訊。在變化的資料本身外,還需要包括表名,列名,列資料類型,索引資訊等等。

針對不同資料庫的特殊字元,還需要處理轉譯字元的問題。

針對表中的長字段,需要優化。如果不修改這些大字段,可以選擇不傳輸它們。

邏輯流複制利用索引的方式優化傳輸資料的效率,它們可以按表為機關定制。大緻分為三種情況:

如果修改的表有 primary key, 則表的變化的邏輯資料隻會包括該表變化的列和pk列資料,如果 pk 列被修改,則還會輸出老的 pk 列資料。

如果修改的表沒有 primary key,則可以使用 alter table 指定一個 replica index,同時需要這個索引列為非空,其産生的效果和 1 相同。

如果修改的表不滿足上面的兩個條件,而又要做同步,可以使用 alter table 設定這個表的 replica identity 為 full。于是系統在表修改時會記錄修改行的所有列,不會做任何的優化。

很明顯,給對應的表設定 pk 或指定索引,在資料同步時效率更高。我們可以安需定制同步政策。在實作功能的過程中需要考慮這部分變化。

邏輯流複制特性對 postgresql 意義重大,目前已經有很多相關的資料同步産品應運而生,比如 2nd quadrant 公司的 bdr/udr。也有公司調整了已有産品原有的技術方案,使用邏輯流複制為增量資料的同步方案,比如 edb 公司的 xdb。阿裡雲 rds 團隊也利用該特性推出了 postgresql 的資料遷移服務,并且開源了相關代碼。

最後,我們期待更多相關産品的出現。

謝謝!