跳转到内容

PostgreSQL/复制

来自维基教科书,开放的书籍,开放的世界


复制是将数据更改从一个或多个数据库(主库)传输到一个或多个运行在其他节点上的其他数据库(备库)的过程。复制的目的是

  • 高可用性:如果一个节点出现故障,另一个节点会代替它,应用程序可以持续工作。
  • 扩展:工作负载需求可能对单个节点来说过高。因此,它被分散到多个节点。

PostgreSQL 提供了一系列在很大程度上相互独立的概念,用于复制解决方案。它们可以根据用例进行选择和组合,仅受少量限制。

事件

  • 基于触发器的复制中,一个触发器(每个表)启动更改数据的传输。这种技术已经过时,不再使用。
  • 基于日志的复制中,传输描述数据更改的信息,这些信息在 WAL 文件中创建和存储。

传输

  • WAL 文件传输复制(或基于文件的复制)表示将完全填充的 WAL 文件(16 MB)从主库传输到备库。这种技术不够优雅,随着时间的推移将被流式复制取代。
  • 流式复制表示通过 TCP 连接将日志记录(单个更改信息)从主库传输到备库。

主要参数:备用服务器上的 recovery.conf 中的 'primary_conninfo'。

格式

  • 物理格式中,传输的 WAL 记录与它们在 WAL 文件中使用的结构相同。它们反映了数据库文件结构,包括块号、VACUUM 信息等等。
  • 逻辑格式是对 WAL 记录的解码,解码成一个抽象的格式,该格式独立于 PostgreSQL 版本和硬件平台。

主要参数:主服务器上 postgres.conf 中的 'wal_level=logical'。

同步方式

  • 异步复制中,数据被传输到不同的节点,而无需等待其接收确认。
  • 同步复制中,数据传输在 COMMIT 情况下会等待备用服务器对其成功处理的确认。

主要参数:主服务器上 postgres.conf 中的 'synchronous_standby_names'。

备用模式

  • 热备用:在热备用模式下,备用服务器在 'recovery 模式' 下运行,接受客户端连接并处理它们的只读查询。
  • 暖备用:在暖备用模式下,备用服务器在 'recovery 模式' 下运行,不允许客户端连接。
  • 冷备用:虽然这不是官方的 PostgreSQL 术语,但冷备用模式可以与使用日志传输技术的非运行备用服务器相关联。WAL 文件被传输到备用服务器,但不会在备用服务器启动之前进行处理。

主要参数:备用服务器上 recovery.conf 中的 'hot_standby=on/off'。

架构
与上述类别不同,两种不同的架构(主备多主)并不严格区分。例如,如果你关注多主架构中的原子复制通道,你也会看到主备复制。

  • 主备架构表示一个或多个备用节点从一个主节点接收更改数据的情况。在这种情况下,备用节点可能会将接收到的数据复制到其他节点,因此它们同时是主库和备库。
  • 多主架构表示一个或多个备用节点从多个主节点接收更改数据的情况。

有 3 个主要的配置文件

  • 'postgres.conf'
  • 'pg_hba.conf'
  • 'recovery.conf'

'postgres.conf' 是主要的配置文件。它用于配置主服务器。备用服务器上可能存在其他实例。

'pg_hba.conf' 是安全和身份验证配置文件。

recovery.conf 以前是可选的,包含恢复和恢复配置。从 PostgreSQL-12 开始,它不再使用,它的存在会阻止服务器启动。从 PostgreSQL-12 开始,recovery.conf 设置可以在 postgres.conf 中设置。

由于概念和相关配置值的众多组合可能在开始时令人困惑,因此本书将重点关注一组最小的初始配置值。

传输方式:WAL 文件传输 vs 流式传输

[编辑 | 编辑源代码]

WAL 文件的生成是必要的,因为它们在崩溃后恢复时是必需的。如果它们被进一步用于将信息传输到备用服务器,则需要在文件中添加更多信息。这可以通过将 'replica' 或 'logical' 作为 wal_level 的值来激活。

# WAL parameters on MASTER's postgres.conf
wal_level=replica                   # 'archive' | 'hot_standby' in versions prior to PG 9.6
archive_mode=on                     # activate the feature
archive_command='scp ...'           # the transfer-to-standby command (or to an archive location, which is the original purpose of this command)

如果将传输技术从 WAL 文件传输切换到流式传输,则不能停用 WAL 文件生成和传输。出于安全原因,你可能仍然希望将 WAL 文件传输到备用服务器之外的其他平台。因此,除了流式复制参数之外,你可以保留上述参数。

流式传输活动由备用服务器启动。当它在启动时找到 'recovery.conf' 文件时,它会假设需要执行恢复。在我们进行复制的情况下,它使用与从崩溃中恢复时几乎相同的技术。'recovery.conf' 中的参数建议它在实例中启动一个所谓的 WAL 接收器进程。该进程连接到主服务器,并在那里启动一个 WAL 发送器进程。这两个进程在无休止的循环中交换信息,而备用服务器保持在 'recovery 模式' 下。

