目前 PostgreSQL 中有两种类型的复制可用:流复制和逻辑复制。如果您正在寻找为 PostgreSQL 13 设置流复制,这是您一直在寻找的页面。本教程将向您展示如何配置 PostgreSQL 复制以及如何快速设置数据库服务器。
流复制:https://www.postgresql.org/docs/current/high-availability.html
逻辑复制:https://www.postgresql.org/docs/current/logical-replication.html
PostgreSQL 复制:我们想要实现的目标
在我们开始配置 PostgreSQL 之前,先看看我们想要实现的目标是有意义的。本教程的目标是使用异步复制创建将主服务器数据复制到备用服务器。
以下是所需的设置:

整个设置将使用 CentOS 8.3 完成。RHEL(Redhat Enterprise Linux)上的过程预计是相同的。只需遵循相同的程序。
为了展示设置的工作原理,我们使用了两个具有以下 IP 的虚拟机:
主:10.0.3.200(node1)
备:10.0.3.201(node2)
让我们逐步准备这些系统。
安装 PostgreSQL
一旦你安装了 CentOS / RHEL,你就可以准备 PostgreSQL 本身的安装了。方法是访问PostgreSQL 网站并按照说明进行操作。以下脚本显示了事情是如何工作的。您可以简单地复制/粘贴脚本:
https://www.postgresql.org/download/linux/redhat/
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpmsudo dnf -qy module disable postgresqlsudo dnf install -y postgresql13-server# can be skipped on the 2nd nodesudo /usr/pgsql-13/bin/postgresql-13-setup initdbsudo systemctl enable postgresql-13# can be skipped on the 2nd nodesudo systemctl start postgresql-13
让我们检查一下我们现在应该在 node1 上看到什么:
[root@node1 ~]# ps axf | grep post5542 pts/1 S+ 0:00 \_ grep --color=auto post5215 ? Ss 0:00 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/5217 ? Ss 0:00 \_ postgres: logger5219 ? Ss 0:00 \_ postgres: checkpointer5220 ? Ss 0:00 \_ postgres: background writer5221 ? Ss 0:00 \_ postgres: walwriter5222 ? Ss 0:00 \_ postgres: autovacuum launcher5223 ? Ss 0:00 \_ postgres: stats collector5224 ? Ss 0:00 \_ postgres: logical replication launcher
在此过程之后,您应该拥有:
已安装的二进制文件
一个完全工作的节点1
系统脚本设置
数据库实例已初始化
准备好的第二个节点(node2)
安装的二进制文件
系统脚本设置
现在让我们继续下一步:禁用主节点上的防火墙。
[root@node1 ~]# systemctl disable firewalldRemoved /etc/systemd/system/multi-user.target.wants/firewalld.service.Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.[root@node1 ~]# systemctl stop firewalld
为什么这是必要的?副本将在端口 5432 上连接到主服务器。如果防火墙仍然处于活动状态,则副本将无法访问端口 5432。在我们的示例中,防火墙将完全禁用以方便连接。在更安全的设置中,您可能希望以更精确的方式执行此操作。
配置主副本以进行复制
我们必须在主服务器上做四件事:
在中启用网络(绑定地址)
postgresql.conf创建复制用户(最佳实践,但不是强制性的)
允许远程访问
pg_hba.conf重启主服务器
我们可以逐步执行这些操作。
首先是改变postgresql.conf
。该文件可以在/var/lib/pgsql/13/data/postgresql.conf
. 但是,如果您不知道在哪里可以找到postgresql.conf
您可以要求 PostgreSQL 本身将您指向配置文件。下面是它的工作原理:
[root@node1 ~]# su - postgres[postgres@node1 ~]$ psql postgrespsql (13.2)Type "help" for help.postgres=# SHOW config_file;config_file----------------------------------------/var/lib/pgsql/13/data/postgresql.conf(1 row)
必须更改以下参数postgresql.conf
:
listen_addresses = '*'
是什么listen_addresses
?默认情况下,PostgreSQL 只监听 localhost。出于安全原因,默认情况下不允许远程访问。因此,我们也必须教 PostgreSQL 监听远程请求。换句话说:listen_addresses
定义我们的数据库服务的绑定地址。没有它,远程访问是不可能的(即使您pg_hba.conf
稍后更改)。
然后我们已经可以在数据库中创建用户了:
postgres=# CREATE USER repuser REPLICATION;CREATE ROLE
当然,您也可以设置密码。这里重要的是用户REPLICATION
设置了标志。基本思想是避免使用超级用户将事务日志从主服务器流式传输到副本服务器。
接下来我们可以做的是更改pg_hba.conf
,它控制谁可以从哪个 IP 连接到 PostgreSQL。请将以下行添加到配置文件中:
host replication repuser 10.0.3.201/32 trust
我们希望允许repuser
来自10.0.3.201
主服务器的登录和流式传输事务日志。请记住,这10.0.3.200
是我们设置中的主要内容,并且10.0.3.201
是副本。
最后,我们可以重新启动主节点,因为我们已经更改listen_addresses
了postgresql.conf
. 如果您只更改pg_hba.conf
重新加载就足够了:
[postgres@node1 ~]$ exitlogout[root@node1 ~]# systemctl restart postgresql-13
您的系统现已准备就绪,我们可以将注意力集中在备上。
创建基础备份
下一步是创建副本。我们需要做很多事情来完成这项工作。首先要确保副本已停止并且数据目录为空。让我们首先确保服务已停止:
[root@node2 ~]# systemctl stop postgresql-13
然后,我们需要确保数据目录为空:
[root@node2 ~]# cd /var/lib/pgsql/13/data/[root@node2 data]# lsPG_VERSION global pg_dynshmem pg_logical pg_replslot pg_stat pg_tblspc pg_xact postmaster.optsbase log pg_hba.conf pg_multixact pg_serial pg_stat_tmp pg_twophase postgresql.auto.confcurrent_logfiles pg_commit_ts pg_ident.conf pg_notify pg_snapshots pg_subtrans pg_wal postgresql.conf[root@node2 data]# rm -rf *
initdb
请注意,如果您在安装过程中跳过了此步骤,则无需执行此步骤。但是,如果您想将现有服务器变为副本,则必须这样做。
[root@node2 data]# su postgresbash-4.4$ pwd/var/lib/pgsql/13/databash-4.4$ pg_basebackup -h 10.0.3.200 -U repuser --checkpoint=fast \-D /var/lib/pgsql/13/data/ -R --slot=some_name -C
pg_basebackup
将连接到主服务器并简单地复制所有数据文件。连接必须为repuser
. 为了确保复制过程立即开始,告诉 PostgreSQL 快速检查点是有意义的。该-D
标志定义了我们要在副本上存储数据的目标目录。这-R
flag 自动配置我们的副本以进行复制。不需要在辅助服务器上进行更多配置。最后,我们创建了一个复制槽。PostgreSQL 中复制槽的用途是什么?基本上,主服务器能够回收 WAL——如果主服务器不再需要它的话。但是如果副本还没有消费呢?在这种情况下,副本将失败,除非有一个复制槽确保主节点只有在副本完全消耗 WAL 时才能回收它。我们 CYBERTEC 建议在最常见的情况下使用复制槽。
让我们弄清楚做了什么pg_basebackup
:
bash-4.4$ ls -ltotal 196-rw-------. 1 postgres postgres 3 Feb 12 09:12 PG_VERSION-rw-------. 1 postgres postgres 224 Feb 12 09:12 backup_label-rw-------. 1 postgres postgres 135413 Feb 12 09:12 backup_manifestdrwx------. 5 postgres postgres 41 Feb 12 09:12 base-rw-------. 1 postgres postgres 30 Feb 12 09:12 current_logfilesdrwx------. 2 postgres postgres 4096 Feb 12 09:12 globaldrwx------. 2 postgres postgres 32 Feb 12 09:12 logdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_commit_tsdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_dynshmem-rw-------. 1 postgres postgres 4598 Feb 12 09:12 pg_hba.conf-rw-------. 1 postgres postgres 1636 Feb 12 09:12 pg_ident.confdrwx------. 4 postgres postgres 68 Feb 12 09:12 pg_logicaldrwx------. 4 postgres postgres 36 Feb 12 09:12 pg_multixactdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_notifydrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_replslotdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_serialdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_snapshotsdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_statdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_stat_tmpdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_subtransdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_tblspcdrwx------. 2 postgres postgres 6 Feb 12 09:12 pg_twophasedrwx------. 3 postgres postgres 60 Feb 12 09:12 pg_waldrwx------. 2 postgres postgres 18 Feb 12 09:12 pg_xact-rw-------. 1 postgres postgres 335 Feb 12 09:12 postgresql.auto.conf-rw-------. 1 postgres postgres 28014 Feb 12 09:12 postgresql.conf-rw-------. 1 postgres postgres 0 Feb 12 09:12 standby.signal
pg_basebackup
已经复制了所有内容。然而,还有更多。已经创建了standby.signal 文件,它告诉备它确实是一个副本。
最后,工具调整了postgresql.auto.conf
文件,该文件恰好包含使副本连接到主服务器(node1)上的副本所需的所有配置:
bash-4.4$ cat postgresql.auto.conf# Do not edit this file manually!# It will be overwritten by the ALTER SYSTEM command.primary_conninfo = 'user=repuser passfile=''/var/lib/pgsql/.pgpass'' channel_binding=prefer host=10.0.3.200 port=5432 sslmode=prefer sslcompression=0 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'primary_slot_name = 'some_name'
我们完成了,可以继续启动备。
启动副本
我们已准备好使用以下命令启动备systemctl
:
bash-4.4$ exitexit[root@node2 data]# systemctl start postgresql-13[root@node2 data]# ps axf | grep post36394 pts/1 S+ 0:00 \_ grep --color=auto post36384 ? Ss 0:00 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/36386 ? Ss 0:00 \_ postgres: logger36387 ? Ss 0:00 \_ postgres: startup recovering 00000001000000000000000736388 ? Ss 0:00 \_ postgres: checkpointer36389 ? Ss 0:00 \_ postgres: background writer36390 ? Ss 0:00 \_ postgres: stats collector36391 ? Ss 0:00 \_ postgres: walreceiver streaming 0/7000148
检查进程是否确实在运行是个好主意。检查walreceiver
进程是否存在尤为重要。walreceiver
负责从主节点获取 WAL。如果它不存在,则您的设置失败。还要确保该服务已启用。
检查您的 PostgreSQL 复制设置
设置完成后,查看监控是有意义的。一般来说,使用pgwatch2 之类的工具来专业地监控您的数据库是有意义的。
https://www.cybertec-postgresql.com/en/products/pgwatch/
让我们首先检查主节点:
[root@node1 ~]# su - postgres[postgres@node1 ~]$ psql postgrespsql (13.2)Type "help" for help.postgres=# \xExpanded display is on.postgres=# SELECT * FROM pg_stat_replication ;-[ RECORD 1 ]----+------------------------------pid | 6102usesysid | 16385usename | repuserapplication_name | walreceiverclient_addr | 10.0.3.201client_hostname |client_port | 34002backend_start | 2021-02-12 09:27:59.53724-05backend_xmin |state | streamingsent_lsn | 0/7000148write_lsn | 0/7000148flush_lsn | 0/7000148replay_lsn | 0/7000148write_lag |flush_lag |replay_lag |sync_priority | 0sync_state | asyncreply_time | 2021-02-12 09:29:49.783076-05
pg_stat_replication
存在的一行数据告诉我们 WAL 正在从主要流向备。
但是,我们也可以对备进行检查:
[root@node2 data]# su - postgres[postgres@node2 ~]$ psql postgrespsql (13.2)Type "help" for help.postgres=# \xExpanded display is on.postgres=# SELECT * FROM pg_stat_wal_receiver;-[ RECORD 1 ]---------+--------------------------------------------pid | 36391status | streamingreceive_start_lsn | 0/7000000receive_start_tli | 1written_lsn | 0/7000148flushed_lsn | 0/7000148received_tli | 1last_msg_send_time | 2021-02-12 09:29:59.683418-05last_msg_receipt_time | 2021-02-12 09:29:59.674194-05latest_end_lsn | 0/7000148latest_end_time | 2021-02-12 09:27:59.556631-05slot_name | some_namesender_host | 10.0.3.200sender_port | 5432conninfo | user=repuserpassfile=/var/lib/pgsql/.pgpasschannel_binding=preferdbname=replicationhost=10.0.3.200port=5432fallback_application_name=walreceiversslmode=prefersslcompression=0ssl_min_protocol_version=TLSv1.2gssencmode=preferkrbsrvname=postgrestarget_session_attrs=any
pg_stat_wal_receiver
中一行数据表明 WAL 接收器确实存在,并且数据正在流动。
到此为止!我希望你喜欢这个教程。有关在同步和异步复制之间进行选择的更多信息,请查看此页面。https://www.cybertec-postgresql.com/en/services/postgresql-replication/synchronous-asynchronous-replication/




