1. 程式人生 > 其它 >PostgreSQL 13: 邏輯複製支援分割槽表

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)

可見分割槽表的資料已從源庫同步到目標庫。

參考