PostgreSQL 教程: 设置流复制

十月 18, 2023

摘要流式复制(物理复制),是逐字节进行复制,涉及连续应用从主用数据库到备用数据库的 WAL 记录。由于它使用基于文件的日志传送方法,因此与逻辑复制或其他基于触发器的方法相比,它是最快的复制方法之一。

它默认是异步的。对于每个副本/备用服务器,在流复制中,主服务器上存在一个 WAL 发送进程,在备用服务器上存在一个 WAL 接收进程。这些进程负责流式传输和应用来自 WAL 段(包括未满的段)中的 WAL 记录。

从 PostgreSQL 13 开始,我们执行流复制的方式发生了一些变化。例如,与版本 11 及更早版本不同,在 PostgreSQL 13 中,我们看不到recovery.conf文件。相反,以前添加到recovery.conf的参数,现在可以直接在postgresql.confpostgresql.auto.conf中设置。

在本教程中,我们将了解在 PostgreSQL 13 中设置流复制所涉及的步骤。

准备工作

我们可以在同一服务器上不同端口上运行的两个实例中设置流复制。但这并没有解决高可用性的目的。因此,建议在地理上隔离的服务器之间建立复制。为了要开始操作的步骤,我们需要两台安装了 PostgreSQL 13 的服务器(主服务器和备用服务器),且在主服务器上的 PostgreSQL 在运行中。

操作步骤

我们将使用以下步骤来设置流复制:

1. 在主数据库上创建复制用户:

$ psql -c "CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'secret'"

2. 在主服务器上的pg_hba.conf文件中添加必要的条目:

$ echo "host replication replicator <slave_ip_address>/32 md5" >>
$PGDATA/pg_hba.conf
$ psql -c "select pg_reload_conf()"

3. 在主数据库上,验证设置复制所需的参数。最好的方法如下:

$ psql -c "select name, setting from pg_settings where name IN ('listen_addresses','archive_mode','archive_command','wal_keep_segments','restore_command')"

4. 修改主数据库上需要修改的参数:

$ psql -c "ALTER SYSTEM SET listen_addresses TO '*'";
$ psql -c "ALTER SYSTEM SET archive_mode TO 'ON'";
$ psql -c "ALTER SYSTEM SET archive_command TO 'cp %p /archives/%f'";
$ psql -c "ALTER SYSTEM SET restore_command TO 'cp /archives/%f %p'";
$ psql -c "ALTER SYSTEM SET wal_keep_segments TO '100'";

5. 根据修改的参数,根据需要重新启动主数据库,或重新加载配置参数:

$ pg_ctl -D $PGDATA restart -mf

使用以下命令让主数据库重新加载配置参数:

$ pg_ctl -d $PGDATA reload

6. 在备用服务器运行pg_basebackup,以生成主数据库的备份:

$ pg_basebackup -h <master_ip> -U replicator -p 5432 -D $PGDATA -Fp -Xs -P -R

7. 在备用数据库上验证复制所需的必要参数:

$ cat $PGDATA/postgresql.auto.conf

8. 设置primary_conninfo参数,如果不存在standby.signal文件,请创建它:

$ echo "primary_conninfo = 'user=replicator password=secret host=<master_IP> port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'" >> $PGDATA/postgresql.auto.conf
$ echo "standby_mode = 'ON'" >> $PGDATA/postgresql.auto.conf
$ touch $PGDATA/standby.signal

9. 启动备用数据库,或者重新加载配置参数,具体取决于更改过的参数:

$ pg_ctl -D $PGDATA start

或者,使用以下命令:

$ sudo systemctl start postgresql-13

怎么做到的

设置流复制的第一步是,创建具有REPLICATION权限的复制用户。我们可以使用超级用户postgres来实现此目的,但不建议这样做。创建用户后,我们需要在主服务器的pg_hba.conf文件中添加一个条目,以允许来自备用服务器的复制连接,如步骤 2 所示。 非常重要的一点是,您需要将 <slave_ip_address>/32 替换为备用服务器的 IP 或主机名/子网,以让主服务器允许复制连接。

如步骤 3 所示,在我们设置流复制时,有一些参数起着至关重要的作用。除了listen_addresses之外,大多数参数的默认值都已经适用于复制了。但是,如果所有这些参数都设置得当,那么我们将拥有完美的复制设置。

例如,在步骤 4 中,我们看到listen_addresses设置为’*’,以允许从特定网络接口或所有网络接口(使用*)连接到主服务器。要启用 WAL 归档,我们可以设置archive_mode为 ‘ON’,并且可以设置archive_command为 WAL 归档进程可以使用的 shell 命令,将完整的 WAL 段复制到安全位置,以用于数据恢复。

另外,我们还可以设置restore_command,这对于以后主用数据库变成备用数据库时会有帮助。该参数必须使用 shell 命令来设置,该命令用于从归档位置获取归档的 WAL 段。如果在主用数据库上设置了该参数,备份时也会复制到备用数据库上,所以不需要设置两次。最后,可以设置wal_keep_segments,让主服务器在任何给定时间保留指定数量的 WAL 段。当备用数据库在复制过程中滞后几个 WAL 段时,这是有帮助的,它可以无需从归档位置去获取 WAL。

在正确设置所有参数后,如果listen_addressesarchive_mode参数已修改,我们可以进入步骤 5 重新启动主服务器,否则,可以跳过此步骤,只需重新加载配置即可。

现在我们可以继续执行步骤 6,从备用数据库备份主数据库的数据目录。在步骤 6 中,我们以原始格式 (-Fp) 使用pg_basebackup。如果主服务器的数据量很大,我们可以在主服务器上以压缩的 tar 格式 (-Ft -z) 使用pg_basebackup,并将备份复制到备用服务器来恢复。这在恢复一个 pg_basebackup 生成的备份教程中进行了描述。

如果您仔细看步骤 6 中使用的命令,它包含了命令行参数-R。这会在备用数据库的数据目录中,创建用于复制的特定文件和条目。您可以使用多种方法(例如 rsync 或任何其他磁盘备份方法),将主服务器的数据目录复制到备用服务器。根据我们选择的备份方法,我们需要设置一些不会自动处理的参数,如带有-R参数的pg_basebackup的情况所示。

然后,我们继续执行第 7 步,验证需要在备用数据库上设置流复制的必要参数。当我们指定-R使用pg_basebackup时,会自动添加primary_conninfo参数。否则,我们需要添加一个与步骤 8 中所示类似的条目,以告诉备用数据库如何连接到主数据库。我们必须将 <master_IP> 替换为主服务器的 IP 地址或主机名。备用数据目录中必须存在一个重要文件 (standby.signal),指示 PostgreSQL 以备用状态运行。当我们使用-R选项执行pg_basebackup时,它会自动创建。如果没有,我们可以简单地使用touch创建这个空文件,如步骤 8 所示。然后,为了指示数据库以备用模式运行,我们需要设置 standby_mode为 ON。

最后一步,即步骤 9,是使用pg_ctl启动备用服务器。