惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
U
Unit 42
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Martin Fowler
Martin Fowler
L
LangChain Blog
博客园_首页
博客园 - 【当耐特】
Vercel News
Vercel News
I
InfoQ
GbyAI
GbyAI
爱范儿
爱范儿
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
B
Blog RSS Feed
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
Google Developers Blog
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Proofpoint News Feed
美团技术团队
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
H
Help Net Security
Recent Announcements
Recent Announcements
Microsoft Azure Blog
Microsoft Azure Blog
D
Docker
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
小众软件
小众软件
J
Java Code Geeks
S
SegmentFault 最新的问题
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
The Cloudflare Blog
Recorded Future
Recorded Future
阮一峰的网络日志
阮一峰的网络日志
T
The Blog of Author Tim Ferriss
MyScale Blog
MyScale Blog
Microsoft Security Blog
Microsoft Security Blog

博客园 - MSSQL123

ubuntu24下 ext4和xfs类型磁盘以及PostgreSQL实例性能对比测试 PostgreSQL 18 新特性 skip scan,一个鸡肋的功能 记一次PostgreSQL交叉表crosstab行转列导致的OOM TiDB 扩容与缩容 PostgreSQL 高可用集群 patroni 自动故障转移测试 Ubuntu 20 环境下 patroni 自动化安装,一分钟快速搭建 patroni 集群 Ubuntu 20 环境下 pg_auto_failover 自动化安装,一分钟快速搭建pg_auto_failover集群 PostgreSQL的消息队列扩展pgmq 磁盘IO延迟和队列深度的关系 TiDB 最小拓扑架构集群安装 PostgreSQL 逻辑复制中的同步和异步模式以及其表现 prometheus 的 altermanager Silences静默告警,优雅地抑制告警 “世界上百分之99的博士和他们的论文都是垃圾”,原本以为这个观点偏激 pg_auto_failover 在多种场景下自动故障转移的验证 pgbouncer连接池设置与压力测试的最大连接数测试 pg_auto_failover 自动故障转移参数 博文阅读密码验证 - 博客园 pg_auto_failover 高可用中,PostgreSQL实例配置文件的加载步骤 pg_auto_failover集群monitor节点的高可用 prometheus监控Linux Server node_exporter代理安装和配置 prometheus监控windows window_exporter代理安装和配置 Prometheus 和 Grafana 监控 PostgreSQL 记一次MySQL binlog日志导致磁盘空间占满的问题 SQLServer 2019 标准版在虚拟机上无法充分利用CPU的问题诊断 Windows Failover Cluster集群中的EventId 1196错误日志 pg_auto_failover 环境变量导致的show命令错误 SqlServer 事务复制(transaction replication)的复制位点信息 SqlServer 事务复制的两个参数immediate_sync,allow_anonymous MySQL,SqlServer,PostgreSQL中,如何实现锁定一张表 PostgreSQL pg_auto_failover 高可用 2:pg_auto_failover集群运维 PostgreSQL pg_auto_failover 高可用 1:pg_auto_failover集群搭建 PostgreSQL patroni 高可用 4:HAProxy和Keepalived实现读写分离 PostgreSQL patroni 高可用 3:patroni 运维
PostgreSQL 17 流复制中开启逻辑复制槽同步,以及逻辑槽的故障转移
MSSQL123 · 2026-06-29 · via 博客园 - MSSQL123
wal_level = logical										#这个只能为logical,因为后续要配置逻辑复制
max_replication_slots = 10								#默认为10,根据具体的情况适当增大
max_wal_senders = 10									#默认为10,根据具体的情况适当增大
synchronous_standby_names = '*'							#同步从库的名字,这里设置为*,代表所有备库都是同步模式,当然这里只有一个备库
synchronized_standby_slots = 'pgstandby_slot01'			#这个名字是流复制配置中,流复制的复制槽名称

备节点192.168.152.137参数

hot_standby_feedback = on;								#默认关闭的,建议打开
sync_replication_slots = on;							#默认关闭的,必须打开
#synchronous_standby_names = '*'						#因为备库是pgbasebackup备份过来的,跟主库参数一样,所以这里备库的synchronous_standby_names要注释掉
#synchronized_standby_slots = 'pgstandby_slot01'		#因为备库是pgbasebackup备份过来的,跟主库参数一样,所以这里备库的synchronized_standby_slots要注释掉