操作系统级别的授权应通过交换 SSH 密钥来完成。

#  Parameters in the STANDBY's recovery.conf
standby_mode=on   # activates standby mode
# How to reach the master:
primary_conninfo='user=<replication_dbuser_at_master> host=<IP_of_master_server> port=<port_of_master_server>
                  sslmode=prefer sslcompression=1 krbsrvname=...'
# This file can be created by the pg_basebackup utility, see below

在主服务器上,必须有一个具有特殊角色 REPLICATION 的特权数据库用户

CREATE ROLE <replication_dbuser_at_master> REPLICATION ...;

主服务器必须通常接受来自备用服务器的连接,并且允许一定数量的进程。

# Allow connections from standby to master in MASTER's postgres.conf
listen_addresses ='<ip_of_standby_server>'         # what IP address(es) to listen on
max_wal_senders = 5   # no more replication processes/connections than this number

此外,必须能够对复制数据库用户进行身份验证。请注意,数据库名称的关键字 ALL 不包括复制活动的身份验证。'Replication' 是一个独立的关键字,必须明确指出。

# One additional line in MASTER's pg_hba.conf
# Allow the <replication_dbuser> to connect from standby to master
host  replication   <replication_dbuser>   <IP_of_standby_server>/32    trust

现在你已经准备好开始。首先,你必须启动主服务器。其次,你必须将完整的数据库从主服务器传输到备用服务器。最后,你可以启动备用服务器。与复制一样,数据库的传输也在备用服务器上启动。

pg_basebackup -h <IP_of_master_server> -D main --wal-methode=stream --checkpoint=fast -R

实用程序pg_basebackup 将所有内容传输到 'main' 目录(应为空),在本例中它使用流式传输方法,它在主服务器上启动一个检查点以强制执行数据库文件和 WAL 文件的一致性,并且由于 -R 标志,它生成之前提到的 recovery.conf 文件。

格式:物理 vs 逻辑

[编辑 | 编辑源代码]

从 PostgreSQL 9.4 版本开始,WAL 记录从物理格式解码到逻辑格式的功能被引入。物理格式包含 - 除其他外 - 块号、VACUUM 信息,并且取决于数据库使用的字符编码。相反,逻辑格式独立于所有这些细节 - 从概念上来说,甚至独立于 PostgreSQL 版本。解码后的记录被提供给注册的流以供使用。

这种逻辑格式提供了一些巨大的优势:传输到不同主要版本级别的数据库、不同硬件架构,甚至传输到其他写入主节点。因此,多主节点架构成为可能。此外,不需要复制整个集群:你可以选择单个数据库对象。

在 9.5 版本中,此功能并未与核心 PostgreSQL 一起发布。你需要安装一些扩展。

CREATE EXTENTION btreee_gist;
CREATE EXTENSION bdr;

