如何在 Debian 10 上使用复制槽设置 PostgreSQL 流式复制
在此页
- 要求
- 第 1 步:安装 PostgreSQL
- 第 2 步:初始配置
- 第 3 步:主配置
- 第 4 步:基础备份
- 第 5 步:备用配置
- 测试
- 测试复制
- 测试故障转移
PostgreSQL 是一个功能强大且功能丰富的关系数据库管理系统 (RDBMS)。它是免费和开源的,自 1996 年以来一直在开发中。Postgres 提供了不同的归档和复制数据的方法,其中之一是流复制。在这种模式下,主(主)实例处理主活动数据库并执行操作。辅助(从属)实例复制主实例的所有更改,维护活动数据库的相同副本。辅助服务器也可以接受只读查询。如果主服务器发生故障,辅助服务器可以退出备用模式并作为新的主服务器运行(这称为故障转移)。
PostgreSQL 复制通常依赖于预写日志记录 (WAL),即在将数据更改写入磁盘之前记录数据更改的过程。然后将这些 WAL 记录作为文件复制到第二个节点(基于文件的日志传送),或者直接在节点之间流式传输(流式复制)。在大多数情况下,后者减少了备用节点接收主节点更改的延迟。
在没有基于文件的日志传送的情况下使用流复制的问题是,如果主服务器过早丢弃它们,则辅助服务器可能会丢失一些 WAL 记录。许多配置参数可以降低这种风险,但通常会带来不必要的存储成本。解决方案是复制槽,这是 Postgres 提供的一项功能,可确保主服务器仅在备用节点接收到 WAL 记录后才丢弃它们。
我们将在两个 Debian 10 节点上设置带有复制槽的流复制。
要求
- 两个相同的 Debian 10 实例。
- 两个实例的根访问权限。
- $EDITOR 环境变量应该在两个实例上设置。
第 1 步:安装 PostgreSQL
更新并重启两个节点:
apt update apt upgrade -y reboot
在两个节点上安装 Postgres 并确保 PostgreSQL 已启用并正在运行:
apt install -y postgresql systemctl enable --now
注意:更新 PostgreSQL 时,根据其文档,先更新备用数据库是更安全的选择。
第 2 步:初始配置
默认情况下,PostgreSQL 只监听环回接口,外部无法访问。通过编辑 postgresql.conf 更改两个节点上的监听地址:
$EDITOR /etc/postgresql/11/main/postgresql.conf
找到以下行:
#listen_addresses = 'localhost'
将其更改为:
listen_addresses = 'node_ip_address,127.0.0.1'
如果两个节点共享同一个本地网络,您可以使用私有地址作为 node_ip_address,尽管 Postgres 无法通过互联网访问。否则,请使用公共地址。
保存更改然后重新启动两个实例:
systemctl restart
第 3 步:主配置
此步骤仅适用于主/主服务器。
打开 Postgres 终端:
sudo -u postgres psql
备用节点将使用用户连接到主节点。创造它:
postgres=# CREATE ROLE replicator LOGIN REPLICATION ENCRYPTED PASSWORD 'replicator_password';
然后创建一个复制槽并退出:
postgres=# SELECT * FROM pg_create_physical_replication_slot('replicator'); postgres=# \q
为了简单起见,复制角色和槽都命名为“复制器”,尽管它们不必完全相同。
接下来,在 pg_hba.conf 中创建一个条目以允许复制器用户从备用数据库连接到主数据库。打开它:
$EDITOR /etc/postgresql/11/main/pg_hba.conf
将以下行附加到末尾:
host replication replicator standby_ip_address/32 md5
重启主实例:
systemctl restart
第 4 步:基础备份
此步骤中的命令应在辅助/从服务器上执行。
首先,停止辅助节点上的 Postgres:
systemctl stop
备份旧数据目录:
mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.bak
使用以下命令将masters数据目录clone到slave:
pg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicator
系统将提示您输入密码。输入您在主服务器上创建复制器角色时为其选择的密码。传输完成后,将数据目录的所有权授予 postgres 用户:
chown -R postgres:postgres /var/lib/postgresql/11/main
第 5 步:备用配置
此步骤仅适用于辅助/从属服务器。
在postgresql.conf中启用双机热备模式:
$EDITOR /etc/postgresql/11/main/postgresql.conf
查找并取消注释以下行:
#hot_standby = on
在 Postgres 数据目录中创建文件 recovery.conf:
$EDITOR /var/lib/postgresql/11/main/recovery.conf
启用待机模式:
standby_mode = 'on'
使用在主服务器上创建的凭据设置复制连接参数:
primary_conninfo = 'host=master_ip_address port=5432 user=replicator password=replicator_password'
设置您在主服务器上创建的复制槽的名称:
primary_slot_name = 'replicator'
设置故障转移触发器文件的路径:
trigger_file = '/var/lib/postgresql/11/main/failover.trigger'
如果设置了 trigger_file 参数,Postgres 将退出待机模式并在创建此触发器文件时作为主服务器开始正常操作。此参数不是必需的。
创建 recovery.conf 后,将所有权授予 postgres 用户:
chown postgres:postgres /var/lib/postgresql/11/main/recovery.conf
您现在可以启动 Postgres:
systemctl start
它现在处于待机模式,应该正在复制任何新事务。
测试
测试复制
要测试复制,请在主服务器上执行任何写入操作。例如在master上新建一个数据库:
sudo -u postgres psql -c "CREATE DATABASE replitest"
等待几秒钟,然后列出从站上的数据库:
sudo -u postgres psql -c "\l"
你应该看到 replitest 数据库确实被备用服务器复制了:
List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | replitest | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows)
测试故障转移
注意:如此处所示的测试故障转移将需要在故障转移后重置备用服务器。
由于 Postgres 处于备用模式,因此在故障转移之前,您应该无法在辅助节点上执行任何写入操作。例如,执行以下命令:
sudo -u postgres psql -c "CREATE DATABASE test"
命令应该失败:
ERROR: cannot execute CREATE DATABASE in a read-only transaction
要发出故障转移信号,请创建在 recovery.conf 中指定的触发器文件
touch /var/lib/postgresql/11/main/failover.trigger
等待几秒钟,然后尝试执行写操作。例如:
sudo -u postgres psql -c "CREATE DATABASE test2"
由于 Postgres 不再作为备用数据库运行,因此操作将会成功。 Postgres 还会将您的 recovery.conf 文件重命名为 recovery.done,并将删除触发器文件。
要返回备用状态,请在(以前的)辅助节点上停止 Postgres:
systemctl stop
重置数据目录:
mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.2.bak pg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicator chown -R postgres:postgres /var/lib/postgresql/11/main
并重新创建 recovery.conf:
cp /var/lib/postgresql/11/main.2.bak/recovery.done /var/lib/postgresql/11/main/recovery.conf
最后,重启 Postgres:
systemctl start
辅助实例现在回到备用模式。此时您可能需要重新测试复制。
整理起来
删除主节点上任何不需要的数据库,例如:
sudo -u postgres psql postgres=# DROP DATABASE replitest;
并删除备用节点上的旧数据目录:
rm /var/lib/postgresql/11/main.bak -r rm /var/lib/postgresql/11/main.2.bak -r