主备复制
主备复制由主节点确定写入顺序,再向备节点传播。本文负责确认时机、日志追赶、快照与读取新鲜度。
1. 面试核心
先记住这几条,再读正文- 写入顺序。 主节点排序写入,备节点按日志顺序应用确定性变化。
- 异步确认窗口。 异步本地确认存在未复制窗口,永久失去主节点时会丢数据。
- 复制进度阶段。 副本收到、持久化和应用日志是三个不同阶段。卡 · 日志接收与回放
- 副本初始化。 新副本加载一致快照,再追赶快照位置之后的日志。
- 安全切换。 安全切换需保留已确认写入,并隔离旧主的写入能力。卡 · 综合题
2. 写入顺序
客户端把写请求交给主节点。主节点分配日志位置或版本,备节点按顺序应用。状态机使用相同输入,才能获得相同结果。
复制设计要明确写入权、确认条件、追赶和接管规则。MySQL、Redis 与共识系统具有不同保证。角色名称本身无法证明数据安全。
3. 写入确认时机
本地确认延迟较低,但未复制写入会随主节点永久故障丢失。等待备节点确认可缩小风险窗口。确认的具体含义仍需明确。
多数派共识还把确认规则与安全选举连接起来。等待所有副本则会受最慢副本和故障副本影响。
3.1 日志接收与回放
备节点收到日志后,还需写入持久存储,再回放到状态。日志已落盘而尚未回放时,备节点查询仍会读到旧值。
PostgreSQL 18 配置同步备库后,synchronous_commit 有以下区别:
| 配置 | 远端确认条件 |
|---|---|
| remote_write | 备库已写入操作系统,未要求刷新到持久存储。 |
| on | 同步备库已把 WAL 刷到持久存储。 |
| remote_apply | 同步备库已回放事务,查询可见其结果。 |
这些远端等待要求 synchronous_standby_names 指定同步备库。remote_write 可应对备库进程退出,仍受操作系统崩溃影响。remote_apply 增加等待,但所等待副本可立即读取该事务。
读取路由若指向其他异步副本,仍需检查它的回放位置。
4. 日志复制
主节点向备节点发送有序日志:

时间、随机数和外部调用结果应成为明确输入。否则,各副本重新计算时会产生不同结果。
日志位置用于发现缺口和重复。冲突分支按具体协议修复。已提交前缀由提交与切换规则保护。
5. 快照
快照保存某个日志位置对应的状态。新副本无需从最早日志重放:

快照与增量需要衔接。备节点安装快照后,从对应位置继续追赶。传输期间产生的新日志必须仍可取得。
快照压缩历史,日志传播后续变化。读取一致性由确认、读取和切换协议共同决定。
6. 故障切换
失联检测负责发现问题,写入协议负责裁决权限。候选节点需包含协议要求保留的写入。新任期或 fencing 需阻止旧主继续修改。
异步复制无法凭空恢复尚未传播的数据。若目标副本缺失这部分内容,应明确数据损失边界。执行流程见故障转移。
7. 复制延迟
复制延迟来自网络、磁盘和回放速度。普通展示可接受旧值。写后读可选择有效主节点,或等待指定副本追到提交位置。
权限与余额判断需要明确的新鲜度保证。位置差、时间滞后、积压和追平速度都应监控。复制停止时,旧采样的低延迟值会失去参考意义。
8. 恢复验证
切换后核对新主数据与已确认请求。旧主重新加入前隔离冲突分支,并按产品恢复流程处理。客户端缓存和长连接也要迁移。
消息、搜索和缓存等派生结果通过重放或对账恢复。故障演练需同时验证数据目标和业务恢复时间。
9. 常见问题
9.1 副本数量与数据安全
数据安全取决于确认位置、持久性和候选选择。副本多但全部落后时,最近写入仍存在风险。
9.2 备节点读取的新鲜度
备节点能提供哪类读,由回放位置与读协议决定。等待自己的写入位置可满足读己之写。线性读取还需本次请求的安全依据。
10 · 面试题卡片
本页题目与参考回答
10.1 主节点故障后,怎样保证新主不丢失已提交数据并避免双主
题型:综合题
考察重点
- 写入确认、日志提交与副本追赶。
- 多数派选举、任期和 fencing。
- 快照、故障恢复和数据验证。
参考回答
新主必须保留已确认写入,并隔离旧主的写入能力,才能同时避免数据丢失和双主修改。
写入确认条件必须与新主选择规则配套。只在旧主本地确认的异步复制存在丢失窗口;共识复制则通过安全提交和选举保留已提交前缀。
副本通过快照与日志追平,新主接管前隔离旧写入权。切换后核对已确认请求、旧连接和业务状态,实际保证以所用复制协议为准。
10.2 同步复制已经确认成功,为什么读取备库仍可能得到旧值?
考察重点:接收、持久化、回放与读取路由。
相关内容:日志接收与回放。
参考回答
同步确认可只等待日志持久化,备库尚未回放时仍会读到旧值。
PostgreSQL 18 配置同步备库后,synchronous_commit=on 等待远端 WAL 持久化。synchronous_commit=remote_apply 还等待事务回放。读取其他异步副本时,仍需等待其追平。