PostgreSQL 13: 邏輯復制支持分區表


PostgreSQL 13: 邏輯復制支持分區表

PostgreSQL 10 版本開始支持邏輯復制,在12版本之前邏輯復制僅支持普通表,不支持分區表,如果需要對分區表進行邏輯復制,需單獨對所有分區進行邏輯復制。

PostgreSQL 13 版本的邏輯復制新增了對分區表的支持,如下:

  • 可以顯式地發布分區表,自動發布所有分區。
  • 從分區表中添加/刪除分區將自動從發布中添加/刪除。

發行說明的解釋如下:

發行說明

Allow partitioned tables to be logically replicated via publications (Amit Langote)
Previously, partitions had to be replicated individually. Now partitioned tables can be published explicitly causing all partitions to be automatically published. Addition/removal of partitions from partitioned tables are automatically added/removed from publications. The CREATE PUBLICATION option publish_via_partition_root controls whether changes to partitions are published as their own or their ancestors.

Allow logical replication into partitioned tables on subscribers (Amit Langote)
Previously, subscribers could only receive rows into non-partitioned tables.

關於邏輯復制之前博客有介紹,詳見PostgreSQL10:邏輯復制(Logical Replication)之一,本文僅做簡單演示。

環境規划

環境規划,如下:

節點 數據庫版本 IP 端口
源庫 PostgreSQL 13beta1 192.168.2.11 1922
目標庫 PostgreSQL 13beta1 192.168.2.13 1924

環境准備

在源庫、目標庫安裝 PostgreSQL 13beta1軟件並初始化數據庫,本文略。

部署mydb數據庫

在源庫和目標庫上均部署 mydb 數據庫,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
--建用戶
CREATE ROLE pguser LOGIN ENCRYPTED PASSWORD 'pguser' nosuperuser noinherit nocreatedb nocreaterole ;

--創建表空間(如果有 Standby ,也需要創建目錄)
mkdir -p /pgdata/pg13/pg_tbs/tbs_mydb

--創建數據庫
CREATE DATABASE mydb
WITH OWNER = postgres
TEMPLATE = template0
ENCODING = 'UTF8'
TABLESPACE = tbs_mydb;

--賦權
grant all on database mydb to pguser with grant option;
grant all on tablespace tbs_mydb to pguser;

\c mydb pguser
create schema pguser;

 

創建分區表

在源庫和目標庫上創建分區表,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
--創建父表
CREATE TABLE tbl_log (
id serial,
user_id int4,
create_time timestamp(0) without time zone
) PARTITION BY RANGE(create_time);

--創建子表
CREATE TABLE tbl_log_his PARTITION OF tbl_log FOR VALUES FROM (minvalue) TO ('2020-01-01');
CREATE TABLE tbl_log_202001 PARTITION OF tbl_log FOR VALUES FROM ('2020-01-01') TO ('2020-02-01');
CREATE TABLE tbl_log_202002 PARTITION OF tbl_log FOR VALUES FROM ('2020-02-01') TO ('2020-03-01');
CREATE TABLE tbl_log_202003 PARTITION OF tbl_log FOR VALUES FROM ('2020-03-01') TO ('2020-04-01');
CREATE TABLE tbl_log_202004 PARTITION OF tbl_log FOR VALUES FROM ('2020-04-01') TO ('2020-05-01');
CREATE TABLE tbl_log_202005 PARTITION OF tbl_log FOR VALUES FROM ('2020-05-01') TO ('2020-06-01');
CREATE TABLE tbl_log_202006 PARTITION OF tbl_log FOR VALUES FROM ('2020-06-01') TO ('2020-07-01');
CREATE TABLE tbl_log_202007 PARTITION OF tbl_log FOR VALUES FROM ('2020-07-01') TO ('2020-08-01');

--創建索引
CREATE INDEX idx_tbl_log_ctime ON tbl_log USING BTREE (create_time);

 

部署邏輯復制

源庫執行以下操作,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--創建復制用戶
CREATE USER repuser
REPLICATION
LOGIN
CONNECTION LIMIT 10
ENCRYPTED PASSWORD 'rep123us345er';

--創建發布
mydb=> CREATE PUBLICATION pub1 FOR TABLE tbl_log;
CREATE PUBLICATION

--給repuser用戶賦權
mydb=> GRANT CONNECT ON DATABASE mydb TO repuser;
GRANT
mydb=> GRANT USAGE ON SCHEMA pguser TO repuser;
GRANT
mydb=> GRANT SELECT ON ALL TABLES IN SCHEMA pguser TO repuser;
GRANT

以上有個步驟是給源庫上的repuser用戶賦相關權限,如果不給repuser用戶賦權,創建訂閱后目標庫無法初始化同步源庫數據。

目標庫創建訂閱,如下:

1
2
3
mydb=# CREATE SUBSCRIPTION sub1 CONNECTION 'host=192.168.2.11 port=1922 dbname=mydb user=repuser' PUBLICATION pub1;
NOTICE: created replication slot "sub1" on publisher
CREATE SUBSCRIPTION

 

注意配置好源庫的pg_hba.conf.pgpass文件,否則創建訂閱會報相關的連接不上錯誤。

數據驗證

源庫批量插入數據,如下:

1
2
INSERT INTO tbl_log(user_id,create_time)
SELECT round(100000000*random()),generate_series('2019-10-01'::date, '2020-06-20'::date, '1 day');

 

源庫查看數據,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[pg13@ydtf01 ~]$ psql mydb pguser -p 1922
psql (13beta1)
Type "help" for help.

mydb=> SELECT count(*) FROM tbl_log;
count
-------
264
(1 row)

mydb=> SELECT count(*) FROM tbl_log_202001;
count
-------
31
(1 row)

mydb=> SELECT count(*) FROM tbl_log_his;
count
-------
92
(1 row)

 

目標庫驗證數據,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[pg13@ydtf03 ~]$ psql mydb pguser -p 1924
psql (13beta1)
Type "help" for help.

mydb=> SELECT count(*) FROM tbl_log;
count
-------
264
(1 row)

mydb=> SELECT count(*) FROM tbl_log_202001;
count
-------
31
(1 row)

mydb=> SELECT count(*) FROM tbl_log_his;
count
-------
92
(1 row)

 

可見分區表的數據已從源庫同步到目標庫。

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM