PostgreSQL主从复制:不开归档也能同步?流复制原理与代价详解
2026/9/9 22:36:46 网站建设 项目流程

这个问题我印象很深,重庆这边不少做数据库运维的朋友都问过我:PostgreSQL 做主从复制,主库不开归档日志,到底能不能同步?

直接说结论:能,而且完全不影响流复制本身。很多人把“归档”和“复制”当成一回事,其实它们是两个完全独立的环节。你开不开归档,都不影响 WAL 日志通过流复制协议发给备库。但反过来讲,如果你只做流复制、完全关掉归档,你就要接受一个后果:你的灾难恢复能力和备库重建能力会被削弱。所以这个问题的完整答案不是简单的“能”或“不能”,而是“能不能”后面还跟着一串“但是”。这篇就把它彻底讲透。

先说个背景,我这边平时主要做重庆及周边企业的 PostgreSQL、Oracle 数据库运维和架构咨询,主从复制是几乎每个生产环境都要碰的东西。每次有客户拿着这个问题来问,我基本能猜到他们脑子里想的是 MySQL 那一套逻辑——因为 MySQL 的主从复制确实和 binlog 归档日志强绑定,不开 binlog 就做不了复制。但 PG 不是这么设计的,PG 里复制依赖的是 WAL(预写日志)的实时传输,归档只是 WAL 的一个额外备份出口。把这个机制搞清楚了,后面所有参数配置、排查思路就都顺了。

1. 主从复制和归档到底是什么关系

1.1 两套机制,两个出口

PostgreSQL 的 WAL 日志从生成到最后销毁,中间有两条路可以走:

第一条路是流复制通道。主库的 WAL sender 进程把日志段直接通过网络发送给备库的 walreceiver 进程,备库拿到日志后不断重放到自己的数据目录里。这个过程是实时的,和归档没有半点关系。

第二条路是归档通道。主库的 archive 进程(如果设置了archive_mode = on)把已经写满的 WAL 段文件复制一份丢到归档目录里,这个目录可以本地的,也可以是 NFS、对象存储之类的。归档的作用是留底,目的是为了将来做 PITR(时间点恢复)或者用归档日志把某个备库补到最新状态。

所以你看,流复制用的是“传输中”的日志,归档用的是“已经写完并切走”的日志。你关掉归档,只是切断了第二条路,第一条路照常跑。

为了把这个讲得更直白,我打个比方。WAL 日志就像店里每天记流水账的账本,主库每做一笔交易就先往账本上写一笔。归档是什么?是你每天打烊之后,把写完的账本复印一份,存到保险柜里,万一哪天店里着火了,你还能靠保险柜里的复印件把账目恢复出来。流复制是什么?是你旁边开了一家分店(备库),你每记一笔,就立刻把这一笔抄送一份给分店,分店照着誊写一份。所以你复印不复印(归档开不开),都不影响你往分店抄送(流复制)。

这个比喻能帮你理解一个核心观点:归档是给“过去”留后路,流复制是让“未来”有实时副本。两个东西服务的场景不同,不是同一个功能。

1.2 为什么总有人把两者混在一起

这个问题出现频率高,我分析下来主要有两个原因。

原因一:MySQL 的思维惯性。MySQL 主从复制里的 binlog 是“一专多能”——它既是归档/备份的依据,也是复制传输的数据源。你让一个 MySQL DBA 来配 PG,他潜意识里会觉得“不开日志归档怎么做复制”,但其实 PG 早在 9.0 版本就把复制独立出来了,流复制不需要等 WAL 归档到某个目录再拉取,而是直接内存级、实时地推送。

原因二:PG 的某些高可用方案(比如 Patroni 搭配 WAL 归档)会同时要求开归档。在实际生产里,很多架构师为了稳妥,会同时开启archive_modearchive_command,这就让新手误以为归档是复制的“前置条件”。但实际上那只是高可用方案里的“增强配置”,不是“必要条件”。

所以你现在再遇到别人说“PG 主从必须开归档”,你可以这样回答他:流复制本身不需要归档,但你要做完善的备份策略、要能在主库数据目录损坏时做时间点恢复,归档就几乎是必须的。开不开归档,取决于你的业务对 RPO/RTO 的要求,不取决于你想不想做主从。

2. PG 流复制的核心流程与关键角色

2.1 WAL 日志的产生、发送与重放

要理解为什么不归档也能同步,就需要看看一条 WAL 日志从生成到应用完整走过了哪些步骤。

