如何在Debian 10中使用复制插槽设置PostgreSQL流复制

如何在Debian 10中使用复制插槽设置PostgreSQL流复制

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 [email protected]

注意:更新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无法访问Internet。否则,请使用公共地址。

保存更改并重新启动两个实例。

systemctl restart [email protected]

步骤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 [email protected]

步骤4:基本备份

此过程中的命令必须在辅助/从属服务器上运行。

首先,在辅助节点上停止Postgres。

systemctl stop [email protected]

备份旧的数据目录。

mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.bak

使用以下命令将主数据目录复制到从属目录:

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 [email protected]

您现在处于待机模式,需要复制新事务。

测试中

测试复制

要测试复制,请在主服务器上执行写操作。例如,在主数据库上创建一个新数据库。

sudo -u postgres psql -c "CREATE DATABASE replitest"

等待几秒钟,然后列出从属服务器上的数据库。

sudo -u postgres psql -c "l"

您需要确保响应数据库实际上是由备用服务器复制的。

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 [email protected]

重置数据目录。

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 [email protected]

辅助实例返回待机模式。您可以在此时重新测试副本。

精加工

删除主节点上不必要的数据库。例如:

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

Source

Sidebar