PG主從系列-邏輯複製
前言
Postgresql支援“邏輯”和“物理”兩種複製方式,邏輯複製是一種基於資料物件的複製標識(通常是主鍵)複製資料物件及其修改的方法,而後者使用準確的塊地址以及逐位元組的複製方式(WAL日誌),邏輯複製允許資料複製和安全性上更細粒度的控制(可以對特定表進行復制)。邏輯複製採用釋出者->訂閱者模型,具體流程結構圖如下:
邏輯複製的能力:
1、一個數據庫或者一個數據庫子集發生更改時,把增量的改變傳送給訂閱者。
2、在更改到達訂閱者時引發觸發器。
3、把多個數據庫聯合到單一資料庫。
4、在Postgresql不同主版本之間進行復制。
5、在不同的平臺(例如Linux到Windows)的Postgresql例項之間複製。
6、將複製資料的訪問給予不同的使用者組。
7、在多個數據庫之間共享資料庫的子集。
8、Pubilcation可以選擇把它們產生的更改限制為INSERT、UPDATE、DELETE及UPDATE的任意組合。
9、表的列通過名稱匹配。訂閱表中的列順序不需要與釋出表順序一致;列的資料型別也不需要一樣,只要可以將資料的文字表示轉換為目標型別即可,如:int列複製到bigint列,此外目標表還可以具備釋出表中不存在的額外列,額外列將以定義的預設值填充。
邏輯複製限制:
1、一個訂閱被刪除並且重建時,同步資訊會丟失,資料必須重新同步。
2、表在釋出者和訂閱者之間使用完全限定的表名進行匹配,不支援複製到訂閱者上命名不同的表,同時列名也必須匹配不能對映。
3、採用複製槽的方式,當存在衝突時,複製會暫停,需要人工處理,可能導致釋出節點WAL日誌積壓嚴重,嚴重情況下導致釋出節點不可用。
4、資料庫模式和DDL命令不會被複制
5、序列資料不被複制
6、大物件不會被複制
7、複製只能是普通表,不能是檢視、物化檢視、分割槽根表或者外部表;如果是分割槽,可以一一對應地複製分割槽層次,但當前不能複製成一種不同的分割槽設定。
8、支援TRUNCATE但是當使用cascade清空,而表存在外來鍵類連結時,如果受影響的表屬於同一訂閱,這會正確工作,但是不屬於同一訂閱的表時,會報錯。
9、要求PG9.4及以上版本
10、複製表需要有主鍵、或者唯一性約束,否則只能設定replica identity補全日誌
11、複製使用者許可權需要replication或superuser許可權
快速部署
1、修改釋出者postgres.conf檔案
wal_level = logical
max_wal_senders = 100
2、釋出者節點建立使用者
#以public模式為例
create user repl replication with password 'repl'; alter user repl set default_transaction_read_only=on; grant USAGE on SCHEMA public to repl; grant SELECT on ALL tables in schema public to repl; alter default privileges in schema public grant select on tables to repl;
3、修改釋出者節點pg_hba.conf檔案
host all repl 訂閱者IP/32 md5
4、重啟PG
su - postgres -c "pg_ctl restart"
5、釋出者節點建立釋出
create publication pub1 for table tab1; --alter table tab1 replica identity full; --無主鍵或者唯一性約束時開啟補全日誌,此時會導致複製效率很低
6、訂閱者節點
#max_replication_slots需要設定
#max_logical_replication_workers需要設定
#max_worker_processes需要設定
#建立表結構
create subscription pub1 connection 'host=釋出者IP post=5432 dbname=postgres user=repl password=repl' publication pub1; alter subscription pub1 refresh publication;
運維監控
alter publication pub1 add table test.tab1;#從節點需要重新整理才能看到新新增表 alter subscription pub1 refresh publication; #重新整理訂閱 drop pubilcation pub1; #刪除釋出 select * from pg_pubilcation;#釋出 select * from pg_pubilcation_tables;#釋出哪些表 select * from pg_stat_subscription;#複製進度 select * from pg_subscription; #訂閱 select *,srrelid::regclass from pg_subscription_rel; #訂閱哪些表 drop subscription pub1;#刪除訂閱
衝突處理
update或delete操作時可能會導致衝突,這時可以檢視日誌剛剛訂閱者上的資料,或者使用pg_replication_origin_advance()函式跳過該事務。