事务提交时,主库把变更记录写入 WAL buffer,然后刷到 pg_wal 目录下的 WAL segment 文件里。每个 segment 默认 16MB,写满之后会切换到下一个编号的 segment。这时候,主库上已经配置好的max_wal_senders会允许若干个 WAL sender 进程存在。每个备库连接上来之后,会有一个专门的 WAL sender 进程负责按照备库请求的 LSN(日志序列号)位置,把 WAL 数据从 pg_wal 目录或者内存缓存里读出来,通过网络发给备库。

备库这边,walreceiver 进程负责接收这些数据,并把它们写进备库自己的 pg_wal 目录。然后,备库的 startup 进程会按照 WAL 记录逐个重放,把变更应用到数据文件里。这一切都是异步的、流水线式的,备库永远在追主库的尾巴,但正常情况下差距只有几百毫秒甚至更小。

这里面有个关键点:WAL sender 在发送日志时,读的是主库 pg_wal 目录里的文件,不是归档目录。哪怕主库完全没开归档,只要 WAL 文件还在 pg_wal 目录里,sender 就有数据可发。

所以“能不能同步”这个问题,真正应该问的是:主库的 pg_wal 目录里,备库需要的那个 WAL 段还在不在?如果备库因为网络原因落后太多,需要读一个已经被主库回收掉的旧 WAL 段,而你又没开归档,那备库就追不上了。这就是“不开归档能同步”这句话的前提限制,后面我会详细讲。

2.2 复制槽:防止 WAL 被过早回收的保险

既然主库 pg_wal 里的 WAL 文件会被循环复用或回收,那怎么保证备库需要的老日志不被删掉?答案有两个:一是调大wal_keep_size,在 pg_wal 目录里多保留一段时间;二是用复制槽(replication slot)。

我一般建议生产环境都开复制槽。复制槽的作用是:主库会记住每个备库当前消费到的 WAL 位置,只要备库还没消费完,主库就不会删除对应的 WAL 日志。这相当于给每个备库发了一个“请勿删除”的标签。

但复制槽也有一个副作用——如果你长期忘记清理备库,或者备库下线了,复制槽会一直把 WAL 日志留在主库磁盘上,直到把磁盘撑爆。所以用复制槽必须配合监控,备库下线时要及时pg_drop_replication_slot

这里再多提一句,PG 12 之前,备库的复制槽是靠standby.signal创建之前手工指定的,PG 12 以后可以直接用pg_create_physical_replication_slot配合primary_slot_name来管理物理复制槽,方便不少。

2.3 归档在恢复路径里到底起什么作用

那归档到底有什么用?最核心的用处是 PITR。

假设你做了全量备份(比如 pg_basebackup 的基础备份),然后开启了归档。当你需要把数据库恢复到某个历史时间点时,流程是:用全量备份把数据文件恢复到那一刻,然后把归档日志从那个时间点开始,用restore_command一步步重放到目标时间点。归档日志在这里就充当了“时间线拼接器”。

如果不开归档,你只能把数据库恢复到“全量备份的时刻”,之后所有的事务变更都无法重演。哪怕你有流复制备库,备库也只能反映主库的“当前状态”,不能把主库“回放”到任意历史时间点。

所以你看,归档和流复制服务的恢复场景是不同的:流复制对应的是“主库宕机,备库顶上”;归档对应的是“数据误操作、逻辑损坏、需要时间点回退”。生产系统要想真正睡得着觉,两个都要有。

3. 实操过程:主库不开归档,部署一套流复制

3.1 实验环境准备

为了演示,我建议你在本地或者测试机上用两个实例做实验。下面是我常用的环境:

  • 主库:192.168.1.10,端口 5432,数据目录 /data/pgdata
  • 备库:192.168.1.11,端口 5432,数据目录 /data/pgdata
  • PG 版本:我用的是 PostgreSQL 16,但流程在 PG 12+ 都是通用的

你可以直接用 YUM/APT 装好 PG,或者用编译安装,这里不再赘述。关键是,主库安装时不要设置archive_mode,我演示的正是“主库不开归档”的场景。

3.2 主库参数修改:哪些必须改,哪些不用动

首先编辑主库的 postgresql.conf:

listen_addresses = '*' port = 5432 wal_level = replica max_wal_senders = 10 wal_keep_size = 512MB max_replication_slots = 10

