1. 程式人生 > 實用技巧 >PG主從系列-邏輯複製

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()函式跳過該事務。