物理与逻辑复制与认证与 WAL

共 20 题
📑 题目列表 20 题
#
★★★

1. PostgreSQL 物理复制(Physical Replication),WAL 流复制?

请解释 PostgreSQL 物理复制机制,特别是基于 WAL 的流复制是如何工作的?

  • 物理复制的原理
  • WAL 流复制流程
  • 主从一致性

物理复制是把主库生成的 WAL(write-ahead log)记录原样传输到备库并重放,从而在备库重建与主库字节级一致的数据库。流复制(streaming replication)通过复制协议(replication protocol)让备库持续接收主库产生的 WAL,代替传统的 WAL 归档文件传输,延迟更低。备库通过 pg_basebackup 初始化后,启动时连接主库的 walsender 进程持续拉取 WAL。物理复制无法在备库上按表/库选择性复制,但支持只读查询与热备(hot standby)。

物理复制是 PG 高可用与只读扩展的基础。它复制整个数据库集群的字节流,机制简单、一致性高,但无法按表/库选择性复制,且备库与主库版本必须一致。

-- 主库创建复制槽(可选)
SELECT * FROM pg_create_physical_replication_slot('slot1');
-- 查看复制状态
SELECT * FROM pg_stat_replication;
#
★★★

2. PostgreSQL 逻辑复制(Logical Replication),publication/subscription?

请解释 PostgreSQL 逻辑复制机制,包括 publication 和 subscription 的使用?

  • 逻辑复制的原理
  • publication/subscription 配置
  • 逻辑复制的应用

逻辑复制以"逻辑变更"为单位复制数据,通过 publication(发布端)定义要复制的表/库,subscription(订阅端)订阅并应用变更。逻辑复制基于 WAL 逻辑解码(默认 pgoutput 插件),将 INSERT/UPDATE/DELETE 翻译为逻辑变更传输给订阅端。与物理复制不同,逻辑复制可跨版本、跨实例、按表复制,支持数据过滤,是数据迁移、数据仓库同步、多活架构的常用方案。配置需在主库设置 wal_level=logical,创建 publication,在订阅端创建 subscription。

逻辑复制灵活但机制复杂,需注意表必须有主键或有效 replica identity(否则 UPDATE/DELETE 无法定位旧行)、DDL 不自动复制、初始数据同步等限制。

-- 主库
CREATE PUBLICATION pub_orders FOR TABLE orders;
-- 备库
CREATE SUBSCRIPTION sub_orders CONNECTION 'host=primary dbname=app'
  PUBLICATION pub_orders;
#
★★★

3. 流复制(Streaming Replication)的搭建,primary/standby?

请说明如何搭建 PostgreSQL 流复制,包括主库(primary)和备库(standby)的配置与步骤?

  • 主库参数配置
  • 备库初始化与启动
  • 复制槽与权限

搭建流复制步骤:主库配置 wal_level=replica/logical、max_wal_senders、wal_keep_size 或复制槽,创建具有 REPLICATION 属性的复制账号,并在 pg_hba.conf 中允许 replication 连接;用 pg_basebackup 从主库建立备库数据目录(PG12+ 自动生成 standby.signal);备库配置 primary_conninfo 指向主库,启动后即可持续流复制。可通过 pg_stat_replication 检查同步状态。生产建议使用复制槽防止 WAL 丢失。

主库的关键是允许复制连接并保留足够 WAL;备库的关键是能用 pg_basebackup 初始化并正确连接主库。复制槽能避免主库 WAL 被过早清理导致备库跟不上。

-- 主库 postgresql.conf
wal_level = replica
max_wal_senders = 10
-- 备库 primary_conninfo(standby 上)
primary_conninfo = 'host=primary port=5432 user=repl'
#
★★★

4. 逻辑复制的 DDL 限制与解决,pgoutput、wal2json?

请说明逻辑复制的 DDL 限制及其解决方案,以及 pgoutput 和 wal2json 的作用?

  • 逻辑复制不复制 DDL
  • pgoutput 与 wal2json 输出插件
  • DDL 变更的应对