逐项解释一下:

  • listen_addresses:允许远程连接。
  • wal_level = replica:这是流复制必须的,PG 15 之前叫hot_standby,PG 15 之后统一叫replica。如果设成minimal(PG 15 前是archiveminimal),备库连不上,因为物理复制需要 WAL 里带完整的数据页信息。
  • max_wal_senders:允许同时存在多少个 WAL sender 进程。一个备库至少占一个,建议设 10 左右,留点余量。
  • wal_keep_size:告诉主库在 pg_wal 目录里至少保留多少 MB 的 WAL 文件。我设 512MB,防止备库短时间断网时的日志被清理。PG 13 之前这个参数叫wal_keep_segments,单位是 WAL 段数量。换算的话:1 个段 = 16MB,所以 512MB 相当于 32 个段。
  • max_replication_slots:物理复制槽的数量上限,不建槽的话也可以不设,但生产我建议建。

不需要改的archive_mode保持offarchive_command留空。这正是本次实验的核心。

改完之后重启主库:

pg_ctl restart -D /data/pgdata
3.3 创建复制用户和 pg_hba.conf 授权

流复制需要一个具备REPLICATION权限的数据库用户:

CREATE ROLE repl LOGIN REPLICATION PASSWORD 'repl_password';

然后编辑 pg_hba.conf,增加如下行:

# 允许 repl 用户从备库 IP 进行复制连接 host replication repl 192.168.1.11/32 md5

这里要特别提醒:replication 连接走的是复制协议,不是普通数据库连接,所以一定要写在replication那一类里。有的新手把它写在all后面,或者只写了host all all ...,结果备库就是连不上,报FATAL: no pg_hba.conf entry for replication connection。所以记住,必须是host replication

改完 pg_hba.conf 之后 reload 一下:

pg_ctl reload -D /data/pgdata
3.4 用 pg_basebackup 做基础备份并启动备库

在主库上执行备份,把数据文件完整拉到备库:

pg_basebackup -h 192.168.1.10 -p 5432 -U repl -D /data/pgdata -Fp -Xs -R -P

参数解释:

  • -Fp:按文件格式备份,不是 tar 包。
  • -Xs:备份过程中同时把 WAL 日志流式传过来,确保备库得到一个一致性的快照点。
  • -R:自动生成备库的standby.signal文件和postgresql.auto.conf里的primary_conninfo,这一步非常省事。
  • -P:显示进度。

执行完后,检查备库的 /data/pgdata 下应该有两个关键文件:

  • standby.signal:告诉 PG 启动时以备库(standby)模式启动。
  • postgresql.auto.conf:包含primary_conninfoprimary_slot_name(如果你指定了)。

然后启动备库:

pg_ctl start -D /data/pgdata

如果你用的是 PG 11 及以前的版本,备库需要在 recovery.conf 里写standby_mode = onprimary_conninfo,PG 12 之后统一改成了standby.signal机制。你只要记住:PG 12+ 的备库身份靠 standby.signal 标记,不是靠某个参数开关。

3.5 验证同步状态

在主库上执行:

SELECT client_addr, state, sync_state, sent_lsn, replay_lsn FROM pg_stat_replication;

正常情况下,你会看到一行:

client_addr | state | sync_state | sent_lsn | replay_lsn --------------+---------+------------+------------+------------ 192.168.1.11 | streaming | async | 0/3002E10 | 0/3002E10

state = streaming说明流复制已经通了;sync_state = async说明是异步复制,主库不会等备库确认才提交事务,这也是默认情况。

到这里,你已经成功在主库完全没有开启归档的前提下,部署了一套可以实时同步的 PG 主从架构。从这个实验可以看出,主库开不开归档,对“流复制通道是否建立”没有影响。

4. 同步复制与异步复制的差异,及监控要点

4.1 异步是默认,但你要知道怎么切同步

上面实验里看到sync_state = async,这是 PG 默认的异步复制。意思是主库提交一个事务时,只要本地 WAL 刷盘成功就返回给客户端,不等备库收到并重放。这个模式的优点是主库性能几乎不受影响,缺点是备库可能会有延迟,主库突然宕机时,可能会丢一部分已在主库提交但尚未传到备库的事务。

如果你业务要求更高的数据安全等级,可以把复制模式改成同步复制。做法是在主库的 postgresql.conf 里设置:

synchronous_standby_names = 'FIRST 1 (standby1)' synchronous_commit = on

这里standby1是你备库的application_name。所谓 FIRST 1,意思是排在最前面的 1 个备库确认后,主库的提交才算完成。

