1. 程式人生 > >PostgreSQL V10邏輯複製最佳實踐

PostgreSQL V10邏輯複製最佳實踐

目錄

環境

文件用途

詳細資訊

環境

系統平臺:Linux x86-64 Red Hat Enterprise Linux 7

版本:10.1

文件用途

PostgreSQL V10邏輯複製原理以及作為邏輯複製使用指導

詳細資訊

一、什麼是邏輯複製(pglogical)
邏輯複製是PostgreSQL V10重量級新特性,支援內建的邏輯複製。在10版本之前,雖然沒有內建的邏輯複製,也可以通過其它方式實現,例如觸發器、自定義指令碼實現表級別同步,另外也可以通過外部工具 Londiste3 實現。從2014年釋出的9.4版本開始,PostgreSQL就支援邏輯複製了,只是一直沒有將其引入核心。你可以針對同一個資料庫例項,同時使用邏輯複製和物理複製,因為他們都是基於REDO的。

二、邏輯複製應用場景
可基於表級別複製,是一種粒度可細的複製,主要用在以下場景:
1)滿足業務上需求,實現某些指定表資料同步
2)報表系統,採集報表資料
3)PostgreSQL 跨版本資料同步
4)PostgreSQL 大版本升級
5)可從多個上游伺服器,做資料的聚集和合並

三、邏輯複製原理
使用釋出者/訂閱者模型,使用訂閱複製槽技術,可並行的傳輸WAL日誌,通過在訂閱端回放WAL日誌中的邏輯條目,保持複製表的資料同步,
注意這裡不是“SQL”複製,而是複製SQL操作的結果。

圖示:

1.png

 

四、邏輯複製的主要組成
1)publication - 釋出
可以在任何物理複製主機上定義釋出; 定義釋出的節點稱為釋出者;
釋出是從一個表或一組表中生成的一組更改,也可能被描述為更改集或複製集;
每個釋出只存在於一個數據庫中。
釋出與模式不同,不影響表格的訪問方式;如果需要,每張表可以新增到多個釋出;
釋出目前可能只包含表;物件必須顯式新增, 除非為ALL TABLES建立了一個釋出。
釋出可以選擇將它們所產生的改變限制在INSERT, UPDATE和DELETE的任意組合上, 類似於觸發器
預設情況下,複製所有操作型別。

publication - 釋出語法

postgres=# \h create publication 
Command:     CREATE PUBLICATION
Description: define a new publication
Syntax:
CREATE PUBLICATION name
    [ FOR TABLE [ ONLY ] table_name [ * ] [, ...]
      | FOR ALL TABLES ]
    [ WITH ( publication_parameter [= value] [, ... ] ) ]

postgres=# \h alter publication 
Command:     ALTER PUBLICATION
Description: change the definition of a publication
Syntax:
ALTER PUBLICATION name ADD TABLE [ ONLY ] table_name [ * ] [, ...]
ALTER PUBLICATION name SET TABLE [ ONLY ] table_name [ * ] [, ...]
ALTER PUBLICATION name DROP TABLE [ ONLY ] table_name [ * ] [, ...]
ALTER PUBLICATION name SET ( publication_parameter [= value] [, ... ] )
ALTER PUBLICATION name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
ALTER PUBLICATION name RENAME TO new_name

publication - 釋出語法示例

CREATE PUBLICATION mypublication FOR TABLE users, departments;

2)subscription - 訂閱

subscription - 訂閱語法

postgres=# \h create subscription
Command:     CREATE SUBSCRIPTION
Description: define a new subscription
Syntax:
CREATE SUBSCRIPTION subscription_name
    CONNECTION 'conninfo'
    PUBLICATION publication_name [, ...]
    [ WITH ( subscription_parameter [= value] [, ... ] ) ]

postgres=# \h alter subscription 
Command:     ALTER SUBSCRIPTION
Description: change the definition of a subscription
Syntax:
ALTER SUBSCRIPTION name CONNECTION 'conninfo'
ALTER SUBSCRIPTION name SET PUBLICATION publication_name [, ...] [ WITH ( set_publication_option [= value] [, ... ] ) ]
ALTER SUBSCRIPTION name REFRESH PUBLICATION [ WITH ( refresh_option [= value] [, ... ] ) ]
ALTER SUBSCRIPTION name ENABLE
ALTER SUBSCRIPTION name DISABLE
ALTER SUBSCRIPTION name SET ( subscription_parameter [= value] [, ... ] )
ALTER SUBSCRIPTION name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
ALTER SUBSCRIPTION name RENAME TO new_name

postgres=# \h drop subscription 
Command:     DROP SUBSCRIPTION
Description: remove a subscription
Syntax:
DROP SUBSCRIPTION [ IF EXISTS ] name [ CASCADE | RESTRICT ]

 

subscription - 訂閱語法示例

建立一個到遠端伺服器的訂閱,複製釋出mypublication和 insert_only中的表,並在提交時立即開始複製:

CREATE SUBSCRIPTION mysub
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
PUBLICATION mypublication, insert_only;

 

建立一個到遠端伺服器的訂閱,複製insert_only釋出中的表, 並且不開始複製直到稍後啟用複製。

CREATE SUBSCRIPTION mysub
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
PUBLICATION insert_only WITH (enabled = false);

將訂閱的釋出更改為insert_only:

ALTER SUBSCRIPTION mysub SET PUBLICATION insert_only;

禁用(啟用)訂閱:

ALTER SUBSCRIPTION mysub DISABLE;
ALTER SUBSCRIPTION mysub ENABLE;


subscription - 訂閱相關配置
這些設定控制邏輯複製訂閱的行為。釋出者的值無關緊要。
請注意,wal_receiver_timeout和 wal_retrieve_retry_interval配置引數還影響邏輯複製工作。

max_logical_replication_workers (int)
指定邏輯複製工作的最大數量。這包括應用工作和表同步工作。
邏輯複製工作程序是從max_worker_processes 定義的程序池中取出的。
預設值是4。

max_sync_workers_per_subscription (integer)
每個訂閱的最大同步工作者數量。 此引數控制訂閱初始化期間或新增新表時初始資料副本的並行數量。
目前,每個表只能有一個同步工作程序。
同步工作程序是從max_logical_replication_workers 定義的程序池中取出的。
預設值是2。

 

3)Replication Slots - 複製槽(釋出端)

每個(活動)訂閱都從遠端(釋出)端的複製槽接收更改。
通常,使用CREATE SUBSCRIPTION 建立訂閱時會自動建立遠端複製槽,使用DROP SUBSCRIPTION 刪除訂閱時會自動刪除該槽。
複製槽提供了一種自動化的方法來確保主控機在所有的後備機收到 WAL段之前不會移除它們,主庫隨時知道從庫應用 wal 的情況 , 哪怕從庫掉線,主庫依然保留 wal日誌
這種機制的缺點是,如果從庫掉線很久, 那麼主庫的wal日誌 會一直保留以至於撐暴硬碟, 這時監控需要做到位。

Replication Slots - 複製槽(釋出端)

#postgresql.conf關聯配置

wal_level = logical
max_replication_slots = 10  #max_replication_slots 值最少需設定成 1,設定後重啟資料庫生效。


五、邏輯複製的限制

1)版本限制

pglogical是邏輯複製的技術元件,功能使用存在資料庫版本限制:

資料來源釋出和訂閱節點需要執行 PostgreSQL 9.4 +

複製源過濾和衝突檢測需要 PostgreSQL 9.5 +

pglogical 支援跨 PostgreSQL 主要版本之間的複製
但在訂閱伺服器上不同版本之間進行復制時,可能會出現問題。

支援從舊版本複製到新版本因為 PostgreSQL 的向後相容性保證的,但只有有限的向前相容性比較安全

2)其它限制

不支援DDL複製(ALTER TABLE/CREATE TABLE)

不支援TEMPRORARY表和UNLOGGED表複製

不支援Sequences複製( serial/bigserial/identity)

不支援TRUNCATE操作複製
不支援大物件複製(Bytea)

不支援檢視、物化檢視、外部表複製
被複制的表上最好有主鍵約束;如果沒有,必須執行:
ALTER TABLE reptest REPLICA IDENTITY FULL;(備註)

訂閱端的複製表是可修改的,複製表一旦修改,釋出者和訂閱者會資料不一致,進而打破複製。

以下兩種情況邏輯複製不支援:

publisher->public.foo replicates to subscriber→private.foo

publisher->public.foo replicates to subscriber->partitioned->public.foo

備註:REPLICA IDENTITY
這種形式更改被寫入到預寫式日誌來標識被更新或刪除行的資訊。除非使用邏輯複製, 這個選項將不會產生效果。

DEFAULT(非系統表的預設值)記錄主鍵列 (如果有)的舊值。

USING INDEX記錄被所提到的索引所覆蓋的列的 舊值,該索引必須是唯一索引、不是部分索引、不是可延遲索引並且只包括被標記成 NOT NULL的列。

FULL記錄行中所有列的舊值。

NOTHING不記錄有關舊行的任何資訊(這是系統表的預設值)。在所 有情況下,除非至少有一個要被記錄的列在新舊行版本之間發生變化,將不記錄舊值。
分割槽表的邏輯複製,需要面向子表建立釋出

CREATE TABLE parttest (id bigint, test text);

– PRIMARY KEYS don’t work on partitioned tables


CREATE TABLE parttest0 PARTITION OF
parttest FOR VALUES FROM (1) TO (100);

CREATE TABLE parttest1 PARTITION OF
parttest FOR VALUES FROM (101) TO (200);


CREATE PUBLICATION parttest FOR TABLE parttest0,parttest1

詳細的邏輯複製例項請登入【瀚高技術支援平臺】檢視

https://support.highgo.com/#/index/docContent/17be95bf02222c7b