逻辑复制默认只复制 DML(INSERT/UPDATE/DELETE),不复制 DDL(如 CREATE/ALTER TABLE),因此表结构变更需 DBA 手动在订阅端同步执行,否则变更后订阅端应用会失败。输出插件用于解码 WAL 为逻辑变更:pgoutput 是 PostgreSQL 内置的默认插件,用于 publication/subscription 之间的标准协议;wal2json 是第三方插件,把变更输出为 JSON 格式,适合接入 CDC 工具、Kafka 等外部系统。解决 DDL 限制的常见做法:维护变更发布流程、用工具(如特定版 pg 的 DDL 逻辑复制或将 ALTER 脚本同步到订阅端)。

DDL 限制是逻辑复制的主要运维难点。理解"逻辑复制只复制 DML"才能设计正确的变更流程。wal2json 因格式灵活适合外部消费,pgoutput 是内部订阅的标准。

#
★★★

5. PostgreSQL 复制与一致性?

请讨论 PostgreSQL 复制与一致性之间的关系,包括同步与异步复制下的一致性保证?

  • 同步复制 vs 异步复制
  • 数据一致性保证
  • 一致性权衡

PostgreSQL 复制的一致性取决于同步模式。异步复制下,主库提交即返回,不等待备库确认,因此存在短暂数据丢失窗口(failover 时可能丢最近提交的 WAL),但写入延迟低;同步复制下,主库等待备库确认 WAL 后才提交,保证提交事务不丢,但增加延迟且受备库可用性影响。可通过 synchronous_standby_names 配置同步备库。synchronous_commit 参数可控制每个事务的同步级别(off、local、remote_write、remote_apply、on)。物理复制保证字节级一致,但逻辑复制在应用层可能因冲突有差异。

"一致性与可用性"的权衡是复制设计的核心。同步复制牺牲吞吐/延迟换 RPO=0,异步复制牺牲 RPO 换性能。理解 synchronous_commit 各级别可精确控制一致性。

#
★★★

6. PostgreSQL 认证方式,trust、md5、scram-sha-256、cert、ldap?

请介绍 PostgreSQL 的认证方式,包括 trust、md5、scram-sha-256、cert 和 ldap?

  • 各认证方式原理
  • 密码加密算法演进
  • 认证方式选择

PostgreSQL 通过 pg_hba.conf 指定各连接来源的认证方式。trust:不验证身份,任何匹配用户可连接,仅限内网/开发环境。md5:密码以 MD5 哈希存储与传输,加密强度弱。scram-sha-256:基于 SCRAM 的强密码认证,密码以 SCRAM 存储,传输过程不泄露明文,是当前推荐方式。cert:基于 SSL 客户端证书验证身份。ldap:通过 LDAP 服务器验证用户名密码,适合企业统一认证。生产环境应使用 scram-sha-256 或 cert/ldap,避免 trust 和 md5。

认证方式直接影响安全性。scram-sha-256 是 PG 10+ 引入的现代密码认证,密码存储为 SCRAM 迭代哈希,比 md5 更安全。公网连接必须用强认证。

#
★★★

7. 逻辑复制为什么要求表有主键或设置 replica identity?没有复制标识时 UPDATE 与 DELETE 如何传输和应用?

请解释逻辑复制为什么要求表有主键或设置 replica identity,以及没有复制标识时 UPDATE 和 DELETE 如何传输应用?

  • replica identity 的作用
  • 无复制标识时的行为
  • 全键与默认复制标识

逻辑复制需要复制标识(replica identity)来定位 UPDATE/DELETE 影响的行。默认(DEFAULT)复制标识使用主键,把变更行的主键值传给订阅端以定位旧行;若表无主键,默认用全部列作为复制标识(FULL),UPDATE/DELETE 时把整行旧值传给订阅端,网络开销大且订阅端需按全列匹配。可通过 ALTER TABLE ... REPLICA IDENTITY 设置 USING INDEX 用唯一索引,或 FULL。若无有效复制标识,逻辑复制无法正确应用 UPDATE/DELETE(会报错或无法定位),因此要求表有主键或显式设置复制标识。