改成同步之后,你再看pg_stat_replicationsync_state会变成sync,并且主库的提交延迟会因为要等备库确认而变高,特别是两台机器物理距离远的时候,延迟会比较明显。所以同步复制不是银弹,要结合实际网络条件来选。

我个人的建议:同机房、同城双机场景,可以开同步复制换取更高的数据安全;跨地域、网络不稳定的场景,老老实实用异步,否则 CPU 和负载都会因为等确认而变得很难看。

4.2 常见监控 SQL与延迟排查

做 DBA 的,不能光把复制搭起来就不管了。我一般会在监控系统里放几条 SQL,定时跑。

-- 查看备库 replay 延迟(字节差) SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_delay_bytes, pg_wal_lsn_diff(pg_current_wal_lsn(), flush_lsn) AS flush_delay_bytes, client_addr, state, sync_state FROM pg_stat_replication;
-- 查看备库是否长时间没有心跳 SELECT client_addr, state, now() - backend_start AS session_age, now() - state_change AS state_change_age FROM pg_stat_replication;

如果 replay_delay_bytes 持续增大,说明备库重放速度跟不上,可能是备库磁盘 IO 慢,或者备库上有大的查询在抢资源。如果state长时间不是 streaming,而是 catchup,说明备库在追赶日志,你要关注网络和主库的 WAL 保留策略。

另外要提醒的是,pg_stat_replication里查到的write_lsnflush_lsnreplay_lsn分别代表备库收到、刷盘、重放的 WAL 位置。异步模式下,这三个位置和主库的pg_current_wal_lsn()的差距,就是最直观的同步延迟指标。

4.3 备库只读,别手滑在上面写数据

备库在 standby 模式下是只读的,但很多初学者不理解,这个“只读”是物理层面的,不是权限层面的。你在备库上执行CREATE TABLEINSERT等写操作,会直接报错:

ERROR: cannot execute INSERT in a read-only transaction

但有几种例外要注意:临时表在备库上是允许建的,因为它只对当前会话可见,不会影响物理数据一致性;pg_stat_statements之类的扩展也可能在备库上写入统计信息,这些不影响复制。

建议生产环境在备库上把default_transaction_read_only设为on,从会话级别就杜绝误操作。

5. 主库不开归档的代价:哪些场景会踩坑

5.1 备库落后太多,WAL 被回收就追不上了

这是不开归档最典型的坑。举个例子:你的主库今天凌晨 2 点因为大批量导入,WAL 写得特别多,而备库因为某种原因停掉了半天。等你下午发现备库不可用,重启备库想接着同步时,备库会要求主库提供它最后一次收到的 WAL 位置之后的日志。但主库的 pg_wal 目录里早就把那些日志回收了(假设你没开足够大的wal_keep_size,也没建复制槽),归档又是关闭状态,怎么办?

备库会一直卡在那里报错,核心日志是:

FATAL: requested WAL segment 00000001000000000000002A has already been removed

这就是为什么我在 3.2 节强调wal_keep_size或者复制槽至少要配一个的原因。但如果你两者都没配,又不开归档,那你只能重新做一次pg_basebackup来重建备库,而不能“续传”。

所以,如果你明确知道自己的环境里备库可能长期离线,或者 WAL 产生速度很快,不开归档的风险就非常大。开归档,相当于给备库加了一道保险网:即使主库的 WAL 被清了,备库还能从归档目录里拉取历史日志补上。

5.2 无法做 PITR,误操作只能认栽

这个前面已经说过了,再给个实际例子。

某天业务人员执行了DELETE FROM orders WHERE status = 'obsolete',忘了加AND create_time < '2024-01-01',结果把所有历史订单全删了。这时候你的第一反应是什么?用 PITR 把数据库恢复到一个小时前,让业务先恢复,再导出数据。但如果你没开归档,你手里只有一个昨天的全量备份,恢复出来也是昨天的数据,这一个小时内新增的订单就全丢了。

很多没开归档的 PG 环境,出事之后唯一的补救手段是:拿备库在误操作发生前的一个时间点快照(通过物理手段或工具),而这个手段其实是非常有限的。所以每次客户跟我说“我们就是不想开归档,觉得占磁盘”,我都会问他一句:如果你误删了数据,你能接受丢多久?如果答案是“一天都不能丢”,那就老老实实开归档,做备份策略。

5.3 想用 pg_rewind 恢复旧主库时更麻烦

