如何在Ubuntu20.04上使用PostgreSQL12设置物理流复制
作者选择了 COVID-19 Relief Fund 作为 Write for DOnations 计划的一部分来接受捐赠。
介绍
流式复制是一种流行的方法,可用于水平扩展关系数据库。 它使用在不同机器上运行的同一数据库集群的两个或多个副本。 一个数据库集群称为主数据库集群,同时提供读写操作; 其他的,称为副本,仅服务于读取操作。 您还可以使用流复制来提供系统的高可用性。 如果主数据库集群或服务器意外失败,则副本能够继续提供读取操作,或者(其中一个副本)成为新的主集群。
PostgreSQL是一个广泛使用的关系型数据库,支持逻辑和物理复制。 逻辑复制 将高级更改从主数据库集群流式传输到副本数据库。 使用逻辑复制,您可以将更改流式传输到数据库中的单个数据库或表。 但是,在 物理复制 中,对 WAL(预写日志记录) 日志文件的更改在副本集群中进行流式传输和复制。 因此,您无法复制主数据库集群的特定区域,而是复制对主数据库集群的所有更改。
在本教程中,您将使用运行两个独立 PostgreSQL 12 集群的两台独立机器在 Ubuntu 20.04 上使用 PostgreSQL 12 设置物理流复制。 一台机器是 primary,另一台机器是 replica。
先决条件
要完成本教程,您将需要以下内容:
- 两台独立的机器 Ubuntu 20.04 机器; 一个称为primary,另一个称为replica。 您可以使用我们的 初始服务器设置指南 进行设置,包括具有 sudo 权限和防火墙的非 root 用户。
- 您的防火墙配置为允许 HTTP/HTTPS 和端口
5432
(PostgreSQL 12 使用的默认端口)上的流量。 您可以按照 How To Set Up a Firewall with ufw on Ubuntu 20.04 来配置这些防火墙设置。 - PostgreSQL 12 在两个 Ubuntu 20.04 服务器上运行。 遵循如何在Ubuntu 20.04上安装和使用PostgreSQL教程的Step 1,该教程涵盖了PostgreSQL在Ubuntu 20.04上的安装和基本使用。
第 1 步 — 配置主数据库以接受连接
在第一步中,您将配置 primary 数据库以允许您的 replica 数据库连接。 默认情况下,PostgreSQL 只监听 localhost
(127.0.0.1
) 的连接。 要更改此设置,您将首先编辑 primary 数据库上的 listen_addresses
配置参数。
在您的 primary 服务器上,打开位于 /etc/postgresql/12/main/
目录中的 PostgreSQL 配置文件 postgresql.conf
:
sudo nano /etc/postgresql/12/main/postgresql.conf
打开文件后,找到 listen_addresses
变量并将值从 localhost
更改为 主 服务器的 IP 地址。 您还需要从行首删除 #
字符,如下所示:
/etc/postgresql/12/main/postgresql.conf
. . . listen_addresses = 'your_primary_IP_address' . . .
保存并退出文件。
完成后,您的 primary 数据库现在将准备好接受来自您输入的 IP 地址上的其他计算机的连接。 接下来,您将创建一个角色,该角色具有 副本 在连接到 主 时将使用的适当权限。
第 2 步 — 创建具有复制权限的特殊角色
现在,您需要在 primary 数据库中创建一个有权复制数据库的角色。 当连接到 主 时,您的 副本 将使用此角色。 仅为复制创建单独的角色也具有安全优势。 您的 replica 将无法操作 primary 上的任何数据; 它只能复制数据。
首先,使用以下命令以 postgres
用户身份连接到数据库集群:
sudo -u postgres psql
创建角色需要在集群上运行CREATE ROLE
命令,如下:
CREATE ROLE test WITH REPLICATION PASSWORD 'testpassword' LOGIN;
您将收到以下输出:
OutputCREATE ROLE
此命令创建一个名为 test
的角色,密码为 'testpassword'
,该角色具有复制数据库集群的权限。
PostgreSQL 有一个特殊的复制伪数据库,replica 连接到它,但是您首先需要编辑 /etc/postgresql/12/main/pg_hba.conf
配置文件以允许您的 replica 访问它。 因此,通过运行以下命令退出 PostgreSQL 命令提示符:
\q
现在您回到了终端命令提示符,使用 nano
打开 /etc/postgresql/12/main/pg_hba.conf
配置文件:
sudo nano /etc/postgresql/12/main/pg_hba.conf
将以下行追加到 pg_hba.conf
文件的末尾:
/etc/postgresql/12/main/pg_hba.conf
. . . host replication test your-replica-IP/32 md5
这确保您的 primary 允许您的 replica 使用您之前创建的角色 test
连接到复制伪数据库。 host
值表示通过普通或 SSL 加密的 TCP/IP 套接字接受非本地连接。 replication
是 PostgreSQL 用于复制的特殊伪数据库的名称。 最后,值 md5
是使用的身份验证类型。 如果您想拥有多个 副本 ,只需将同一行再次添加到文件末尾,并使用您的另一个 副本 的 IP 地址。
要确保对配置文件进行这些更改,您需要使用以下命令重新启动 primary 集群:
sudo systemctl restart postgresql@12-main
如果您的 primary 集群成功重新启动,则它已正确设置并准备好在您的 replica 连接后开始流式传输。 接下来,您将继续设置 副本 集群。
第 3 步 — 在副本上备份主集群
当您在本教程中使用 PostgreSQL 设置物理复制时,您需要将 主 集群的数据文件物理备份到 副本的 数据目录中。 为此,您将首先清除 副本的 数据目录中的所有文件。 Ubuntu 上 PostgreSQL 的默认数据目录是 /var/lib/postgresql/12/main/
。
您还可以通过在 副本的 数据库上运行以下命令来找到 PostgreSQL 的数据目录:
SHOW data_directory;
获得数据目录的位置后,运行以下命令删除所有内容:
sudo -u postgres rm -r /var/lib/postgresql/12/main/*
由于目录中文件的默认所有者是 postgres 用户,因此您需要使用 sudo -u postgres
以 postgres
身份运行命令。
注意: 如果在极少数情况下目录中的文件损坏并且命令不起作用,请一起删除 main
目录并使用适当的权限重新创建它,如下所示:
sudo -u postgres rm -r /var/lib/postgresql/12/main sudo -u postgres mkdir /var/lib/postgresql/12/main sudo -u postgres chmod 700 /var/lib/postgresql/12/main
现在 副本的 数据目录为空,您可以对 主节点的 数据文件进行物理备份。 PostgreSQL 方便地拥有实用程序 pg_basebackup
来简化流程。 它甚至允许您使用 -R
选项将服务器置于待机模式。
在replica上执行pg_basebackup
命令如下:
sudo -u postgres pg_basebackup -h primary-ip-addr -p 5432 -U test -D /var/lib/postgresql/12/main/ -Fp -Xs -R
-h
选项指定非本地主机。 在这里,您需要输入带有 primary 集群的服务器的 IP 地址。-p
选项指定它连接到 primary 服务器上的端口号。 默认情况下,PostgreSQL 使用端口:5432
。-U
选项允许您指定连接到 primary 集群的用户。 这是您在上一步中创建的角色。-D
标志是备份的输出目录。 这是您之前清空的 副本的 数据目录。-Fp
指定要以纯格式而不是tar
文件输出的数据。-Xs
流式传输 WAL 日志的内容,因为执行了 primary 的备份。- 最后,
-R
在 副本的 数据目录中创建一个名为standby.signal
的空文件。 这个文件让你的 replica 集群知道它应该作为备用服务器运行。-R
选项还将有关 primary 服务器的连接信息添加到postgresql.auto.conf
文件中。 这是一个特殊的配置文件,每当读取常规postgresql.conf
文件时都会读取它,但.auto
文件中的值会覆盖常规配置文件中的值。
当 pg_basebackup
命令连接到 primary 时,将提示您输入您在上一步中创建的角色的密码。 根据 primary 数据库集群的大小,复制所有文件可能需要一些时间。
您的 replica 现在将拥有开始复制所需的 primary 中的所有数据文件。 接下来,您将把 replica 置于待机模式并开始复制。
第 4 步 - 重新启动和测试集群
既然primary集群的数据文件已经成功备份到replica上,下一步就是重启replica数据库集群,使其进入standby模式. 要重新启动 replica 数据库,请运行以下命令:
sudo systemctl restart postgresql@12-main
如果您的 replica 集群在待机模式下成功重启,它应该已经连接到您另一台机器上的 primary 数据库集群。 要检查 replica 是否已连接到 primary 并且 primary 是否正在流式传输,请运行以下命令连接到 primary 数据库集群:
sudo -u postgres psql
现在查询primary数据库集群上的pg_stat_replication
表如下:
SELECT client_addr, state FROM pg_stat_replication;
在 primary 集群上运行此查询将输出类似于以下内容的内容:
Output client_addr | state ------------------+----------- your_replica_IP | streaming
如果您有类似的输出,则 primary 正确地流式传输到 副本 。
结论
您现在有两台 Ubuntu 20.04 服务器,每台服务器都有一个 PostgreSQL 12 数据库集群,它们之间运行物理流。 现在对 primary 数据库集群所做的任何更改也将出现在 replica 集群中。
如果您的数据库需要处理更多流量,您还可以在设置中添加更多副本。
如果您想了解有关物理流复制的更多信息,包括如何设置同步复制以确保丢失任何关键任务数据的可能性为零,您可以阅读官方 PostgreSQL 文档 中的条目。
您可以查看我们的 PostgreSQL 主题页面 以获取更多教程和内容。