复制标识决定了逻辑复制如何标识和定位变更行。主键(含唯一索引)最高效;FULL 通用但开销大。理解此机制才能正确设计被逻辑复制的表结构。

ALTER TABLE orders REPLICA IDENTITY USING INDEX orders_pkey;
-- 或全列
ALTER TABLE orders REPLICA IDENTITY FULL;
#
★★★

8. WAL 记录与 LSN 如何协同 checkpoint 与崩溃恢复?group commit 如何合并多个事务的 fsync 提升写入吞吐?

请解释 WAL 记录与 LSN 如何协同 checkpoint 与崩溃恢复,以及 group commit 如何合并 fsync 提升写入吞吐?

  • WAL 与 LSN 的作用
  • checkpoint 与崩溃恢复
  • group commit 机制

每条 WAL 记录都有唯一的 LSN(Log Sequence Number)标识其在 WAL 中的位置。事务提交时强制把 WAL flush 到磁盘(fsync),崩溃恢复时从重做点(redo point,即 checkpoint 记录的 LSN)开始重放 WAL 到末尾,恢复未持久化的提交。checkpoint 定期把脏页刷盘并记录 checkpoint LSN,把崩溃恢复起点前移,缩短恢复时间。group commit 把同一时刻多个并发事务的 WAL 提交记录合并为一次 fsync(写一批 WAL 再同步一次),把多个磁盘同步合并为一个,显著提升写吞吐,尤其在 fsync 是昂贵操作时。

WAL 的先写后读(先写日志再改数据)是崩溃恢复的基础。checkpoint 把恢复起点前移减少重放量。group commit 是减小 fsync 开销的关键优化,理解它才能解释 PG 高并发写入性能。

#
★★

9. WAL 归档(archive_mode、archive_command)的应用?

请说明 WAL 归档(archive_mode、archive_command)的配置与应用?

  • archive_mode 与 archive_command
  • WAL 归档的用途
  • 归档监控

WAL 归档用于把已完成的 WAL 段复制到归档存储(如本地目录、对象存储)。配置:设置 archive_mode=on,archive_command 指定归档命令(如 'cp %p /archive/%f',%p 源文件、%f 目标文件名)。归档的用途:支持 PITR(时间点恢复)——结合基础备份+归档 WAL 可恢复到任意时间点;可作为备库的补充数据源。归档失败会阻塞主库 WAL 进度,需监控归档状态(pg_stat_archiver 的 failed_count、last_failed_time)。

WAL 归档是 PITR 和备份策略的核心组件。归档命令必须成功返回 0 才算归档成功,否则会重试并阻塞。合理的归档位置与监控是生产必备。

-- postgresql.conf
archive_mode = on
archive_command = 'cp "%p" /backup/wal/%f'
-- 监控
SELECT * FROM pg_stat_archiver;
#
★★

10. WAL(Write-Ahead Log)的作用与配置,wal_level、max_wal_size?

请说明 WAL(Write-Ahead Log)的作用及其关键配置参数 wal_level 和 max_wal_size?

  • WAL 的作用
  • wal_level 的级别
  • max_wal_size 与 checkpoint

WAL(Write-Ahead Log)是 PostgreSQL 的预写日志,记录所有数据变更,先写日志再改数据,保证崩溃恢复(持久性)与数据一致性。wal_level 决定 WAL 记录的内容与详细程度:minimal(最少,仅崩溃恢复)、replica(支持复制、归档,默认)、logical(支持逻辑解码,用于逻辑复制)。max_wal_size 控制 checkpoint 触发前 WAL 可增长到的目标大小,影响 checkpoint 频率和 WAL 峰值占用;设置过大减少 checkpoint 次数但恢复时间变长、占用磁盘多,过小则 checkpoint 频繁。

WAL 是事务持久性与复制的基础。wal_level 需按是否使用复制/逻辑解码选择,logical 比 replica 记录更多信息。max_wal_size 与 checkpoint 频率、恢复时间、磁盘占用相关,需权衡。

#
★★

11. WAL 接收与回放,pg_receivewal、pg_basebackup?

请说明 WAL 接收与回放工具,包括 pg_receivewal 和 pg_basebackup 的作用?

  • pg_receivewal 的用途
  • pg_basebackup 的用途
  • 回放与恢复