级联故障、主备切换后,旧主库如果要重新加入集群,通常用pg_rewind快速增量同步数据,避免重新全量复制。pg_rewind需要从新主库拉取旧主库落后期间产生的 WAL 日志,而这些日志从哪来?如果新主库的 pg_wal 里还留着,那没问题;如果已经被回收了,而你开过归档,新主库可以去归档目录取;没开归档的话,pg_rewind很可能失败。

这也是为什么不少高可用方案的文档里会强制要求开归档——因为它依赖归档来度过日志缺失的空窗期。

5.4 什么时候你可以放心不开归档

说完坏处,也得说说什么场景可以不开归档。

一是纯测试环境:你只是要验证流复制功能,不在乎数据丢失,或者能随时重建数据。

二是短生命周期集群:比如你临时搭一套环境做数据分析,用完就删,不需要灾备和历史恢复。

三是你的备份方案根本不以事务日志为基础:比如你每天夜里定时用pg_dump逻辑备份,接受最多丢一天数据,而且业务数据没有严格的一致性要求。这种情况下,不开归档也可以接受,因为逻辑备份本身不依赖 WAL。

但只要是核心业务生产环境,我的态度一直很明确:开归档不是可选项,是必选项。它和主从复制不冲突,而且互相配合最好的姿势是:流复制保证“主库挂了有备用”,归档保证“数据坏了能回滚”,两者合在一起才是完整的数据库容灾。

6. 常见问题与排查技巧实录

6.1 备库一直显示 “catchup”,而不是 “streaming”,怎么办

备库启动后,状态一般会短暂经历catchup,然后变成streaming。如果一直停在catchup,说明备库正在追赶主库的日志,且差距较大。

排查步骤:

  1. 看主库pg_stat_replicationreplay_lsnpg_current_wal_lsn()差距有多大。
  2. 看备库 IO 和 CPU:如果备库是机械盘,重放开 16MB 的 WAL 文件速度受限,追赶慢是正常的,等一会儿就好。
  3. 看备库日志里有没有反复出现的 WAL 文件缺失错误,如果有,详见 6.2。

多数情况下,开着流复制不管它,过一段时间备库会自然追上。如果你设置了复制槽,主库会保证需要的 WAL 不被清理,所以不用太慌,但也要关注追赶时间是否在业务可接受范围内。

6.2 备库日志报 “requested WAL segment has already been removed”

这个错误上过线的人应该都不陌生。原因就是备库需要的 WAL 段在主库的 pg_wal 里已经不存在,且归档关闭/归档目录也找不到。

处理办法只有一个:重建备库,用pg_basebackup重新拉一份全量数据,再启动流复制。这就是不自救的后果——你要依赖重新做一次 pg_basebackup 的时间窗口,期间业务没有跨机房的备用节点。

防止策略:

  • 开复制槽:CREATE SLOT之后主库会“钉住”备库的消费位置。
  • 开归档:万一 pg_wal 里没有,可以从归档拉取。
  • 调大wal_keep_size:适合备库数量少、WAL 产生速度可预估的环境。

我个人最推荐组合是:开复制槽 + 开归档。两条腿走路,哪一个都不能少。

6.3 备库启动报 “FATAL: no pg_hba.conf entry for replication connection”

百分之九十的情况是 pg_hba.conf 配置漏了replication关键字。比如:

host all repl 192.168.1.11/32 md5

这种写法只允许普通数据库连接,不允许复制连接。复制连接需要这样写:

host replication repl 192.168.1.11/32 md5

改完记得 reload。

另外还有一种情况,主库上的复制用户没有REPLICATION权限。你在 pg_hba.conf 里面写了replication,但用户的角色没有这个属性,备库连接时可能报:

FATAL: permission denied for replication

解决办法是给用户赋值权限:

ALTER ROLE repl WITH REPLICATION;

这种权限类问题,通常多看两眼日志就能定位,备库那端报错往往不是第一现场,你要去主库的日志里找根因。

6.4 同步复制模式下,备库挂了把主库也拖住了

有些同学把synchronous_standby_names配上去之后,发现备库一断,主库的写入也 hang 住了,客户端报错:

ERROR: canceling statement due to conflict with recovery

或者主库直接不commit。原因很简单:同步复制要求备库确认,备库不可用时,主库会一直等待,事务提交被无限期挂起。

如果你能接受“备库挂了主库也能继续写入”,建议把synchronous_commit调成remote_apply之外的降级选项,或者用DEFAULT+synchronous_standby_names保持默认的off/local,让主库在备库不可用时自动降级成异步。更严格的做法是设置synchronous_standby_names时不要用FIRST 1的强绑定写法,而是用某种带降级逻辑的HA方案来管理。

