二进制复制教程
欢迎来到新的 PostgreSQL 9 复制和备用数据库指南。这套新的功能实现了 PostgreSQL 历史上可能最受期待的功能。因此,许多人将首次尝试部署备用数据库,并发现该过程相当不直观。本指南旨在提供帮助。
本教程不完整且已过时
注意:与流式复制页面存在一些重复
5 分钟完成简单复制
这是在主服务器和备用服务器之间设置复制的最简单方法。它需要关闭主服务器;其他方法将在本指南后面的部分中详细介绍。
我们将要做的是关闭主服务器并将所需的文件复制到备用服务器,创建主服务器的克隆副本。由于主服务器已关闭,因此不必担心对主服务器进行更改。
注意:以下的“5 分钟”说明和“10 分钟”版本都没有处理使用表空间的数据库中出现的复杂情况,尤其是如何处理 pg_tblspc 目录及其内容。
先决条件
您必须具备正确的设置才能使其正常工作
- 2 台具有相似操作系统的服务器(例如,两台 Linux 64 位,相同版本的 glibc)。
- 两台服务器上都安装了相同版本的 PostgreSQL 9.0。
- 两台服务器上的 PostgreSQL 超级用户 shell 访问权限。
- 了解如何启动、停止和重新加载 Postgres。
- Server1 上运行着 PostgreSQL 9.0。
- 在 Server1 上创建并加载了一个数据库。
- 具有网络访问权限的 postgres 用户或 root 用户
有关更多信息,请参阅完整文档
7 步完成二进制复制
本 6 步指南以及本教程中的所有示例都假定您在 192.168.0.1 处有一台主服务器,在 192.168.0.2 处有一台备用服务器,并且您的数据库及其配置文件安装在 /var/lib/postgresql/data 中。将这些替换为您实际的服务器地址和目录。
1. 在主服务器上编辑 postgresql.conf 以启用流式复制。更改以下设置
listen_addresses = '*' wal_level = hot_standby max_wal_senders = 3
2. 在主服务器上编辑 pg_hba.conf 以允许备用服务器连接。
host replication all 192.168.0.2/32 trust
3. 在备用服务器上编辑 postgresql.conf 以设置热备。更改以下行
hot_standby = on
4. 在备用服务器上创建或编辑 recovery.conf 以设置复制和备用模式。在备用服务器的**数据目录**中保存一个名为 recovery.conf 的文件,其中包含以下行
standby_mode = 'on' primary_conninfo = 'host=192.168.0.1'
5. 关闭主服务器和备用服务器,然后复制文件。您需要将大部分(但不是全部)文件复制到两台服务器之间,排除配置文件和 pg_xlog 目录。一个示例 rsync 脚本如下
rsync -av --exclude pg_xlog --exclude postgresql.conf data/* 192.168.0.2:/var/lib/postgresql/data/
6. 首先启动备用服务器,以便它们不会不同步。(将记录有关无法连接到主服务器的消息,这是正常的。)
7. 启动主服务器。
仅通过快速主服务器重启启动复制
关闭主服务器的时间太长,无法复制文件吗?那么您需要 10 分钟版本。
这一次我们将做的事情类似于之前,通过从主服务器复制文件到备用服务器来克隆数据库。但是,由于数据库只会被关闭一小段时间(足够激活配置文件中的更改),因此在复制数据文件后,我们需要复制其他文件,以便备用服务器成为主服务器的最新副本。
因此,我们将告诉主服务器我们正在运行备份,复制数据文件(与之前复制的略有不同),告诉主服务器备份已完成,然后复制 pg_xlog 目录中的 WAL 文件,以便备用服务器启动后可以对主数据库在备份启动后提交的所有更改进行更改。
首先,从上面的相同先决条件开始。
1. 与上面的步骤 (1) 相同,设置 postgresql.conf 变量。
2. 现在不要关闭文件。您需要设置另外两个控制写前日志 (WAL) 大小的变量。第一个是 wal_keep_segments,第二个是 checkpoint_segments。除非您已经这样做,否则您需要增加这些值,这通常也是提高性能的一个好方法。您希望 WAL 足够大,不会在 15 或 20 分钟内用完。如果您对此没有明确的想法,这里给出了一些合理的值,基于您的数据库有多忙和有多大。此外,具有大型 blob 对象的数据库可能需要更大的设置。请记住,这些日志将占用磁盘空间,因此请确保您有足够的可用空间 - 空间需求如下。
checkpoint_segments = 8 wal_keep_segments = 8 # light load 500MB
checkpoint_segments = 16 wal_keep_segments = 32 # moderately busy 1.5GB
checkpoint_segments = 64 wal_keep_segments = 128 # busy server 5GB
您不必为了增加 wal_keep_segments 而增加 checkpoint_segments,但这通常是一个好主意。现在保存文件。
3. 与上面的“六步”中的 (2) 相同,编辑 pg_hba.conf。
4. 现在您需要重新启动主服务器。鉴于服务中断,您可能应该提前计划好。
5. 与上面的 (3) 相同,在备用服务器上编辑 postgresql.conf 和 recovery.conf。
6. 现在,我们需要从主服务器复制文件并启动备用服务器。与 6 步版本不同,这需要快速完成,否则备用服务器将无法同步,您需要重新尝试。第一步,您需要告诉主服务器您要开始备份(有关此操作的更详细说明,请参见下文)。以数据库超级用户身份登录 psql。
psql -U postgres # select pg_start_backup('clone',true);
请注意,您用作备份标签的字符串并不重要;使用任何您想要的字符串。
7. 现在,快速复制所有数据库文件。此 rsync 与 6 步版本略有不同
rsync -av --exclude pg_xlog --exclude postgresql.conf --exclude postgresql.pid \ data/* 192.168.0.2:/var/lib/postgresql/data/
8. 完成后,您需要停止主服务器上的备份
# select pg_stop_backup();
9. 完成后,您需要快速将 WAL 文件从主服务器复制到备用服务器。
rsync -av data/pg_xlog 192.168.0.2:/var/lib/postgresql/data/
10. 现在,启动备用服务器。
如果您足够快地完成了这些操作,那么备用服务器应该赶上主服务器,并且您应该可以进行复制。如果没有,您将收到以下消息
(Future Revisions note: Message needs to go here)
... 这意味着您需要重新尝试,可能需要将 checkpoint_segments 和 wal_keep_segments 设置得更高。如果仍然不起作用,您需要使用下面描述的更复杂的方法进行归档。
现在,指南的其余部分将解释如何处理更复杂的情况,例如归档日志、处理安全性和维护可用性、故障转移和备用服务器提升。
二进制复制简介
二进制复制也称为“热备”和“流式复制”,它们是 PostgreSQL 9.0 及更高版本中的两个独立但互补的功能。以下是一些关于它们如何工作以及用途的一般信息。
二进制复制可以做什么?
- 拥有生产数据库的简单而完整的副本,即使在灾难性情况下,也能防止除几秒钟以外的所有数据丢失。
- 在您的读写主服务器和多个只读备用服务器之间进行负载均衡。(注意:这意味着不能在备用服务器上运行非只读查询。一个常见的误解是关于在备用服务器上查找序列的“当前”值,这是不可能的。)
- 在副本服务器上运行报告或其他长时间运行的查询,将它们从主要的事务处理服务器上移开。
- 复制所有 DDL,包括表和索引更改,甚至创建新数据库。
- 复制托管的多租户数据库,对用户的主键或数据库更改没有特定要求。
二进制复制不能做什么?
- 复制特定表、模式或数据库。二进制复制是整个 Postgres 实例(或“集群”)。
- 多主复制。多主二进制复制可能在技术上不可能。
- 在不同版本的 PostgreSQL 之间或在不同平台之间进行复制。
- 在没有服务器管理权限的情况下设置复制。抱歉,正在努力改进。
- 同步复制数据,保证零数据丢失。并且... 自 PostgreSQL 9.1 发布以来,这里就有了这个功能!
由于上述原因,我们预计 Slony-I、Londiste、Bucardo、pgPool2 和其他系统将继续使用。
事务日志和日志传送
已经熟悉 PostgreSQL 事务日志和热备的用户可以跳过本节。
单个“实例”、“服务器”或(令人困惑的是)PostgreSQL 的“集群”(以下简称服务器)包含一个连接到单个初始化的 PostgreSQL 数据目录 (PGDATA) 的单个后主服务器进程,而该数据目录又包含多个数据库。每个运行的服务器都有一个事务日志,位于 PGDATA/pg_xlog 目录中。此事务日志包含数据的二进制快照,用于同步记录对所有数据库数据的每次更改,以防数据库服务器意外关闭(例如,电源故障)。这确保数据不会损坏,并且不会丢失任何已完成的事务。
您还可以使用此日志来允许原始数据库的副本复制对主数据库所做的更改。这最早是在 PostgreSQL 8.0 中使用 PITR 功能实现的,被称为“日志传送”。日志传送对于大多数形式的二进制复制都是必需的。
此日志由 16 MB 的日志段组成,这些日志段包含数据库的新数据页(8 KB 的段),而不是 SQL 语句。因此,无法通过此日志进行审计,因为你无法准确知道发生了哪些更改。此外,日志被视为缓冲区,在不再需要用于崩溃恢复时被删除。更重要的是,日志的数据页格式意味着日志段只能应用于与创建日志的数据库二进制相同的数据库。
PITR、温备、热备和流式复制
在本教程的剩余部分,我们将把生成事务日志的服务器的活动读写实例称为“主服务器”,并将接收事务日志的被动、只读或脱机实例(或实例)称为“备用服务器”(或“备用服务器”)。主服务器/备用服务器术语等同于数据库行业中可能使用的其他术语,例如主服务器/从服务器、主服务器/副本或主服务器/从服务器。
PITR
在时间点恢复 (PITR) 中,事务日志会被复制并保存到存储设备中,直到需要时为止。然后,在需要时,可以“启动”备用服务器(使其变为活动状态)并应用事务日志,要么在日志用完时停止,要么在管理员指示的先前点停止。PITR 自 PostgreSQL 8.0 版本开始可用,因此此处不再进行介绍。
PITR 主要用于数据库取证和恢复。当需要备份非常大的数据库时,它也很有用,因为它有效地支持增量备份,而 pg_dump 不支持增量备份。
温备
在温备中,事务日志会从主服务器复制到备用服务器,并在接收后立即应用,或稍后应用。备用服务器处于脱机状态(处于“恢复模式”),不可用于任何查询工作负载。这允许备用服务器非常快速地启动完全运行。温备自 8.3 版本开始可用,此处不再进行详细介绍。
温备需要日志传送。它主要用于数据库故障转移。
热备
热备与温备相同,区别在于备用服务器可用于运行只读查询。这提供了温备的所有优势,以及将部分业务工作负载分发到备用服务器的能力。热备本身需要日志传送。
热备既用于数据库故障转移,也可用于负载均衡。与流式复制相比,它不会给主服务器带来任何负载(除了磁盘空间要求),因此理论上可以无限扩展。可以通过网络存储将 WAL 归档分发到几十台甚至数百台服务器。WAL 文件也可以很容易地通过质量较差的网络连接或 SFTP 复制。
但是,由于热备通过传送 16 MB 的日志进行复制,因此它最多落后几分钟,有时甚至更久。这对于故障转移和负载均衡来说都是一个问题。
流式复制
流式复制通过在备用服务器和主数据库之间打开网络连接来改进温备或热备,而不是复制 16 MB 的日志文件。这使得数据更改几乎可以在主服务器上完成时立即通过网络复制。
在流式复制中,主服务器和备用服务器具有称为 walsender 和 walreceiver 的特殊进程,这些进程通过网络端口传输修改后的数据页。这要求每个备用服务器建立一个相当繁忙的连接,这会给每个额外的备用服务器带来增量负载。不过,负载相当低,一台主服务器应该能够轻松地支持多个备用服务器。
流式复制在正常运行时不需要日志传送。但是,它可能需要日志传送来启动复制,并且可以使用日志传送来追赶落后的备用服务器。
如何复制
克隆实时数据库
如果你的工作负载不允许你关闭主服务器(谁的允许呢?),事情就会变得更加复杂。你需要以某种方式获取主服务器的“一致快照”,这样你才能在备用服务器上获得一致且无错误的数据库。现在,在某些情况下,可以使用文件系统快照工具或类似的技巧来完成此操作,但由于这种方法很棘手且依赖于平台,因此我们不会在此处进行介绍。
相反,我们将介绍内置方法,该方法涉及记录在复制过程中应用于数据库的所有更改。无论你计划只使用热备、流式复制还是两者兼而有之,步骤基本上都是相同的。有两个部分
- 克隆数据库文件
- 复制归档日志
虽然很不直观,但后者需要先设置,所以我们将从这里开始。
在主服务器上设置归档
归档是将每个 WAL 文件完成时制作一份额外副本的过程。然后,备用服务器需要以某种方式访问这些日志文件。处理此问题有三种基本方法,你应该事先决定要使用哪种方法
- 手动
- 使用 rsync 或类似工具从主服务器自动复制文件到备用服务器
- 将它们写入到一个公共共享网络文件位置
第一种方法仅适用于你仅归档日志来启动流式复制,并且你的数据库流量较低或能够停止所有写入的情况。第三种方法可能是最容易管理的方法,前提是你拥有合适的网络共享;它甚至可以通过一些额外的思考和脚本编写来支持多个备用服务器。所有这些方法将在下面解释。
这需要在主服务器上启用,如果以前从未启用过,则可能需要重启(抱歉,正在努力解决),并且肯定需要重新加载。你需要设置以下参数
wal_level = hot_standby archive_mode = on archive_command = 'some command'
你使用什么归档命令取决于你采用的归档方法。以下是你可能使用的三个命令示例。请注意,你需要创建“archive”目录。
- 手动:cp -f %p /var/lib/postgresql/data/archive/%f </dev/null
- 自动复制:rsync -a %p 192.168.0.2:/var/lib/pgsql/data/archive/%f
- 网络共享:cp -f %p /shares/walarchive/archive/%f </dev/null
在这些命令中,%p 在调用时会被 postgres 替换为 WAL 文件的完整路径和名称,%f 被替换为文件的名称。还有更多转义字符和参数与 WAL 归档有关,将在本教程的后面详细介绍。请注意,在实际生产环境中,你不太可能想要使用上述任何简单命令。通常,你希望 archive_command 调用一个可执行脚本,该脚本可以捕获错误并且可以禁用。本教程中提供此类脚本的示例。
现在,如果 archive_mode 最初为“off”或你需要更改 wal_level,则需要重启主服务器(抱歉,这将在以后的版本中修复)。但是,如果你只需要更改 archive_command,则只需要重新加载即可。
重启或重新加载后,检查主服务器的日志,以确保归档正在正常工作。如果失败,主服务器将发出大量抱怨。你还可以检查是否正在创建归档日志文件;以超级用户身份运行命令“SELECT pg_switch_xlog();”以强制写入新日志。
在备用服务器上设置归档
备用服务器需要配置为使用日志。这比主服务器的设置更简单,并且无论你使用哪种归档复制策略,它都不会改变。
Recovery.conf
在备用服务器上,复制配置通过一个名为 recovery.conf 的文件进行控制。如果此文件在 PostgreSQL 启动时存在于 PostgreSQL 的数据目录中,则该服务器将假设它是一个备用服务器,并尝试遵守它。通常,在其他 PostgreSQL 共享文档中会安装一个示例文件。但是,该示例文件同时涵盖了所有各种复制选项,因此从头开始编写自己的文件通常更简单。对 recovery.conf 的任何更改都需要重启备用服务器。
在 recovery.conf 中,你需要添加一个命令来将归档的 WAL 文件复制到备用服务器的 pg_xlog 目录中。这是主服务器上 archive_command 的镜像。通常,一个简单的 cp 命令就足够了
restore_command = 'cp -f /var/lib/postgresql/data/archive/%f %p </dev/null' restore_command = 'cp -f /shares/walarchive/%f %p </dev/null'
同样,你可能希望使用一个简单的 shell 脚本,该脚本可以捕获错误消息,并且重要的是,可以删除不再需要的归档文件。如果你只进行热备而不使用流式复制,则可能希望编译 PostgreSQL 附加模块或“contrib”中提供的 pg_standby 二进制文件,并使用它代替
restore_command = 'pg_standby /shares/walarchive %f %p %r'
有关 pg_standby 的更多详细信息,请参阅其 文档。
克隆主服务器的快照
归档正常工作后,你就可以克隆主数据库了。此时,这是一个简单的过程
- 以超级用户身份,在主服务器上发出命令“SELECT pg_start_backup('backup');”。
- 将所有数据库文件复制到备用服务器。
- 启动备用数据库。
- 在主服务器上发出命令“SELECT pg_stop_backup();”。
当然,每个步骤都需要更详细的说明。pg_start_backup 和 pg_stop_backup 是你在主服务器上发出的特殊命令,用于创建、保持打开和关闭“快照”,这是我们确保你的数据库副本一致的方式。它们还会将特殊文件写入到归档日志中,告知备用服务器何时获得完整的快照。
如果你使用的是“手动”方法来同步归档日志,则在步骤 4 之后,你需要立即对归档日志执行最后一次 rsync 或复制操作,以将其复制到备用服务器。
克隆完成后,你应该看到类似于以下内容的输出
这意味着你已经启动并正在复制,现在你应该能够在备用服务器上运行查询了。
故障转移到备用服务器
当然,拥有备用服务器的主要原因之一是为了防止某些情况(计划的或意外的)导致主服务器关闭。然后,你希望“故障转移”,或者停止复制并将备用服务器更改为完全读写主服务器。
无论复制类型或备用类型如何,推荐的方法都是一样的:通过“触发文件”。首先,你需要在备用服务器的 recovery.conf 中设置一个配置选项
trigger_file = '/var/lib/postgresql/data/failover'
然后,在需要故障转移时,你只需创建一个具有该名称的空文件,例如使用“touch”命令。备用服务器将注意到该文件,尝试应用它已接收到的任何剩余 WAL 记录或文件,然后切换到读写或“主服务器”模式。发生这种情况时,你将在 Postgres 日志中看到类似于以下内容的消息
PostgreSQL 还会将 recovery.conf 文件重命名为 recovery.done,以防止新的主服务器在重启时发生故障。因此,recovery.conf 文件应由运行服务器的同一用户拥有(通常为“postgres”)。
使用触发文件的替代方法是手动故障转移,方法是删除或重命名 recovery.conf 文件并重启备用服务器。这种方法比较差,因为它需要重启,这会中断当前正在使用的备用服务器的任何只读连接。
在高可用性系统中,上述活动应自动管理以避免停机。PostgreSQL 本身没有提供执行此操作的工具,但许多第三方实用程序(如“Linux 心跳”)与 PostgreSQL 复制兼容。
重要的是要防止原始主服务器在故障转移后重新启动,否则您最终会遇到“脑裂”问题和数据丢失。对此有很多文献和第三方工具,因此我们目前不会在此处讨论。