pg_basebackup 用于从主库创建基础备份(拷贝整个数据目录),是搭建备库和创建备份的基础工具,可与 WAL 归档配合实现 PITR。pg_receivewal 用于持续接收主库的 WAL 流并写入本地,可把 WAL 实时归档到独立存储,作为 archive_command 的补充或替代,适合需要持续 WAL 归档的场景。回放(replay)指备库或恢复过程把 WAL 应用到数据页,通过自动恢复完成。

pg_basebackup 提供一致性基础备份,pg_receivewal 提供持续 WAL 归档。二者结合可构建完善的备份与恢复体系。pg_receivewal 相比 archive_command 更实时、不依赖归档命令返回。

#
★★

12. pg_hba.conf 的配置规则,host、database、user、address、auth-method?

请解释 pg_hba.conf 的配置规则,包括 host、database、user、address、auth-method 字段?

  • pg_hba.conf 的字段含义
  • 匹配顺序规则
  • 认证配置

pg_hba.conf(PostgreSQL host-based authentication)定义客户端认证规则,每条记录包含:连接类型(local 为 socket、host 为 TCP/IP)、database(允许的数据库,可用逗号或 all)、user(允许的用户,all 表示任意)、address(客户端 IP 或 CIDR,如 192.168.1.0/24)、auth-method(认证方式,如 trust、md5、scram-sha-256、cert、reject 等)。规则按文件从上到下匹配,第一条匹配生效,不匹配则继续。常在其后追加 replication 条目以允许复制连接。

pg_hba.conf 是连接安全的第一道门。注意"从上到下、先匹配先生效"的规则,把严格规则放前面,reject 用于拒绝特定来源。修改后需 reload 生效。

# TYPE  DATABASE  USER  ADDRESS        METHOD
host    all       all   127.0.0.1/32   scram-sha-256
host    all       all   192.168.1.0/24 scram-sha-256
host    replication repl  192.168.1.5/32 scram-sha-256
#
★★

13. 物理 vs 逻辑复制的取舍?

请比较物理复制与逻辑复制的取舍,说明各自适用场景?

  • 物理复制特点
  • 逻辑复制特点
  • 选型考量

物理复制复制整个数据库的字节级 WAL,一致性高、简单、覆盖全部对象,但只能复制整库、备库与主库版本必须一致、不能按表过滤。逻辑复制按逻辑变更复制,灵活(可按表、可过滤、可跨版本、可跨数据库),但机制复杂、对 DDL 支持有限、性能开销略高、需处理复制冲突。取舍:高可用、只读扩展、灾难恢复用物理复制;数据迁移、跨库同步、CDC、数据仓库、多活用逻辑复制。

物理复制偏"基础设施",逻辑复制偏"数据集成"。很多生产环境两者并用:物理复制做高可用,逻辑复制做数据外发。理解各自边界有助于合理选型。

#
★★

14. pgoutput 在逻辑复制协议中的角色,作为输出插件如何解码 WAL 并推送给订阅端,与 wal2json 的格式差异及对 CDC 工具的适配?

请说明 pgoutput 在逻辑复制协议中的角色,以及它与 wal2json 的格式差异和对 CDC 工具的适配?

  • pgoutput 的工作机制
  • 与 wal2json 的差异
  • CDC 工具适配

pgoutput 是 PostgreSQL 内置的逻辑解码输出插件,在逻辑复制协议中负责把 WAL 中的变更解码为逻辑复制流,并推送给订阅端(subscription 的 apply 进程)。它使用二进制协议(replication protocol),与订阅端原生集成,性能好,是 publication/subscription 的默认输出插件。wal2json 是第三方插件,把变更输出为 JSON 格式(含事务边界、表名、操作、新旧值),适合接外部 CDC 工具(如 Debezium、Kafka connect)消费。差异:pgoutput 是二进制原生协议、面向 PG 内部订阅;wal2json 是 JSON 文本、面向外部系统。CDC 工具通常用 wal2json 或适配 pgoutput 协议。

