PG Logical Replication 邏輯複製

PG10 到 PG11 的邏輯複製
html


我下面演示的PG環境是單機多實例的方式部署在同一臺物理機上的。部署方式能夠參考 上一篇博客。sql



一、當前老的PG10主庫(須要先設置wal_level = logical):數據庫

su - postgres 
cd /usr/local/pgsql-10.10/

./bin/psql --port 5433

postgres=# create database testdb1;
CREATE DATABASE
postgres=# create database testdb2;
CREATE DATABASE

postgres=# \c testdb1
You are now connected to database "testdb1" as user "postgres".
testdb1=# create table tb1(a int ,b int, c int );
testdb1=# create table tb2(a int ,b int, c int );
testdb1=# create table tb3(a int ,b int, c int );


建立一個複製用的帳號
bash

CREATE USER repuser REPLICATION LOGIN CONNECTION LIMIT 10 ENCRYPTED PASSWORD 'repuser';

另外,還須要給 repuser 用戶對源庫、源表、源schmea 賦權
\c testdb1
grant connect on database testdb1 to repuser;
grant usage on schema public to repuser;
grant select on all tables in schema public to repuser;  -- 這個受權有點大,可是問題不算太嚴重

而後,還要去pg_hba.conf 放開 repuser帳號的訪問地址,以下:
ide

host    all     repuser    192.168.2.1/24      md5

而後,reload下pg的配置。函數


二、初始化PG11新庫post

cd /usr/local/pgsql-11.5
mkdir data

./bin/initdb -D data

./bin/pg_ctl -D data/ -o "-p 5434" -l pg.log start
./bin/psql --port 5434



三、導出PG10的 schema definitionsspa

cd /usr/local/pgsql-10.10

./bin/pg_dumpall -s  --port 5433 --no-subscriptions > ./schemadump.sql


四、 將PG10的 導出數據導入到PG11中postgresql

su - postgres 
cd /usr/local/pgsql-11.5

./bin/psql --port 5434 -d postgres -f /usr/local/pgsql-10.10/schemadump.sql


五、在源實例PG10中的每一個數據庫中,建立一個捕獲全部表的發佈orm

注意:邏輯複製在每一個數據庫中分別工做,所以須要在每一個數據庫中重複。另外一方面,您沒必要一次升級全部數據庫,所以能夠一次完成一個數據庫,甚至不升級某些數據庫。

cd /usr/local/pgsql-10.10

./bin/psql --port 5433

postgres=# \c testdb1
testdb1=# CREATE PUBLICATION p_upgrade FOR ALL TABLES;
testdb1=#  \dRp+
                Publication p_upgrade
  Owner   | All tables | Inserts | Updates | Deletes 
----------+------------+---------+---------+---------
 postgres | t          | t       | t       | t
(1 row)

testdb1=# \c testdb2
testdb2=# CREATE PUBLICATION p_upgrade2 FOR ALL TABLES;
testdb2=#  \dRp+
               Publication p_upgrade2
  Owner   | All tables | Inserts | Updates | Deletes 
----------+------------+---------+---------+---------
 postgres | t          | t       | t       | t
(1 row)


六、 在目標實例 PG11 中的每一個數據庫中,建立訂閱剛剛建立的發佈的訂閱。確保與源數據庫和目標數據庫匹配正確。

su - postgres 
cd /usr/local/pgsql-11.5 
./bin/psql --port 5434


testdb2=# \c testdb1
testdb2=# CREATE SUBSCRIPTION s_sub CONNECTION 'host=192.168.2.4 port=5433 dbname=testdb1 user=repuser password=repuser' PUBLICATION p_upgrade;

testdb1=# \dRs+
                                                          List of subscriptions
 Name  |  Owner   | Enabled | Publication | Synchronous commit |                                Conninfo                                 
-------+----------+---------+-------------+--------------------+-------------------------------------------------------------------------
 s_sub | postgres | t       | {p_upgrade} | off                | host=192.168.2.4 port=5433 dbname=testdb1 user=repuser password=repuser
(1 row)

testdb2=# \c testdb2
testdb2=# CREATE SUBSCRIPTION s_sub2 CONNECTION 'host=192.168.2.4 port=5433 dbname=testdb2 user=repuser password=repuser' PUBLICATION p_upgrade2;

testdb2=# \dRs+
                                                           List of subscriptions
  Name  |  Owner   | Enabled | Publication  | Synchronous commit |                                Conninfo                                 
--------+----------+---------+--------------+--------------------+-------------------------------------------------------------------------
 s_sub2 | postgres | t       | {p_upgrade2} | off                | host=192.168.2.4 port=5433 dbname=testdb2 user=repuser password=repuser
(1 row)


七、在PG10上,造些數據:

postgres=# \c testdb1
testdb1=# insert into tb1(a,b,c) values (1,1,1),(2,2,2),(3,3,3);
testdb1=# insert into  tb2(a,b,c) values (1,1,1);

而後,到 PG11上的testdb1庫裏面,能夠看到 數據已同步了。


八、後續若是在PG10上有加表操做,相似以下:

PG10上,咱們加一個表
testdb1=# \c testdb1
testdb1=# create table tb_new( a int ,b int );
testdb1=# insert into tb_new values(1,1) ,(2,2) ,(3,3),(4,4);

testdb1=# GRANT SELECT ON tb_new to repuser;    須要受權下

由於咱們第五步的時候,給了all table作了複製的配置, 所以新加表後這裏不須要執行添加到發佈者的命令。

testdb1=# \dRp+ p_upgrade  -- 查看發佈者的詳細信息
                Publication p_upgrade
Owner   | All tables | Inserts | Updates | Deletes 
----------+------------+---------+---------+---------
 postgres | t          | t       | t       | t
(1 row)


PG10上加完表後,咱們能夠看到PG11上這個 tb_new 表是不存在的。 須要咱們到PG11上手工建立下:

在PG11上執行以下命令:

\c testdb1
create table tb_new( a int ,b int );
select count(*) from tb_new;   -- 這時候數據仍是爲0的

ALTER SUBSCRIPTION s_sub REFRESH PUBLICATION;  -- 刷新一下訂閱者

select count(*) from tb_new;   -- 這時候數據變成了4條了


九、 清除複製設置(在PG11新庫上執行)

\c testdb1
DROP SUBSCRIPTION s_sub;

\c testdb2
DROP SUBSCRIPTION s_sub2;

而後, 也能夠刪除源實例PG10上的發佈,但這不是必需的。


十、最後,若是老的PG10上流量都切到PG11後,能夠將PG10這個實例下線。


原生logical複製的限制【很是關鍵】: 

一、只支持普通表生效,不支持序列、視圖、物化視圖、外部表、分區表和大對象

關於邏輯複製不支持的事項的變通方法的一些附加註釋。若是您正在使用大型對象,則可使用pg_dump移動它們,固然只要它們在升級過程當中不會更改。這是一個重要的限制,所以若是您是大型對象的重度用戶,那麼此方法可能不適合您。若是您的應用程序在升級過程當中發出TRUNCATE,則不會複製這些操做。也許您能夠調整應用程序以防止它在升級時執行此操做,或者您能夠替換DELETE。PostgreSQL 11將支持複製TRUNCATE,但這隻有在源和目標實例都是PostgreSQL 11或更新版本時纔有效。

二、只支持普通表的DML(INSERT、UPDATE、DELETE)操做,不支持truncate、DDL操做

三、須要同步的表必須設置 REPLICA IDENTITY 不能爲noting(默認值是default),同時表中必須包含主鍵,不然delete和update報錯

四、一個publisher能夠包含一張或多張表,一張表能夠有一個或多個publishers

五、一個發佈者能夠有多個訂閱者訂閱,一個訂閱者也能夠同時訂閱多個發佈者,在同一個數據庫下訂閱者不能對同一個發佈者的表重複訂閱(避免數據衝突)

六、邏輯複製不一樣於流複製,不是嚴格的主從關係,訂閱者端的普通表依然能夠進行增刪改操做

七、同步表的表結構須要在發佈者和訂閱者兩邊保持一致(列的順序容許不同,可是列對應的數據類型必須一致)

八、若是訂閱者端的數據被誤刪,想要從發佈者從新copy同步表的數據,只能以重建同步表所在的訂閱者的方式來實現



其它注意事項:

publication - 發佈者

邏輯複製的前提是將數據庫 wal_level 參數設置成 logical;

源庫上邏輯複製的用戶必須具備 replicatoin 或 superuser 角色;

邏輯複製目前僅支持數據庫表邏輯複製,其它對象例如函數、視圖不支持;

邏輯複製支持DML(UPDATE、INSERT、DELETE)操做,TRUNCATE 和 DDL 操做不支持;

須要發佈邏輯複製的表,須配置表的 REPLICA IDENTITY 特性;

一個數據庫中能夠有多個publication,經過 pg_publication 查看;

容許一次發佈全部表,語法: CREATE PUBLICATION alltables FOR ALL TABLES;

subscription - 訂閱者

訂閱節點須要指定發佈者的鏈接信息;

一個數據庫中能夠有多個訂閱者;

可使用enable/disable啓用/暫停該訂閱;

發佈節點和訂閱節點表的模式名、表名必須一致,訂閱節點容許表有額外字段;

發佈節點增長表名,訂閱節點須要執行: ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION


參考資料:

https://www.postgresql.org/docs/10/sql-createpublication.html

https://www.postgresql.org/docs/10/sql-createsubscription.html

https://www.postgresql.org/docs/10/sql-altersubscription.html


https://yq.aliyun.com/articles/585446?spm=a2c4e.11153940.0.0.48e86e272CVXQp

https://postgres.fun/20170528142004.html

相關文章
相關標籤/搜索