
主从术语
master/primary 服务器
可以进行写入的服务器。 也称为读/写服务器。
Slave/Standby 服务器
数据与主服务器连续保持同步的服务器。 也称为备份服务器或副本。 热备用服务器是一种无法升级的服务器,除非将其升级为主服务器。 相反,热备用服务器[1]可以接受连接并提供只读查询。对于本讨论的其余部分,我们将仅专注于热备用服务器。
数据被写入主服务器并传播到从服务器。如果现有主服务器出现问题,则其中一台从属服务器将接管并继续进行写操作,以确保系统的可用性。
基于 WAL 传送的复制
什么是 WAL?
WAL 代表预写日志记录[2]。 它是一个日志文件,所有对数据库的修改都在写入数据文件之前写入其中。 WAL 用于数据库崩溃后的恢复,以确保数据完整性。 WAL 用于数据库系统以实现原子性和持久性。
WAL 如何用于复制?
预写日志记录用于使数据库服务器之间的数据保持同步。这可以通过两种方式实现:
基于文件的日志传送
WAL 日志文件从主服务器传送到备用服务器,以保持数据同步。 主服务器可以将日志直接复制到备用服务器存储,也可以与备用服务器共享存储。 一个 WAL 日志文件最多可以包含 16MB 的数据。 WAL 文件仅在达到该阈值后才被发送。 如果主数据库崩溃且日志未归档,这将导致复制延迟并增加丢失数据的机会
流式传输 WAL 记录
WAL 记录块由数据库服务器流传输以保持数据同步。 备用服务器连接到主服务器以接收 WAL 块。 WAL 记录在生成时将进行流传输。 WAL 记录的流传输无需等待 WAL 文件被填充。 与基于文件的日志传送相比,这可使备用服务器保持最新状态。 默认情况下,流复制是异步的,即使它也支持同步复制。
两种方法各有利弊。使用基于文件的传送可实现时间点恢复和连续归档,而流传送可确保备用服务器上的即时数据可用性。但是,您可以将 PostgreSQL 配置为同时使用两种方法并享受其中的好处。
理论部分啰嗦完毕,开始今天的 Docker 实现部分。代码基于CraigOptimaData/docker-pg-cluster[3]修改实现,原始版本是针对 11 的,12 开始主要变化如下,
recovery.conf 配置文件不再支持,此文件中的参数合并到 postgresql.conf,若 recovery.conf 存在,数据库无法启动。
新增 recovery.signal 标识文件,表示数据库处于 recovery 模式
新增加 standby.signal 标识文件,表示数据库处于 standby 模式
trigger_file 参数更名为 promote_trigger_file
standby_mode 参数不再支持 另外 12 版本
pg_basebackup
命令的 -R 参数的效果和之前不同,主要体现在:命令执行后在 $PGDATA 目录创建 standby.signal 标识文件,文件内容为空
命令执行后在 $PGDATA 目录的 postgresql.auto.conf 文件中添加 primary_conninfo 参数信息
关于流复制的分解动作可以访问我的另外一篇文章,PostgreSQL 12 流复制
所以我重点也是针对这两处做了修改,详细代码可以访问alitrack/docker-pg-cluster[4]查看。

本文摘译自Getting Started with PostgreSQL Streaming Replication[5],并参考了PostgreSQL 12: Recovery.conf 文件参数合并到 postgresql.conf[6] 的部分内容,在此一并致谢!
参考资料
热备用服务器: https://www.postgresql.org/docs/10/static/hot-standby.html
[2]预写日志记录: https://www.postgresql.org/docs/9.1/static/wal-intro.html
[3]CraigOptimaData/docker-pg-cluster: https://bitbucket.org/CraigOptimaData/docker-pg-cluster.git
[4]alitrack/docker-pg-cluster: https://github.com/alitrack/docker-pg-cluster
[5]Getting Started with PostgreSQL Streaming Replication: https://scalegrid.io/blog/getting-started-with-postgresql-streaming-replication/
[6]PostgreSQL 12: Recovery.conf 文件参数合并到 postgresql.conf: https://postgres.fun/20190718155800.html