输出插件决定逻辑复制的"出口格式"。pgoutput 面向 PG-PG 订阅,wal2json 面向外部消费。理解其差异才能为 CDC 管道选择正确插件。

#
★★

15. wal2json 在 CDC 管道中的应用,将逻辑复制输出为 JSON 变更流的事务边界与性能开销如何权衡,生产上为何常被 pgoutput 取代?

请说明 wal2json 在 CDC 管道中的应用,包括 JSON 变更流的事务边界与性能开销权衡,以及为何生产常被 pgoutput 取代?

  • wal2json 的 JSON 输出
  • 事务边界与性能
  • 被 pgoutput 取代的原因

wal2json 将逻辑复制输出为 JSON 变更流,每条 JSON 包含事务相关信息(事务 ID、时间戳、变更表、操作类型、新旧值),可配置 include-timestamp、include-transaction 等选项以适应 CDC 管道。其 JSON 输出便于外部系统消费,但 JSON 序列化开销较高、格式较庞大,且需第三方编译安装、版本与 PG 版本匹配。生产上常被 pgoutput 取代的原因:pgoutput 是内置插件、随 PG 发行、二进制协议更高效、无需额外部署,且不少 CDC 工具(如 Debezium 的 PG 插件)已直接支持 pgoutput 协议,因此更稳定、维护成本更低。

wal2json 灵活但引入第三方依赖与性能开销;pgoutput 作为官方内置方案更稳。若 CDC 工具支持 pgoutput 则优先使用,否则才考虑 wal2json。

#
★★

16. WAL 与复制槽(replication slot)的配合,复制槽如何保证 standby 与逻辑订阅端不丢 WAL,槽位堆积导致的磁盘风险如何监控与清理?

请说明 WAL 与复制槽的配合机制,以及复制槽堆积导致的磁盘风险如何监控与清理?

  • 复制槽的作用
  • 槽位堆积风险
  • 监控与清理

复制槽(replication slot)记录下游消费位置(LSN),主库据此保留下游尚未消费的 WAL,防止 standby 或逻辑订阅端因主库 WAL 被清理而丢数据。若下游长期不消费或断开,主库会一直保留 WAL 导致 pg_wal 目录膨胀甚至磁盘满。监控:查询 pg_replication_slots 的 restart_lsn 与 confirmed_flush_lsn,对比当前 WAL 位置(pg_wal_lsn_diff)判断堆积;结合 pg_stat_activity 的 walsender 状态。清理:修复下游消费,或删除不再使用的复制槽(pg_drop_replication_slot),并 promote 备库时注意槽位处理。

复制槽是"不丢 WAL"的保证,但也是"磁盘膨胀"的隐患。监控槽位落后量(restart_lsn 与当前 LSN 的差)是运维关键。

SELECT slot_name, slot_type, restart_lsn,
       pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) AS lag_bytes
FROM pg_replication_slots;
SELECT pg_drop_replication_slot('slot1');
#
★★

17. publication 支持的表级、行级(WHERE)与列级过滤对逻辑复制的数据量与性能有何影响?DDL 变更后过滤条件如何生效?

请说明 publication 的表级、行级(WHERE)与列级过滤对逻辑复制的数据量与性能影响,以及 DDL 变更后过滤条件如何生效?

  • publication 的过滤类型
  • 过滤对数据量与性能的影响
  • DDL 变更后过滤生效

publication 支持表级过滤(只发布指定表)、行级过滤(CREATE PUBLICATION ... FOR TABLE t WHERE 条件,只发布满足条件的行)和列级过滤(FOR TABLE t (col1, col2),只发布指定列)。过滤可减少传输数据量、降低网络与订阅端开销,但每次变更需评估过滤条件,增加一定解码开销。DDL 变更后(如 ALTER TABLE 加列)过滤条件需重新评估:PG 15+ 支持行级过滤的 DDL 变更会重置或需要重新验证,表结构变化后旧过滤条件可能不适用,需手动调整 publication 定义使其生效。

过滤是逻辑复制精准裁剪的关键,减数据量但增过滤计算。DDL 变更后过滤器需重新同步,是运维要点。