生产环境里,我一般建议:同步复制只用于同机房、网络稳定的两台机器,跨机房一定要慎用,或者使用半同步方案(比如用 Pgpool-II、Patroni 做管理)。裸用同步复制跨机房,网络抖动一次,业务可能就抖一片,那感觉比丢几秒数据还难受。

7. 手工切换与回切流程:验证你的复制真能救急

光看state=streaming不算数,你得真正演练过主备切换,才知道你的环境在故障来临时能不能顶住。

假设你要把备库提升为主库,步骤如下:

在备库上执行:

SELECT pg_promote();

或者旧版本用:

pg_ctl promote -D /data/pgdata

执行完之后,备库会立刻应用完已接收的日志,然后把standby.signal文件删掉,回放完最后一段 WAL 后,开始接受读写。

同时,确认新主库的pg_stat_replication状态。如果旧主库还要重新加入集群,可以在修复后用pg_rewind快速切换回来,步骤大致是:

  1. 确保旧主库已停止。
  2. 用新主库的pg_rewind --target-pgdata=旧主库目录 --source-server='host=新主库ip port=5432 user=repl dbname=postgres'把旧主库对齐到新主库的时间线。
  3. 在旧主库目录里重新创建standby.signal,再启动它作为新主库的备库。

pg_rewind需要开启wal_log_hints或使用 checksum,否则会报不支持。这个也是配置时容易漏的一个点,很多新版本还默认关闭wal_log_hints,所以如果你想做快速回切,配置阶段就要把它打开:

wal_log_hints = on

如果没有这个参数,pg_rewind会拒绝执行,提示数据页缺少校验信息。这时候你只能老老实实重新pg_basebackup

实际上,我见过不少团队在生产环境做主备切换演练,过程比预想的坑多:有的是因为关着归档,备库在切换时没有完整日志导致丢数据;有的是因为复制槽没建,切换后新主库把旧主库需要的 WAL 直接删了,旧主库回不来了。所以建议你在测试环境先把切换演练跑熟,演练完再回切一轮,确认整个生命周期都通,才叫真的会了。

8. 给正在做 PG 主从的人几点心得

根据这些年的实战经验,最后分享几个比较零碎但实用的心得。

第一,不要被“开不开归档”这个问题带偏。你真正要关心的是:如果主库瞬间宕机,你能不能在一个可接受的时间内恢复业务,并尽可能少丢数据。不开归档的主从复制,只是“看起来有容灾”,本质上它的恢复能力是打折的。所以只要条件允许,我都建议在生产环境把归档打开,并且有意识地做定期的恢复演练,别等事故来了才后悔。

第二,WAL 日志是 PG 的高可用命脉。无论是流复制、归档、还是 PITR,都围绕 WAL 做文章。平时多花点时间弄懂 WAL 的生成、切换、回收机制,比背一万个参数都管用。有时候排障排到最后,就是看 WAL 有没有被清、备库能不能拿到对应的 WAL。再直白一点,PG 的高可用问题,十有八九就是 WAL 的问题。

第三,监控比配置更重要。主从复制配完之后,一定要有告警盯着pg_stat_replication这个视图。延迟告警、连接断了告警、备库追上不告警,这些都是最基本的。配置再完美,没有监控,故障来了你仍然是被动的。

第四,做切换演练时,别在业务高峰期搞。选一个业务低峰窗口,提前通知相关团队,模拟主库故障,演练备库接管、旧主库回切全流程。每季度甚至每月做一次,你会发现流程里隐藏的坑不下三个。

第五,如果团队规模不大,尽量用现成的开源高可用工具,比如 Patroni 加上 etcd 或者 ZooKeeper,把自动故障切换这件事交给成熟方案,而不是自己写脚本。但用工具之前,底层这些原生的原理一定要懂,否则工具出了问题,你都不知道怎么排查。

最后再说回标题里的问题:主库不开归档,能进行同步吗?能,流复制真的不需要归档参与。但作为过来人,我想提醒你的是,如果你只追求“复制”这个动作,那不开归档确实够用;但如果你是做生产环境的,请一定认真对待归档这件事。它不会破坏你原有的一主一备架构,反而会在关键时刻救你一把。我见过太多“不开归档反正也没出事”的案例,出事那天,当事人都懊悔到不行。

今天就分享到这里吧,这套思路在 PG 12 到 PG 17 上都通用。有机会再单独聊聊 Patroni 的配置细节和故障切换源码层面的实现。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询