对于备节点上的postgresql.auto.conf,也即流复制连接信息。因为 PG17开始支持的逻辑复制槽同步功能, slot sync worker 做的事情不是 WAL 级别协议,而是同时需要 replication protocol + 普通 SQL 连接能力,所以需要手动修改primary_conninfo,在连接串中指定一个dbname,默认的连接串为

# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repl_user password=repl_user_pwd channel_binding=prefer host=192.168.152.136 port=9700 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'pgstandby_slot01'

需要再primary_conninfo中指定一个dbname=postgres参数,如下

# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repl_user password=repl_user_pwd channel_binding=prefer host=192.168.152.136 port=9700 dbname=postgres sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'pgstandby_slot01'

否则备库启动的时候会类似如下的错误: replication slot synchronization requires "dbname" to be specified in "primary_conninfo"

2026-06-29 08:37:37.106 UTC [2241336] LOG:  starting PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0, 64-bit
2026-06-29 08:37:37.106 UTC [2241336] LOG:  listening on IPv4 address "0.0.0.0", port 9700
2026-06-29 08:37:37.106 UTC [2241336] LOG:  listening on IPv6 address "::", port 9700
2026-06-29 08:37:37.108 UTC [2241336] LOG:  listening on Unix socket "/tmp/.s.PGSQL.9700"
2026-06-29 08:37:37.110 UTC [2241340] LOG:  database system was interrupted; last known up at 2026-06-29 08:36:52 UTC
2026-06-29 08:37:37.117 UTC [2241340] LOG:  starting backup recovery with redo LSN 0/A000028, checkpoint LSN 0/A000080, on timeline ID 1
2026-06-29 08:37:37.117 UTC [2241340] LOG:  entering standby mode
2026-06-29 08:37:37.122 UTC [2241340] LOG:  redo starts at 0/A000028
2026-06-29 08:37:37.123 UTC [2241340] LOG:  completed backup recovery with redo LSN 0/A000028 and end LSN 0/A000120
2026-06-29 08:37:37.123 UTC [2241340] LOG:  consistent recovery state reached at 0/A000120
2026-06-29 08:37:37.123 UTC [2241336] LOG:  database system is ready to accept read-only connections
2026-06-29 08:37:37.125 UTC [2241342] LOG:  slot sync worker started
2026-06-29 08:37:37.127 UTC [2241342] ERROR:  replication slot synchronization requires "dbname" to be specified in "primary_conninfo"
2026-06-29 08:37:37.299 UTC [2241341] LOG:  started streaming WAL from primary at 0/B000000 on timeline 1
2026-06-29 08:38:37.148 UTC [2241734] LOG:  slot sync worker started
2026-06-29 08:38:37.149 UTC [2241734] ERROR:  replication slot synchronization requires "dbname" to be specified in "primary_conninfo"
2026-06-29 08:39:37.205 UTC [2242122] LOG:  slot sync worker started
2026-06-29 08:39:37.206 UTC [2242122] ERROR:  replication slot synchronization requires "dbname" to be specified in "primary_conninfo"
2026-06-29 08:40:37.270 UTC [2242510] LOG:  slot sync worker started
2026-06-29 08:40:37.271 UTC [2242510] ERROR:  replication slot synchronization requires "dbname" to be specified in "primary_conninfo"
2026-06-29 08:41:37.333 UTC [2242905] LOG:  slot sync worker started
2026-06-29 08:41:37.333 UTC [2242905] ERROR:  replication slot synchronization requires "dbname" to be specified in "primary_conninfo"

启动从库,流复制自动开启,可以看到walreceiver进程启动,说明目前节点是一个备用节点

