文章目錄
目前邏輯複製中兩點需要注意:
- 不支持DDL的同步,需要主庫與備庫手動執行
- 僅支持table的複製。其他對象不支持
配置發佈節點 - 主庫端
修改主庫配置參數
vi postgresql.conf配置文件
wal_level = replica
max_wal_senders = 10
max_replication_slots = 8
創建邏輯複製用戶
[postgres@pg01 data]$ psql
create user luser
replication
login
connection limit 8
encrypted password '123456';
創建測試表
創建要複製的表,並插入一條測試數據
dong=# create table tlt (id int , name varchar(20));
CREATE TABLE
dong=# insert into tlt values (1 , 'logical');
INSERT 0 1
注意tlt表上,沒有主鍵
賦予select權限
將需要複製的表,授予select權限給複製用戶
dong=# grant select on tlt to luser;
GRANT
創建發佈
發佈該庫中的指定的表:
dong=# create publication pub1 for table tlt;
或者也可以發佈該庫中的所有表,包括以後在這個庫中新建的表:
dong=# create publication pub1 for all table ;
查看發佈的表list
dong=# select * from pg_publication_tables;
pubname | schemaname | tablename
---------+------------+-----------
pub1 | public | tlt
(1 row)
查詢發佈狀態
dong=# select * from pg_publication;
oid | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate
-------+---------+----------+--------------+-----------+-----------+-----------+-------------
16464 | pub1 | 10 | f | t | t | t | t
(1 row)
配置訂閱節點 - 邏輯備庫端
修改備庫配置參數
vi postgresql.conf
[postgres@pg02 data]$ vi postgresql.conf
max_replication_slots = 8
max_logical_replication_workers = 4
重啓後生效
[postgres@pg02 data]$ pg_ctl restart
創建相應的庫
[postgres@pg02 data]$ createdb dong
創建需要複製的表結構
注意我這裏創建表的時候,並沒有創建到dong這個數據庫中(其實是不小心創建錯了,那就將錯就錯吧,看後邊會有什麼情況)
postgres=# create table tlt (id int , name varchar(20));
CREATE TABLE
創建訂閱
創建訂閱,必須使用pg的用戶纔可以
[postgres@pg02 data]$ psql
postgres=# create subscription sub1 connection 'host=192.168.56.103 port=5432 dbname=dong user=luser password=123456'
postgres-# publication pub1;
NOTICE: created replication slot "sub1" on publisher
CREATE SUBSCRIPTION
在發佈節點(主)查看邏輯複製槽信息
postgres=# select slot_name , plugin , slot_type , database , active , restart_lsn
postgres-# from pg_replication_slots;
slot_name | plugin | slot_type | database | active | restart_lsn
---------------+---------------+-----------+----------+--------+-------------
logical_slot1 | test_decoding | logical | postgres | f | 0/7F014FD0
sub1 | pgoutput | logical | dong | t | 0/82000688
(2 rows)
在訂閱節點(備) 查看邏輯複製信息
postgres=# select * from pg_subscription;
oid | subdbid | subname | subowner | subenabled | subconninfo | subslotname | subsynccommit | subpublic
ations
-------+---------+---------+----------+------------+----------------------------------------------------------------------+-------------+---------------+----------
-------
24597 | 13830 | sub1 | 10 | t | host=192.168.56.103 port=5432 dbname=dong user=luser password=123456 | sub1 | off | {pub1}
(1 row)
檢查數據
發佈端
dong=# insert into tlt values (2,'data');
INSERT 0 1
dong=#
dong=#
dong=# select * from tlt;
id | name
----+---------
1 | logical
2 | data
(2 rows)
訂閱端
postgres=# select * from tlt;
id | name
----+---------
1 | logical
2 | data
(2 rows)
支持update、delete
我們之前買了一個伏筆,主庫的表沒有主鍵,那麼是無法同步update、delete操作的,並且主庫端也會報錯,如下:
dong=# update tlt set name='new date' where id=2;
ERROR: cannot update table "tlt" because it does not have a replica identity and publishes updates
HINT: To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.
DDL操作是不能同步的,所以需要在兩個節點上分別創建主鍵。
dong=# alter table tlt add primary key(id);
ALTER TABLE
dong=#
再次嘗試更新數據,成功
dong=# update tlt set name='new date' where id=2;
UPDATE 1
在接收端,查看是否有 new data
postgres=# select * from tlt;
id | name
----+----------
1 | logical
2 | new date
(2 rows)
添加複製表
1 - 發佈:新建表
新建表
dong=# create table order_detail (id serial ,
dong(# order_info varchar(20) ,
dong(# order_date timestamp(0) with time zone) ;
CREATE TABLE
插入測試數據
dong=# insert into order_detail (id , order_date)
dong-# values (1, '2015-10-01');
INSERT 0 1
dong=# insert into order_detail (id , order_date)
dong-# values (1, '2021-10-01');
INSERT 0 1
查看測試表及數據
dong=# select * from order_detail;
id | order_info | order_date
----+------------+------------------------
1 | | 2015-10-01 00:00:00+08
1 | | 2021-10-01 00:00:00+08
(2 rows)
2 - 發佈:賦權給複製賬戶
dong=# grant select on order_detail to luser;
GRANT
3 - 發佈:添加至已有的發佈
dong=# alter publication pub1 add table order_detail;
ALTER PUBLICATION
4 - 發佈:檢查
dong=# select * from pg_publication_tables;
pubname | schemaname | tablename
---------+------------+--------------
pub1 | public | tlt
pub1 | public | order_detail
(2 rows)
5 - 訂閱:新建表
```sql
dong=# create table order_detail (id serial ,
dong(# order_info varchar(20) ,
dong(# order_date timestamp(0) with time zone) ;
CREATE TABLE
## 6 - 訂閱:刷新訂閱
```sql
postgres=# alter subscription sub1 refresh publication;
ALTER SUBSCRIPTION
7 - 訂閱:檢查
postgres=# select * from order_detail;
id | order_info | order_date
----+------------+------------------------
1 | | 2015-10-01 00:00:00+08
1 | | 2021-10-01 00:00:00+08
(2 rows)
刪除複製表
發佈:在發佈中drop
alter publication pub1 drop table order_detail;
邏輯複製啓動、停止
訂閱節點啓動同步數據
alter subscription sub1 disable;
訂閱節點停止同步數據
alter subscription sub1 enable;