AI 13 问, 全方位理解PG同步逻辑复制槽-完结篇
AI 13 问, 全方位理解PG同步逻辑复制槽
全方位理解PG同步逻辑复制槽, 这个问题要从前面几篇文章说起(这事必须感谢zhijie和传成老师的打脸,不然我还没想到要好好梳理本篇).
因为机制设计得有点复杂, 而且涉及到一些底层机制. 必须完全吃透它, 否则以后遇到问题肯定抓瞎.
只要理解了下面13个问题, 我相信你可以吃透PG同步逻辑复制.
1、主节点如何保障逻辑复制的连续性、可靠性? 2、主节点如何判断要保留哪些可解析逻辑日志的wal、以及对应的catalog version? 3、逻辑复制槽在逻辑复制中起的作用是什么? 4、逻辑复制槽的订阅位置用什么来表示? 如何推进这个订阅位置? 5、当存在物理备库, 并且逻辑复制槽的信息会同步给物理备库时. 逻辑复制槽的订阅位置是通过什么方式同步给物理备库的? 是不是WAL? 6、当存在物理备库, 并且逻辑复制槽的信息会同步给物理备库时. 在此情景下如果主节点挂了, 物理备库被激活为新的主库, 逻辑复制槽failover到新的主库, 这个逻辑复制槽还可用吗? 如果可用, 是通过什么机制保障连续性、可靠性的? 7、当存在物理备库, 并且逻辑复制槽的信息会同步给物理备库时. 物理备库是如何推进逻辑复制槽的订阅位置(对应的WAL和需要的catalog版本)? 物理备库上要保留哪些可解析逻辑日志的wal、以及对应的catalog version? 8、物理备库上要保留的WAL很好理解, 逻辑复制槽推进位置之后的WAL都保留即可. 但是要保留的catalog版本, 与主库有关吗? 换句话说catalog版本是通过wal复制给从库的吗? 如果不是, 那么WAL的同步和catalog的同步步调可能不一致吗? 为什么要开启hot_standby_feedback? 是为了防止主库把从库解析逻辑复制槽对应WAL所需要的catalog旧版本vacuum掉吗? 9、如果主库的逻辑复制槽已经推进到了1234位置点, 备库的逻辑复制槽才推进到123(比1234更旧很多), 此时, 如果主库的autovacuum清理了1234以前解析wal所需的catalog版本, 而且携带这个vacuum信息的wal也同步给了从库, 从库也apply了这个wal. 如果此时从库激活成新的主库, 还可以从逻辑复制槽这个123的位置正常解析出WAL的逻辑数据吗? 10、设计同步逻辑复制槽的目的是什么? 11、同步逻辑复制槽采用了什么机制来达到它的设计目的? 12、由于逻辑复制槽的位点同步并不是通过WAL来进行, 而是直接通过连接主库查询SQL得到, 因此还可能出现一种情况, 物理备库同步到的WAL比主库逻辑复制槽被消费的WAL位置更早. 这种情况如果物理备库激活成新的主库, 那么这个逻辑复制槽也不可用. 数据库采用了什么机制避免这种情况发生? 13、如果配置了synchronized_standby_slots, 意味着这里面的任意物理从库出现复制延迟, 都有可能影响WAL的逻辑订阅?
https://deepwiki.com/search/_ac32b438-f971-4838-830b-ab0f14b2e396?mode=fast
AI 的回答给我惊掉了下巴!
1、主节点如何保障逻辑复制的连续性、可靠性?
主节点通过复制槽、故障转移机制、WAL流式传输和同步复制等多种机制保障逻辑复制的连续性和可靠性。
核心保障机制
复制槽机制
复制槽是保障逻辑复制连续性的核心组件,它防止主节点删除订阅者尚未接收的WAL段 。每个逻辑复制槽都有唯一的标识符,并且是崩溃安全的 。
故障转移支持
通过启用failover=true参数,主节点的逻辑复制槽可以同步到物理备节点,确保在主节点故障后订阅者能够从新的主节点继续复制 。备节点通过sync_replication_slots参数自动同步这些故障转移槽 。
WAL流式传输
逻辑复制基于WAL流式传输,主节点的WAL发送进程将WAL记录连续传输给订阅者 。这确保了数据变更的可靠传输。
可靠性增强机制
同步复制
主节点支持同步复制模式,事务提交会等待备节点确认接收WAL记录,提供更强的数据一致性保证 。
冲突检测和处理
系统提供冲突检测机制,当检测到冲突时会记录详细的错误信息,包括冲突类型和相关LSN,便于管理员进行处理 。
监控和验证
主节点提供多种监控视图(如pg_replication_slots、pg_stat_replication)来监控复制状态和延迟 。在故障转移前,可以通过SQL查询验证所有必要的复制槽是否已同步到备节点 。
Notes
复制槽可能导致WAL文件积累过多,需要通过 max_slot_wal_keep_size参数限制保留的WAL文件大小逻辑复制槽在备节点上的同步需要确保所需的WAL和系统目录行仍然可用,否则同步可能失败 只有在备节点上达到 synced=true状态的持久化槽才能在故障转移后用于逻辑复制
2、主节点如何判断要保留哪些可解析逻辑日志的wal、以及对应的catalog version?
主节点通过复制槽的restart_lsn和catalog_xmin机制来判断需要保留哪些WAL日志和对应的系统目录版本。
WAL保留判断机制
复制槽的LSN计算
主节点通过ReplicationSlotsComputeLogicalRestartLSN()函数计算所有逻辑复制槽需要保留的最老WAL位置 。该函数遍历所有逻辑复制槽,获取每个槽的restart_lsn,对于持久化槽还会考虑last_saved_restart_lsn以防止崩溃后数据丢失 。
WAL保留设置
当创建逻辑复制槽时,ReplicationSlotReserveWal()函数会设置槽的restart_lsn并立即调用ReplicationSlotsComputeRequiredLSN()来防止WAL被删除 。对于逻辑槽,还会记录一个standby快照以确保解码能够快速启动 。
Catalog版本保留机制
安全事务ID计算
在创建逻辑解码上下文时,CreateInitDecodingContext()函数通过GetOldestSafeDecodingTransactionId()获取一个安全的事务ID边界,确保从该点开始的解码不会遇到已被清理的行 。这个值被设置为槽的catalog_xmin和effective_catalog_xmin。
并发保护
计算catalog_xmin时需要获取ProcArrayLock锁来防止其他后端同时计算新的xmin边界,确保计算结果的有效性 。
数据结构支持
复制槽结构中包含关键字段来跟踪保留需求:
restart_lsn: 需要保留的最早WAL位置catalog_xmin: 系统目录的保留事务ID边界effective_catalog_xmin: 实际生效的catalog_xmin,用于防止VACUUM清理必要的行
Notes
主节点通过 XLogSetReplicationSlotMinimumLSN()设置全局的WAL保留最小LSN逻辑解码从槽的 restart_lsn开始读取WAL,确保能够重建完整的事务上下文如果所需的WAL或系统目录行已被清理,复制槽会被标记为无效状态
3、逻辑复制槽在逻辑复制中起的作用是什么?
逻辑复制槽在逻辑复制中起着核心的桥梁和状态管理作用,主要体现在以下几个方面:
核心作用概述
逻辑复制槽是逻辑复制系统的关键组件,它作为发布者和订阅者之间的数据流标识符,确保数据变更的可靠传输和状态跟踪 。
主要功能
1. 变更流管理
复制槽代表一个可以从发布者重放到客户端的变更序列,每个槽从单个数据库流式传输变更 。槽确保每个变更在正常操作中只发送一次 。
2. 资源保护机制
复制槽防止WAL和系统目录行的过早删除,这些资源是逻辑解码所必需的 。这是通过槽的restart_lsn和catalog_xmin字段实现的 。
3. 状态持久化
复制槽独立于使用它们的连接而持久存在,并且是崩溃安全的 。槽的状态数据存储在$PGDATA/pg_replslot/目录下的专用文件中 。
4. 故障转移支持
通过failover=true参数,逻辑复制槽可以同步到物理备节点,确保在主节点故障后逻辑复制能够继续 。
技术实现
槽的生命周期管理
复制槽的创建、获取、释放和删除操作通过专门的锁机制进行保护,确保并发访问的安全性 。
多消费者支持
单个数据库可以存在多个独立的复制槽,每个槽都有自己的状态,允许不同的消费者从数据库变更流的不同点接收变更 。
Notes
复制槽可能导致磁盘空间问题,因为它们会阻止WAL清理,不再需要的槽应该被删除 逻辑复制槽对接收者的状态一无所知,甚至可以在不同时间由多个不同的接收者使用同一个槽 每个订阅都会通过一个复制槽接收变更,额外的复制槽可能用于初始数据同步
4、逻辑复制槽的订阅位置用什么来表示? 如何推进这个订阅位置?
逻辑复制槽的订阅位置主要通过LSN(Log Sequence Number)来表示和跟踪。
订阅位置的表示
confirmed_flush_lsn字段
逻辑复制槽使用confirmed_flush_lsn字段来表示订阅者已确认接收数据的位置 。这个LSN之前的所有事务数据已被订阅者确认接收,对应的数据不再可用 。
数据结构中的存储
在ReplicationSlot结构体中,这个位置存储在data.confirmed_flush字段中 ,同时还有last_saved_confirmed_flush来跟踪上次刷新到磁盘的位置 。
订阅位置的推进机制
1. 自动推进机制
当使用pg_logical_slot_get_changes()函数获取变更时,会自动调用LogicalConfirmReceivedLocation()来推进位置 。该函数确保位置只能向前推进,防止数据重复 。
2. 手动推进机制
可以通过pg_replication_slot_advance()函数手动推进槽位置 。该函数会:
检查目标位置不能小于当前最小位置 根据槽类型调用相应的推进函数 重新计算所有槽的最小LSN和xmin
3. 推进过程中的保护机制
系统会防止位置向后推进,以避免数据重复问题 。同时,推进操作会标记槽为脏状态,确保在下次检查点时持久化到磁盘 。
Notes
逻辑槽的位置推进是崩溃安全的,但在崩溃后可能会回到检查点时的位置,导致部分数据重复 pg_logical_slot_peek_changes()函数可以查看变更但不推进位置对于故障转移槽,位置推进需要等待所有同步的物理槽确认接收WAL
5、当存在物理备库, 并且逻辑复制槽的信息会同步给物理备库时. 逻辑复制槽的订阅位置是通过什么方式同步给物理备库的? 是不是WAL?
逻辑复制槽的订阅位置不是通过WAL本身同步的,而是通过专门的槽同步机制,使用SQL查询从主库获取槽的元数据信息。
同步机制概述
物理备库通过槽同步工作进程(slot sync worker)或手动调用pg_sync_replication_slots()函数来同步逻辑复制槽信息 。
具体同步方式
1. SQL查询获取槽信息
备库连接到主库后,执行SQL查询获取逻辑复制槽的元数据:
SELECT slot_name, plugin, confirmed_flush_lsn,
restart_lsn, catalog_xmin, two_phase, two_phase_at, failover,
database, invalidation_reason
FROM pg_catalog.pg_replication_slots
WHEREfailoverandNOTtemporary
这个查询在synchronize_slots()函数中执行 。
2. 位置信息同步
查询结果包含了关键的订阅位置信息:
confirmed_flush_lsn: 订阅者已确认接收的位置restart_lsn: 需要保留的WAL起始位置catalog_xmin: 系统目录保留的事务ID边界
3. 本地槽更新
备库根据获取的信息更新本地同步槽的状态,确保本地槽的confirmed_flush_lsn与主库保持一致 。
同步验证机制
系统会验证远程槽的confirmed_lsn不能超过备库的当前刷新位置,防止数据丢失 。
Notes
这种同步方式需要备库配置 sync_replication_slots = on和hot_standby_feedback = on同步过程通过WAL receiver连接建立,但传输的是槽的元数据而非WAL记录本身 只有标记为 failover=true的逻辑复制槽才会被同步
6、当存在物理备库, 并且逻辑复制槽的信息会同步给物理备库时. 在此情景下如果主节点挂了, 物理备库被激活为新的主库, 逻辑复制槽failover到新的主库, 这个逻辑复制槽还可用吗? 如果可用, 是通过什么机制保障连续性、可靠性的?
在主节点故障、物理备库被激活为新主库的情况下,逻辑复制槽是可用的,但需要满足特定条件并通过专门的机制来保障连续性和可靠性。
故障转移后的可用性
逻辑复制槽在故障转移后仍然可用,但必须满足关键条件:只有那些在备库上达到synced=true状态的持久化槽才能在故障转移后用于逻辑复制 。临时的同步槽无法用于逻辑解码,因此逻辑复制无法从这些槽恢复 。
连续性和可靠性保障机制
1. 槽状态管理和验证
系统通过pg_replication_slots视图的synced字段来标识槽的同步状态 。在故障转移前,可以通过SQL查询验证所有必要的复制槽是否已正确同步到备库 。
2. WAL和系统目录保护
槽同步机制确保逻辑复制槽在主库上保留必要的WAL和系统目录行,这些资源在备库上仍然可用 。如果所需的WAL或目录行已被清理,同步将失败以防止数据丢失 。
3. 配置要求保障
为确保故障转移成功,需要满足以下配置要求:
备库启用 sync_replication_slots = on启用 hot_standby_feedback = on配置物理复制槽并在 synchronized_standby_slots中指定
4. 实际故障转移流程
测试文件展示了完整的故障转移验证流程:
创建带failover选项的逻辑复制槽 备库同步槽并验证synced状态 提升备库为新主库 验证同步槽在新主库上保留并可用 更新订阅连接信息以指向新主库
5. 数据一致性保障
通过synchronized_standby_slots配置,主节点会等待指定的物理备库确认接收WAL后,才向逻辑订阅者发送解码变更,确保逻辑复制不会超过物理备库的进度 。
Notes
故障转移后需要使用 ALTER SUBSCRIPTION ... CONNECTION命令更新订阅的连接信息指向新主库建议在提升备库前先禁用订阅,提升完成后再重新启用,以避免数据不一致问题 槽同步工作进程会定期同步槽信息,确保备库上的槽状态与主库保持一致
7、当存在物理备库, 并且逻辑复制槽的信息会同步给物理备库时. 物理备库是如何推进逻辑复制槽的订阅位置(对应的WAL和需要的catalog版本)? 物理备库上要保留哪些可解析逻辑日志的wal、以及对应的catalog version?
物理备库通过槽同步机制来推进逻辑复制槽的订阅位置,并根据同步状态保留相应的WAL和catalog版本。
物理备库的订阅位置推进机制
槽同步过程
物理备库通过槽同步工作进程或手动调用pg_sync_replication_slots()函数来同步逻辑复制槽信息 。同步过程通过SQL查询从主库获取槽的元数据:
SELECT slot_name, plugin, confirmed_flush_lsn,
restart_lsn, catalog_xmin, two_phase, two_phase_at, failover,
database, invalidation_reason
FROM pg_catalog.pg_replication_slots
WHEREfailoverandNOTtemporary
这个查询在synchronize_slots()函数中执行 。
位置推进验证
备库会验证远程槽的confirmed_lsn不能超过备库的当前刷新位置,防止数据丢失 。验证通过后,备库会更新本地同步槽的状态,确保本地槽的confirmed_flush_lsn与主库保持一致 。
WAL和Catalog版本保留策略
保留条件判断
物理备库只有在满足特定条件时才会持久化同步的槽:
主库上的逻辑复制槽必须保留WAL和系统目录行,这些资源在备库上仍然可用 如果所需的WAL或目录行已被清理,同步将失败以防止数据丢失
槽状态管理
同步槽在备库上有两种状态:
RS_TEMPORARY:当WAL不可用或catalog_xmin过早时的临时状态 RS_PERSISTENT:当条件满足时的持久化状态,表示槽已准备好用于故障转移
需要保留的资源
物理备库需要保留:
WAL资源:从 restart_lsn开始的所有WAL记录,确保逻辑解码能够重建完整的事务上下文Catalog版本:通过 catalog_xmin确定的系统目录行版本,防止VACUUM清理必要的元数据
连续性保障机制
配置要求
为确保同步成功,需要配置:
sync_replication_slots = on:启用槽同步功能hot_standby_feedback = on:防止主库清理备库仍需要的catalog行synchronized_standby_slots:确保逻辑复制不会超过物理备库进度
状态验证
只有达到synced=true状态的持久化槽才能在故障转移后用于逻辑复制 。临时的同步槽无法用于逻辑解码。
Notes
物理备库通过定期同步机制保持槽状态与主库一致,同步间隔根据槽更新情况动态调整 如果同步失败,系统会记录详细的错误信息,包括所需的LSN和catalog xmin与备库实际状态的对比 测试用例展示了完整的同步和故障转移流程,验证了机制的可靠性
8、物理备库上要保留的WAL很好理解, 逻辑复制槽推进位置之后的WAL都保留即可. 但是要保留的catalog版本, 与主库有关吗? 换句话说catalog版本是通过wal复制给从库的吗? 如果不是, 那么WAL的同步和catalog的同步步调可能不一致吗? 为什么要开启hot_standby_feedback? 是为了防止主库把从库解析逻辑复制槽对应WAL所需要的catalog旧版本vacuum掉吗?
物理备库上保留的catalog版本确实与主库密切相关,并且通过特定的反馈机制保持同步。
Catalog版本同步机制
Catalog版本不是通过WAL直接复制的
Catalog版本本身不是通过WAL记录直接复制给从库的。相反,物理备库通过hot_standby_feedback机制向主库报告自己的catalog_xmin需求 。
Hot Standby Feedback的工作原理
备库的WAL receiver进程定期发送hot standby feedback消息给主库,包含:
xmin: 备库需要的最老事务IDcatalog_xmin: 备库逻辑解码需要的最老catalog事务ID
主库收到这些反馈后,会确保不会清理比这些xmin更早的行版本。
WAL与Catalog同步的一致性保障
同步步调一致性
WAL同步和catalog同步是协调进行的:
WAL通过物理流式复制保持同步 Catalog版本通过hot standby feedback机制保护 只有当备库的Hot Standby处于活跃状态时才会发送反馈
配置要求验证
槽同步机制强制要求启用hot_standby_feedback,否则同步无法进行 。这确保了catalog版本保护机制始终生效。
Hot Standby Feedback的核心作用
防止Catalog清理
开启hot_standby_feedback的主要目的确实是防止主库的VACUUM进程清理掉备库逻辑解码所需的catalog旧版本 。
保护机制说明
当备库上有逻辑复制槽时,需要特定的系统目录版本来正确解码WAL中的变更 如果没有hot standby feedback,主库可能清理这些catalog行 一旦catalog行被清理,备库上的逻辑解码就会失败,槽会被标记为无效
Notes
如果没有物理复制槽,hot standby feedback只在连接存活期间有效,节点重启会中断保护 测试显示启用hot_standby_feedback后,物理槽的catalog_xmin会被正确设置 这种机制确保了WAL和catalog版本保护的协调性,避免了同步步调不一致的问题
9、如果主库的逻辑复制槽已经推进到了1234位置点, 备库的逻辑复制槽才推进到123(比1234更旧很多), 此时, 如果主库的autovacuum清理了1234以前解析wal所需的catalog版本, 而且携带这个vacuum信息的wal也同步给了从库, 从库也apply了这个wal. 如果此时从库激活成新的主库, 还可以从逻辑复制槽这个123的位置正常解析出WAL的逻辑数据吗?
在这种情况下,从库激活为新主库后无法从逻辑复制槽的123位置正常解析WAL逻辑数据。
核心问题分析
当主库的autovacuum清理了1234位置以前解析WAL所需的catalog版本后,即使备库接收并应用了包含vacuum信息的WAL,这些catalog行在备库上也同样被清理了 。
失败机制
Catalog版本依赖
逻辑解码需要特定的系统目录版本来正确解析WAL中的变更 。如果所需的catalog行已被清理,解码过程会失败。
槽状态验证
在槽同步过程中,系统会验证远程槽的catalog_xmin需求与备库实际状态的匹配性 。如果备库的catalog xmin比主库槽需要的更新,同步会失败。
错误处理
当检测到catalog版本不匹配时,系统会记录类似以下的错误信息:
LOG: could not synchronize replication slot "failover_slot"
DETAIL: Synchronization could lead to data loss, because the remote slot needs WAL at LSN 0/03003F28 and catalog xmin 754, but the standby has LSN 0/03003F28 and catalog xmin 756.
预防机制
Hot Standby Feedback的作用
这正是为什么必须启用hot_standby_feedback的原因 。该机制防止主库清理备库逻辑解码所需的catalog旧版本。
配置要求
槽同步机制强制要求以下配置来避免此类问题:
hot_standby_feedback = on:保护catalog版本物理复制槽:确保持久化保护
结果
在这种情况下,逻辑复制槽会被标记为无效状态,invalidation_reason会显示为rows_removed 。无法从位置123进行逻辑解码,需要重新创建复制槽。
Notes
测试用例展示了当catalog版本被清理时,逻辑复制槽会被标记为无效且无法用于解码 这就是为什么故障转移前必须验证槽的 synced状态为true的原因只有当WAL和catalog版本都可用时,槽才能达到持久化状态用于故障转移
10、设计同步逻辑复制槽的目的是什么?
设计同步逻辑复制槽的主要目的是实现逻辑复制的高可用性和故障转移能力。
核心设计目的
1. 实现逻辑复制的高可用性
同步逻辑复制槽确保在主节点故障后,逻辑复制订阅者能够无缝切换到新的主节点继续复制,而不需要重新创建订阅或进行完整的数据同步 。
2. 防止数据丢失
通过将逻辑复制槽的状态同步到物理备库,确保在故障转移时不会丢失任何已提交的事务数据。槽同步机制保证备库上有完整的WAL和系统目录版本来支持逻辑解码 。
3. 自动化故障转移流程
同步机制减少了故障转移时的人工干预需求。通过sync_replication_slots参数,备库可以自动定期同步槽状态,无需手动操作 。
技术实现保障
状态一致性保障
系统通过confirmed_flush_lsn、restart_lsn和catalog_xmin等关键指标确保槽状态在主备之间保持一致 。
资源保护机制
通过hot_standby_feedback和synchronized_standby_slots配置,确保主库不会清理备库逻辑解码所需的资源 。
可靠性验证
只有达到synced=true状态的持久化槽才能在故障转移后使用,确保了机制的可靠性 。
Notes
同步逻辑复制槽是PostgreSQL 17+版本引入的重要高可用特性 需要物理复制槽作为基础,不支持级联备库的槽同步 测试用例验证了完整的故障转移流程,确保机制的实用性
11、同步逻辑复制槽采用了什么机制来达到它的设计目的?
设计同步逻辑复制槽的主要目的是实现逻辑复制的高可用性和故障转移能力。
核心设计目的
1. 实现逻辑复制的高可用性
同步逻辑复制槽确保在主节点故障后,逻辑复制订阅者能够无缝切换到新的主节点继续复制,而不需要重新创建订阅或进行完整的数据同步 。
2. 防止数据丢失
通过将逻辑复制槽的状态同步到物理备库,确保在故障转移时不会丢失任何已提交的事务数据。槽同步机制保证备库上有完整的WAL和系统目录版本来支持逻辑解码 。
3. 自动化故障转移流程
同步机制减少了故障转移时的人工干预需求。通过sync_replication_slots参数,备库可以自动定期同步槽状态,无需手动操作 。
技术实现保障
状态一致性保障
系统通过confirmed_flush_lsn、restart_lsn和catalog_xmin等关键指标确保槽状态在主备之间保持一致 。
资源保护机制
通过hot_standby_feedback和synchronized_standby_slots配置,确保主库不会清理备库逻辑解码所需的资源 。
可靠性验证
只有达到synced=true状态的持久化槽才能在故障转移后使用,确保了机制的可靠性 。
Notes
同步逻辑复制槽是PostgreSQL 17+版本引入的重要高可用特性 需要物理复制槽作为基础,不支持级联备库的槽同步 测试用例验证了完整的故障转移流程,确保机制的实用性
同步逻辑复制槽通过多种协调机制来实现其高可用性和故障转移的设计目的。
核心同步机制
1. 槽同步工作进程机制
物理备库通过专门的槽同步工作进程(slot sync worker)自动定期同步逻辑复制槽信息 。该进程负责从主库获取槽元数据并在本地创建或更新同步槽。
2. SQL查询获取槽元数据
同步过程通过执行SQL查询从主库获取逻辑复制槽的完整状态信息:
SELECT slot_name, plugin, confirmed_flush_lsn,
restart_lsn, catalog_xmin, two_phase, two_phase_at, failover,
database, invalidation_reason
FROM pg_catalog.pg_replication_slots
WHEREfailoverandNOTtemporary
这个查询在synchronize_slots()函数中执行 。
3. 状态管理和验证机制
槽状态转换
同步槽在备库上有两种关键状态:
RS_TEMPORARY:初始状态,当WAL或catalog版本不可用时 RS_PERSISTENT:持久化状态,表示槽已准备好用于故障转移
一致性验证
系统会验证远程槽的confirmed_lsn不能超过备库的当前刷新位置,防止数据丢失 。同时检查catalog_xmin的匹配性,确保解码所需的系统目录版本仍然可用。
4. 资源保护机制
Hot Standby Feedback
通过hot_standby_feedback机制,备库向主库报告自己的catalog_xmin需求,防止主库清理备库逻辑解码所需的catalog旧版本 。
Synchronized Standby Slots
通过synchronized_standby_slots配置,主节点会等待指定的物理备库确认接收WAL后,才向逻辑订阅者发送解码变更,确保逻辑复制不会超过物理备库的进度 。
5. 配置要求和验证
强制配置检查
槽同步机制强制要求以下配置:
sync_replication_slots = on:启用槽同步功能hot_standby_feedback = on:保护catalog版本物理复制槽:确保持久化保护
参数验证函数
ValidateSlotSyncParams()函数确保所有必需的配置参数都已正确设置 。
6. 故障转移保障机制
Synced状态验证
只有达到synced=true状态的持久化槽才能在故障转移后用于逻辑复制 。这确保了只有真正同步完成的槽才能用于故障转移。
测试验证
测试用例展示了完整的故障转移流程,验证了从槽创建、同步到故障转移的整个过程 。
Notes
同步逻辑复制槽是PostgreSQL 17+版本引入的重要高可用特性 不支持级联备库的槽同步 手动同步函数 pg_sync_replication_slots()主要用于测试和调试
12、由于逻辑复制槽的位点同步并不是通过WAL来进行, 而是直接通过连接主库查询SQL得到, 因此还可能出现一种情况, 物理备库同步到的WAL比主库逻辑复制槽被消费的WAL位置更早. 这种情况如果物理备库激活成新的主库, 那么这个逻辑复制槽也不可用. 数据库采用了什么机制避免这种情况发生?
数据库通过synchronized_standby_slots机制和相关的等待确认逻辑来避免物理备库WAL滞后于逻辑复制槽消费位置的情况。
核心防护机制
synchronized_standby_slots配置
主库通过synchronized_standby_slots参数指定需要等待的物理复制槽列表 。逻辑WAL发送进程只有在这些物理槽确认接收WAL后,才会向逻辑订阅者发送解码变更。
等待确认机制
WaitForStandbyConfirmation()函数确保逻辑解码操作会等待所有指定的物理备库确认接收WAL 。该函数通过StandbySlotsHaveCaughtup()检查物理槽是否已追赶到指定位置 。
同步验证逻辑
在槽同步过程中,synchronize_one_slot()函数会验证远程槽的confirmed_lsn不能超过备库的当前刷新位置 。如果检测到不一致,会跳过同步并记录警告。
具体实现流程
1. 逻辑复制槽推进时的等待
当使用pg_logical_slot_get_changes()或pg_replication_slot_advance()操作逻辑故障转移槽时,系统会自动调用WaitForStandbyConfirmation()等待物理备库确认 。
2. 物理槽状态检查
StandbySlotsHaveCaughtup()函数会检查每个指定的物理槽:
槽是否存在且有效 槽的 restart_lsn是否已达到等待位置槽是否处于活跃状态
3. 配置强制要求
系统强制要求配置synchronized_standby_slots才能使用故障转移槽,确保防护机制始终生效 。
测试验证
测试用例展示了该机制的实际效果:当物理备库停止时,启用了failover的逻辑订阅不会接收到数据,直到物理备库重新启动并追赶上进度 。
Notes
该机制确保逻辑复制的消费进度永远不会超过物理备库的WAL接收进度 如果指定的物理槽不存在或无效,逻辑复制会暂停并等待问题解决 这是PostgreSQL 17+版本引入的关键高可用特性,专门解决用户描述的潜在数据丢失问题
13、如果配置了synchronized_standby_slots, 意味着这里面的任意物理从库出现复制延迟, 都有可能影响WAL的逻辑订阅?
是的,如果配置了synchronized_standby_slots,其中任意一个物理从库出现复制延迟,都会影响WAL的逻辑订阅。
核心机制
synchronized_standby_slots参数指定了需要等待的物理复制槽列表,逻辑WAL发送进程只有在这些物理槽都确认接收WAL后,才会向逻辑订阅者发送解码变更 。
等待确认逻辑
WaitForStandbyConfirmation函数
当操作逻辑故障转移槽时,WaitForStandbyConfirmation()函数会等待所有指定的物理备库确认接收WAL 。该函数通过循环检查直到所有物理槽都追赶到指定位置。
StandbySlotsHaveCaughtup检查
StandbySlotsHaveCaughtup()函数会检查每个指定的物理槽状态 :
槽是否存在且有效 槽的 restart_lsn是否已达到等待位置槽是否处于活跃状态
如果任意一个物理槽未满足条件,函数返回false,逻辑复制将继续等待。
实际影响
测试验证
测试用例展示了这种机制的实际效果:当物理备库停止时,启用了failover的逻辑订阅不会接收到数据,直到物理备库重新启动并追赶上进度 。
错误处理
如果指定的物理槽不存在、无效或出现延迟,系统会记录警告信息并暂停逻辑复制 。
设计目的
这种"等待最慢节点"的设计是为了确保故障转移时的数据一致性。通过保证逻辑复制的消费进度永远不会超过物理备库的WAL接收进度,避免了在故障转移时出现数据丢失的情况 。
Notes
这是PostgreSQL 17+版本引入的关键高可用特性 如果某个物理从库长期不可用,可能需要从 synchronized_standby_slots中移除该槽以恢复逻辑复制该机制确保了故障转移的可靠性,但可能影响逻辑复制的实时性