由于该功能相对较新,我们不会提供详细信息,请参考 [文档](https://postgresql.ac.cn/docs/current/static/logicaldecoding.html)。还有一个重要的项目 [双向复制](http://bdr-project.org/docs/stable/index.html) 基于此技术。

同步:同步 vs. 异步

[编辑 | 编辑源代码]

默认行为是异步复制。这意味着,传输的数据在备用服务器上进行处理,而不与主节点同步,即使在提交(COMMIT)的情况下也是如此。与这种行为相反,同步复制的主节点会在将提交(COMMIT)语句确认给其客户端之前,等待备用节点成功处理这些语句。

同步复制通过参数 'synchronous_standby_names' 激活。它的值标识那些需要同步的备用服务器。'*' 表示所有备用服务器。

# master's postgres.conf file
synchronous_standby_names = '*'

备用模式:热 vs. 暖

[编辑 | 编辑源代码]

只要备用服务器正在运行,它就会持续处理传入的更改信息,并将这些信息存储在它的数据库中。如果不需要处理来自应用程序的请求,它应该以暖备用模式运行。这种行为在 recovery.conf 文件中强制执行。

# recovery.conf on standby server
hot_standby = off

如果要允许客户端连接,它必须以热备用模式启动。在这种模式下,允许客户端进行只读访问 - 写操作被拒绝。

# recovery.conf on standby server
hot_standby = on

为了在主节点端生成足够的信息以供备用节点的热备用模式使用,它的 WAL 级别也必须是 replica 或更高。

# postgres.conf on master server
wal_level = replica

典型用例

[编辑 | 编辑源代码]

我们提供一些上述概念的典型组合,并展示它们的优缺点。

暖备用 + 日志传送

[编辑 | 编辑源代码]

在这种情况下,主节点使用完全填充的 WAL 文件(16 MB)将更改数据的相关信息发送给备用节点。备用节点持续处理传入的信息,这意味着在主节点上进行的更改会在一段时间后在备用节点上可见。

要构建这种场景,你需要执行与 [带 PITR 的备份](/wiki/PostgreSQL/BackupAndRecovery#Physical_Backup_plus_PITR) 非常类似的步骤。

  • 执行完全相同的物理备份,如 [带 PITR 的备份](/wiki/PostgreSQL/BackupAndRecovery#Physical_Backup_plus_PITR) 中所述,并将备份传输到备用节点。
  • 在主节点端,postgres.conf 必须指定 wal_level=replica; archive_mode=on,以及一个用于将 WAL 文件传输到备用节点端的 copy 命令。
  • 在备用节点端,中心步骤是创建一个包含 standby_mode='on' 行的 recovery.conf 文件。这是备用节点在启动后执行“无限恢复过程”的标志。
  • recovery.conf 必须包含一些其他的定义:restore_command, archive_cleanup_command

通过这种参数化,主节点将完全填充的 WAL 文件复制到备用节点。备用节点通过将更改信息复制到其数据库文件来处理接收到的 WAL 文件。这种行为与崩溃后的恢复非常相似。不同之处在于,恢复模式在处理完最后一个 WAL 文件后不会结束,备用节点会等待下一个 WAL 文件的到来。

你可以将产生的 WAL 文件复制到许多服务器,并在每个服务器上激活暖备用。这样做,你就可以获得许多备用节点。

热备用 + 日志传送

[编辑 | 编辑源代码]

与暖备用场景相比,这种方案提供了一个非常有价值的功能:应用程序可以在备用节点以备用模式运行时连接到它并发送读取请求。

为了实现这种情况,你需要在主节点端将 wal_level 增加到 hot_standby。这将在 WAL 文件中添加一些额外的信息。在备用节点端,你需要在 postgres.conf 中添加 hot_standby=on。启动后,备用节点不仅会处理 WAL 文件,还会接受和响应来自客户端的读取请求。

热备用的主要用例是负载均衡。如果存在大量读取请求,你可以通过将这些请求委托给一个或多个备用服务器来减少主节点的负载。这种解决方案可以很好地扩展到大量并行工作的备用服务器。

这两个场景(冷/热 + 日志传送)都有一个共同的缺点:传输数据的量始终为 16 MB。根据主节点上更改的频率,启动传输可能需要很长时间。下一章将介绍一种没有此缺点的技术。

热备用 + 流式复制

[编辑 | 编辑源代码]

使用文件将信息从一台服务器传输到另一台服务器 - 如上述日志传送场景中所示 - 存在许多缺点,因此有点过时了。在运行在不同节点上的程序之间进行直接通信更复杂,但提供了显著的优势:通信速度快得多,在很多情况下,传输数据的量更小。为了获得这些好处,PostgreSQL 实施了 流式复制技术,该技术通过 TCP 连接主节点和备用节点。这种技术添加了两个额外的进程:主节点端的 WAL 发送器 进程和备用节点端的 WAL 接收器 进程。它们交换有关主节点数据库中数据更改的信息。

通信由备用节点启动,必须使用具有 REPLICATION 权限的数据库用户运行。该用户必须在主节点端创建,并在主节点的 pg_hba.conf 文件中授权。主节点必须总体上接受来自备用节点的连接,并接受一定数量的进程。操作系统级别的授权应该通过交换 SSH 密钥来完成。

Master site:
============

-- SQL
CREATE ROLE <replication_dbuser_at_master> REPLICATION ...;

# postgresql.conf: allow connections from standby to master
listen_addresses ='<ip_of_standby_server>'         # what IP address(es) to listen on
max_wal_senders = 5   # no more replication processes/connections than this number
# make hot standby possible
wal_level = replica   # 'hot_standby' in versions prior to PG 9.6

# pg_hba.conf: one additional line (the 'all' entry doesn't apply to replication)
# Allow the <replication_dbuser> to connect from standby to master
host  replication   <replication_dbuser>   <IP_of_standby_server>/32    trust


Standby site:
=============

# recovery.conf (this file can be created by the pg_basebackup utility, see below)
standby_mode=on   # activates standby mode
# How to reach the master:
primary_conninfo='user=<replication_dbuser_at_master_server> host=<IP_of_master_server> port=<port_of_master_server>
                  sslmode=prefer sslcompression=1 krbsrvname=...'

# postgres.conf: activate hot standby
hot_standby = on

现在你已经准备好了。首先,你需要启动主节点。其次,你需要将主节点的完整数据库传输到备用节点。最后,你启动备用节点。与复制活动一样,数据库的传输也是由备用节点启动的。

pg_basebackup -h <IP_of_master_server> -D main --wal-method=stream --checkpoint=fast -R

实用程序 pg_basebackup 将所有内容传输到 'main' 目录(应该是空的),在这种情况下,它使用流式方法,它在主节点端启动一个检查点以强制执行数据库文件和 WAL 文件的一致性,并且由于 -R 标志,它会生成前面提到的 recovery.conf 文件。

激活“热”备用与之前的用例完全相同。

其他工具

[编辑 | 编辑源代码]

如果你需要管理复杂的复制用例,你可能想查看开源项目 [repmgr](https://repmgr.org/)。它可以帮助你监控节点集群或执行故障转移。


华夏公益教科书