CREATE PUBLICATION pub1 FOR TABLE orders WHERE (status = 'paid');
CREATE PUBLICATION pub2 FOR TABLE orders (id, amount);
#
★★

18. scram-sha-256 认证的密码如何存储?password_encryption 参数与旧 md5 哈希的平滑迁移升级如何做?

请说明 scram-sha-256 认证的密码存储方式,以及如何通过 password_encryption 参数平滑迁移升级旧 md5 哈希?

  • SCRAM 密码存储格式
  • password_encryption 参数
  • 从 md5 平滑迁移

scram-sha-256 认证的密码以 SCRAM-SHA-256 格式存储,格式为 SCRAM-SHA-256$<迭代次数>:<盐>: :,其中包含迭代次数、随机盐和经过 PBKDF2/哈希派生的密钥,不保存明文且抗离线破解。password_encryption 参数(scram-sha-256 或 md5)决定新建/修改密码时的存储算法。平滑迁移:先把 password_encryption 设为 scram-sha-256,然后逐个用户执行 ALTER ROLE ... PASSWORD 重设密码(生成的哈希为 SCRAM);期间旧 md5 哈希用户仍可登录(认证时兼容),全部重设后可将 pg_hba.conf 的认证方式改为只接受 scram-sha-256,完成迁移。

SCRAM 存储格式安全先进,md5 是旧格式。迁移的关键是"先改存储算法并逐个重设密码,再收紧认证方式",保证平滑无中断。

SET password_encryption = 'scram-sha-256';
ALTER ROLE app_user PASSWORD 'new-secret';
#

19. PostgreSQL 逻辑复制的冲突处理,主键冲突、表结构不一致时的行为与 subscription 的 disable/enable 恢复?

请说明 PostgreSQL 逻辑复制的冲突处理,包括主键冲突、表结构不一致时的行为及 subscription 的 disable/enable 恢复?

  • 主键冲突行为
  • 表结构不一致行为
  • subscription 恢复

逻辑复制应用变更时可能遇到冲突:主键冲突(订阅端已存在相同主键的行,INSERT 失败)、表结构不一致(订阅端表缺少列或类型不匹配,UPDATE/INSERT 失败)。冲突时复制进程(apply worker)会报错并停止,后续变更无法继续应用。处理:先排查冲突原因,修正订阅端数据或表结构,然后通过 ALTER SUBSCRIPTION ... DISABLE 暂停、清理/对齐数据、再 ENABLE 恢复订阅。可配置 subscription 的 skip 选项跳过特定事务,或先手动修正再继续。注意逻辑复制默认不处理冲突,需运维介入。

冲突处理是逻辑复制的常见运维。关键在于"先修数据/结构,再恢复订阅",避免盲目重开。理解冲突类型才能快速定位。

ALTER SUBSCRIPTION sub_orders DISABLE;
-- 修正订阅端数据或结构
ALTER SUBSCRIPTION sub_orders ENABLE;
#

20. 复制账号为何应使用最小权限而非超级用户?REPLICATION 属性与 pg_hba.conf 中 replication 条目如何配置?

请说明复制账号为何应使用最小权限,以及 REPLICATION 属性和 pg_hba.conf 中 replication 条目的配置?

  • 最小权限原则
  • REPLICATION 属性
  • 复制连接配置

复制账号如果使用超级用户,一旦泄露将拥有全部权限,风险极高;因此应创建仅具备所需复制权限的最小权限账号。复制账号需要 REPLICATION 属性(CREATE ROLE ... REPLICATION LOGIN),这是允许其建立复制连接(流复制、逻辑解码)的必要属性,同时按需授予对其复制表的 SELECT 权限(逻辑复制)。pg_hba.conf 中需配置 replication 条目,数据库字段使用 replication,允许该账号的连接。

最小权限是安全基线。REPLICATION 属性是复制相关权限的开关,配合 pg_hba.conf 的 replication 条目精确控制谁能做复制。

CREATE ROLE repl WITH REPLICATION LOGIN PASSWORD 'x';
GRANT SELECT ON orders TO repl;
host    replication   repl   192.168.1.5/32   scram-sha-256