root@ubuntu27:/usr/local/pg_install# bash pg_streaming_replication_setup.sh
=== PostgreSQL Standby Initialization Start ===
Mon Jun 29 05:30:37 PM CST 2026
############ Data directory /usr/local/pgsql17/pg9700/data does not exist. Creating it...
############ Checking replication user repl_user on primary...
############ Replication user repl_user already exists.
############ Checking replication slot pgstandby_slot01 on primary...
############ Replication slot pgstandby_slot01 already exists.
############ Performing pg_basebackup from primary node...
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/E000060 on timeline 1
pg_basebackup: starting background WAL receiver
30961/30961 kB (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 0/E000158
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed
############ Starting PostgreSQL standby...
=== Standby Initialization Complete ===
Mon Jun 29 05:30:40 PM CST 2026
root@ubuntu27:/usr/local/pg_install#
root@ubuntu27:/usr/local/pg_install# systemctl restart postgresql9700
root@ubuntu27:/usr/local/pg_install#
root@ubuntu27:/usr/local/pg_install# systemctl status postgresql9700
● postgresql9700.service - PostgreSQL database server
     Loaded: loaded (/etc/systemd/system/postgresql9700.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-06-29 17:33:34 CST; 8s ago
    Process: 2263119 ExecStart=/usr/local/pgsql17/server/bin/pg_ctl start -D ${PGDATA} -s -w -t ${PGSTARTTIMEOUT} (code=exited, status=0/SUCCESS)
   Main PID: 2263123 (postgres)
      Tasks: 6 (limit: 4543)
     Memory: 63.8M (peak: 64.0M)
        CPU: 124ms
     CGroup: /system.slice/postgresql9700.service
             ├─2263123 /usr/local/pgsql17/server/bin/postgres -D /usr/local/pgsql17/pg9700/data
             ├─2263130 "postgres: logger "
             ├─2263131 "postgres: checkpointer "
             ├─2263132 "postgres: background writer "
             ├─2263133 "postgres: startup recovering 00000001000000000000000F"
             └─2263139 "postgres: walreceiver streaming 0/F000060"

Jun 29 17:33:34 ubuntu27 systemd[1]: Starting postgresql9700.service - PostgreSQL database server...
Jun 29 17:33:34 ubuntu27 pg_ctl[2263123]: 2026-06-29 09:33:34.306 UTC [2263123] LOG:  redirecting log output to logging collector process
Jun 29 17:33:34 ubuntu27 pg_ctl[2263123]: 2026-06-29 09:33:34.306 UTC [2263123] HINT:  Future log output will appear in directory "/usr/local/pgsql17/pg9700/log".
Jun 29 17:33:34 ubuntu27 systemd[1]: Started postgresql9700.service - PostgreSQL database server.
root@ubuntu27:/usr/local/pg_install#

订阅节点192.168.152.138参数

参数无特殊要求

4,流复制状态检查

192.168.152.136和192.168.152.137之间的流复制已完成同步,检查流复制的状态

主节点192.168.152.136上的状态

root@ubuntu26:/usr/local/pg_install# psql -h 127.0.0.1 -p 9700  postgres postgres
Password for user postgres:
psql (17.6)
Type "help" for help.
postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 3019576
usesysid         | 16388
usename          | repl_user
application_name | walreceiver
client_addr      | 192.168.152.137
client_hostname  |
client_port      | 45264
backend_start    | 2026-06-29 09:03:23.143699+00
backend_xmin     |
state            | streaming
sent_lsn         | 0/D000060
write_lsn        | 0/D000060
flush_lsn        | 0/D000060
replay_lsn       | 0/D000060
write_lag        | 00:00:00.022827
flush_lag        | 00:00:00.023348
replay_lag       | 00:00:00.154594
sync_priority    | 1
sync_state       | sync
reply_time       | 2026-06-29 09:03:23.182874+00

postgres=#

从节点192.168.152.137上的状态

root@ubuntu27:/usr/local/pg_install# psql -h 127.0.0.1 -p 9700  postgres postgres
Password for user postgres:
psql (17.6)
Type "help" for help.

postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_wal_receiver;
-[ RECORD 1 ]---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid                   | 2251271
status                | streaming
receive_start_lsn     | 0/D000000
receive_start_tli     | 1
written_lsn           | 0/D000060
flushed_lsn           | 0/D000060
received_tli          | 1
last_msg_send_time    | 2026-06-29 09:04:53.210286+00
last_msg_receipt_time | 2026-06-29 09:04:53.21439+00
latest_end_lsn        | 0/D000060
latest_end_time       | 2026-06-29 09:03:23.156472+00
slot_name             | pgstandby_slot01
sender_host           | 192.168.152.136
sender_port           | 9700
conninfo              | user=repl_user password=******** channel_binding=prefer dbname=replication host=192.168.152.136 port=9700 fallback_application_name=walreceiver sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable

postgres=#

5,创建发布

创建逻辑复制用户

create database db01;

###创建复制用户
--drop user app_replication;
create user logic_repl_user with password 'logic_repl_user';
alter role logic_repl_user with replication;

###给复制用户授权,切换到目标数据库db01下执行
GRANT CONNECT ON DATABASE db01 TO logic_repl_user;
GRANT USAGE ON SCHEMA public TO logic_repl_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO logic_repl_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO logic_repl_user;
--切换到db01下面

--创建测试表
create table test_slot_failover
(
	c1 int generated always as identity primary key,
	c2 timestamptz 
);

--创建逻辑复制槽,注意最后一个参数是是否failover,默认是false,要明确指出failover为true
select * from pg_create_logical_replication_slot('logic_repl_slot01','pgoutput', false,false, true);
slot_name        |lsn      |
-----------------+---------+
logic_repl_slot01|0/31A9BB0|

--创建发布
create publication mysqlpg_db01_pulication for table test_slot_failover with (publish = 'insert,update');

Updated Rows	0
Execute time	0.008s
Start time	Mon Jun 29 14:12:15 CST 2026
Finish time	Mon Jun 29 14:12:15 CST 2026
Query	create publication mysqlpg_db01_pulication for table test_slot_failover with (publish = 'insert,update')

查看逻辑复制槽的状态

主节点上

postgres=# SELECT slot_name, database, failover, synced,active  FROM pg_replication_slots;
     slot_name     | database | failover | synced | active
-------------------+----------+----------+--------+--------
 pgstandby_slot01  |          | f        | f      | t											#注意这是物理复制槽,只有主节点上有
 logic_repl_slot01 | db01     | t        | f      | f
(2 rows)

备节点上

postgres=#
postgres=# SELECT slot_name, database, failover, synced,active  FROM pg_replication_slots;
     slot_name     | database | failover | synced | active
-------------------+----------+----------+--------+--------
 logic_repl_slot01 | db01     | t        | t      | f										#可以发现逻辑复制槽已经被复制到备节点
(1 row)

6,创建订阅

订阅服务器上创建测试库db01创建测试表

--切换到db01下创建订阅表
create table test_slot_failover
(
	c1 int generated always as identity primary key,
	c2 timestamptz 
);

创建订阅


--创建订阅
create subscription mypg_db01_subscription 
connection 'host=192.168.152.136 port=9700 dbname=db01 user=logic_repl_user  password=logic_repl_user' 
publication mypg_db01_pulication 
with 
(
    create_slot = false,						#这里不创建复制槽,因为前面已经提前创建好了
    slot_name = logic_repl_slot01,
    streaming = parallel,
    copy_data = true,
    failover = true								#注意如果没有创建复制槽,上面的create_slot为true的话,这里也一定要为failover = true,
);


Updated Rows	0
Execute time	0.051s
Start time	Mon Jun 29 14:29:59 CST 2026
Finish time	Mon Jun 29 14:29:59 CST 2026
	create subscription mypg_db01_subscription 
	connection 'host=192.168.152.136 port=9700 dbname=db01 user=logic_repl_user  password=logic_repl_user' 
	publication mypg_db01_pulication 
	with 
	(
	    create_slot = false,
	    slot_name = logic_repl_slot01,
	    streaming = parallel,
	    copy_data = true,
	    failover = true
	)


--查看订阅状态
select * from pg_subscription; 
oid  |subdbid|subskiplsn|subname               |subowner|subenabled|subbinary|substream|subtwophasestate|subdisableonerr|subpasswordrequired|subrunasowner|subfailover|subconninfo                                                                              |subslotname      |subsynccommit|subpublications        |suborigin|
-----+-------+----------+----------------------+--------+----------+---------+---------+----------------+---------------+-------------------+-------------+-----------+-----------------------------------------------------------------------------------------+-----------------+-------------+-----------------------+---------+
16444|  16388|0/0       |mypg_db01_subscription|      10|true      |false    |p        |d               |false          |true               |false        |false      |host=192.168.152.136 port=9700 dbname=db01 user=logic_repl_user  password=logic_repl_user|logic_repl_slot01|off          |{mypg_db01_publication}|any      |

7,PostgreSQL流复制故障转移

模拟主节点故障,备用节点提升为主节点

1,关闭主节点                        systemctl stop postgresql9700

root@ubuntu26:/usr/local/pg_install# systemctl stop postgresql9700
root@ubuntu26:/usr/local/pg_install#

2,从节点直接pg_promote    select pg_promote()

postgres=# select pg_promote();
 pg_promote
------------
 t
(1 row)

此时逻辑复制的订阅端开始报错,提示找不到发布端主机: could not connect to the publisher: connection to server at "192.168.152.136", port 9700 failed: Connection refused  Is the server running on that host and accepting TCP/IP connections?

2026-06-29 09:14:43.546 UTC [2247682] LOG:  background worker "logical replication apply worker" (PID 2265592) exited with exit code 1
2026-06-29 09:14:48.543 UTC [2265603] LOG:  logical replication apply worker for subscription "mypg_db01_subscription" has started
2026-06-29 09:14:48.544 UTC [2265603] ERROR:  could not connect to the publisher: connection to server at "192.168.152.136", port 9700 failed: Connection refused
		Is the server running on that host and accepting TCP/IP connections?
2026-06-29 09:14:48.545 UTC [2247682] LOG:  background worker "logical replication apply worker" (PID 2265603) exited with exit code 1
2026-06-29 09:14:53.544 UTC [2265611] LOG:  logical replication apply worker for subscription "mypg_db01_subscription" has started
2026-06-29 09:14:53.545 UTC [2265611] ERROR:  could not connect to the publisher: connection to server at "192.168.152.136", port 9700 failed: Connection refused
		Is the server running on that host and accepting TCP/IP connections?
2026-06-29 09:14:53.546 UTC [2247682] LOG:  background worker "logical replication apply worker" (PID 2265611) exited with exit code 1
2026-06-29 09:14:58.556 UTC [2265623] LOG:  logical replication apply worker for subscription "mypg_db01_subscription" has started
2026-06-29 09:14:58.557 UTC [2265623] ERROR:  could not connect to the publisher: connection to server at "192.168.152.136", port 9700 failed: Connection refused
		Is the server running on that host and accepting TCP/IP connections?
2026-06-29 09:14:58.559 UTC [2247682] LOG:  background worker "logical replication apply worker" (PID 2265623) exited with exit code 1
2026-06-29 09:15:03.568 UTC [2265636] LOG:  logical replication apply worker for subscription "mypg_db01_subscription" has started
2026-06-29 09:15:03.569 UTC [2265636] ERROR:  could not connect to the publisher: connection to server at "192.168.152.136", port 9700 failed: Connection refused
		Is the server running on that host and accepting TCP/IP connections?
2026-06-29 09:15:03.570 UTC [2247682] LOG:  background worker "logical replication apply worker" (PID 2265636) exited with exit code 1

8,逻辑复制故障转移

此时需要对订阅端执行故障转移,也即先停止订阅,然后修改订阅的连接串中的主机信息,指向新的主节点,最后启动订阅

--停止订阅
ALTER SUBSCRIPTION mypg_db01_subscription DISABLE;
--修改订阅的连接信息,执行新的主节点
ALTER SUBSCRIPTION mypg_db01_subscription CONNECTION  'host=192.168.152.137 port=9700 dbname=db01 user=logic_repl_user  password=logic_repl_user'
--启动订阅
ALTER SUBSCRIPTION mypg_db01_subscription ENABLE;

查看新的订阅信息

oid  |subdbid|subskiplsn|subname               |subowner|subenabled|subbinary|substream|subtwophasestate|subdisableonerr|subpasswordrequired|subrunasowner|subfailover|subconninfo                                                                              |subslotname      |subsynccommit|subpublications        |suborigin|
-----+-------+----------+----------------------+--------+----------+---------+---------+----------------+---------------+-------------------+-------------+-----------+-----------------------------------------------------------------------------------------+-----------------+-------------+-----------------------+---------+
16447|  16388|0/0       |mypg_db01_subscription|      10|true      |false    |p        |d               |false          |true               |false        |false      |host=192.168.152.137 port=9700 dbname=db01 user=logic_repl_user  password=logic_repl_user|logic_repl_slot01|off          |{mypg_db01_publication}|any      |

在新的主库192.168.152.137上,往发布表写入数据,可以正常同步到订阅端。

9,总结

PostgreSQL 17 已经可以在物理备库上同步逻辑复制槽,实现“逻辑复制 Failover 的基础能力”,本文简单通过一个简单的测试案例来测试逻辑复制槽的failover效果,订阅端可以基于新的主节点做逻辑复制,但订阅端的连接切换仍需人工干预,尚未实现全自动高可用。