PostgreSQL 逻辑复制

本文详细介绍了PostgreSQL逻辑复制的配置流程,包括主库和备库的参数设置、逻辑复制用户的创建、测试表的建立、权限分配、发布与订阅的创建、数据同步检查等关键步骤。同时,文中还探讨了逻辑复制的限制,如不支持DDL同步和仅限于表的复制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前逻辑复制中两点需要注意:

  1. 不支持DDL的同步,需要主库与备库手动执行
  2. 仅支持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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值