4.6. 备份 PostgreSQL 数据
要备份 PostgreSQL 数据,请使用以下方法之一:
- SQL 转储
- 文件系统级别备份
- 持续归档
4.6.1. 使用 SQL 转储备份 PostgreSQL 数据 复制链接链接已复制到粘贴板!
SQL 转储方法基于使用 SQL 命令生成转储文件。当转储上传回数据库服务器时,它会按与转储时相同的状态重新创建数据库。
以下 PostgreSQL 客户端应用程序为 SQL 转储提供了保证:
- pg_dump 转储单个数据库,而没有集群范围的有关角色或表空间的信息
- pg_dumpall 转储给定集群中的每个数据库,并保留集群范围的数据,如角色和表空间定义。
默认情况下,pg_dump 和 pg_dumpall 命令将它的们结果写入标准输出。要将转储保存到文件中,请将输出重定向到 SQL 文件。生成的 SQL 文件可以是文本格式,也可以是允许并行且可以更详细地控制对象恢复的其他格式。
您可以在任何可访问数据库的远程主机中执行 SQL 转储。
4.6.1.1. SQL 转储的优点和缺陷 复制链接链接已复制到粘贴板!
与其它 PostgreSQL 备份方法相比,SQL 转储具有以下优点:
- SQL 转储是唯一的、不针对特定服务器版本的 PostgreSQL 备份方法。pg_dump 工具的输出可以重新加载到 PostgreSQL 的后续版本中,这不适用于文件系统级备份或持续归档。
- SQL 转储是将数据库传输到不同计算机架构(比如从 32 位服务器传输到 64 位服务器)的唯一方法。
- SQL 转储提供内部一致的转储。转储表示 pg_dump 开始运行时的数据库的快照。
- pg_dump 工具在运行时不会阻止对数据库的其他操作。
SQL 转储的一个缺点是,与文件系统级备份相比,它需要更长的时间。
4.6.1.2. 使用 pg_dump 执行 SQL 转储 复制链接链接已复制到粘贴板!
要转储一个没有集群范围信息的单个数据库,请使用 pg_dump 工具。
先决条件
-
您必须对要转储的所有表具有读的权限。若要转储整个数据库,您必须以
postgres超级用户或具有数据库管理员特权的用户身份运行命令。
流程
转储没有集群范围信息的数据库:
pg_dump dbname > dumpfile
$ pg_dump dbname > dumpfileCopy to Clipboard Copied! Toggle word wrap Toggle overflow 要指定 pg_dump 将联系哪个数据库服务器,请使用以下命令行选项:
-h选项用来定义主机的。默认主机要么是本地主机,要么是
PGHOST环境变量所指定的主机。-p选项用来定义端口。默认端口是由
PGPORT环境变量或编译后的默认值指明的。
4.6.1.3. 使用 pg_dumpall 执行 SQL 转储 复制链接链接已复制到粘贴板!
要转储给定数据库集群中的每个数据库,并保留集群范围的数据,请使用 pg_dumpall 工具。
先决条件
-
您必须以
postgres超级用户或具有数据库管理员特权的用户身份运行命令。
流程
转储数据库集群中的所有数据库,并保留集群范围的数据:
pg_dumpall > dumpfile
$ pg_dumpall > dumpfileCopy to Clipboard Copied! Toggle word wrap Toggle overflow
要指定 pg_dumpall 将联系哪个数据库服务器,请使用以下命令行选项:
-h选项用来定义主机的。默认主机要么是本地主机,要么是
PGHOST环境变量所指定的主机。-p选项用来定义端口。默认端口是由
PGPORT环境变量或编译后的默认值指明的。-l选项用来定义默认数据库。这个选项使您能够选择一个与初始化过程中自动创建的
postgres数据库不同的默认数据库。
4.6.1.4. 使用 pg_dump 恢复转储的数据库 复制链接链接已复制到粘贴板!
要从使用 pg_dump 工具转储的 SQL 转储恢复数据库,请按照以下流程。
先决条件
-
您必须以
postgres超级用户或具有数据库管理员特权的用户身份运行命令。
流程
创建新数据库:
createdb dbname
$ createdb dbnameCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 确保所有拥有对象的用户或对转储数据库中的对象赋予了权限的用户都已存在。如果这样的用户不存在,恢复将无法重新创建具有原始所有权和权限的对象。
运行
psql工具,来恢复 pg_dump 工具创建的文本文件转储:psql dbname < dumpfile
$ psql dbname < dumpfileCopy to Clipboard Copied! Toggle word wrap Toggle overflow 其中
dumpfile是pg_dump命令的输出。要恢复非文本文件转储,请使用pg_restore工具:pg_restore non-plain-text-file
$ pg_restore non-plain-text-fileCopy to Clipboard Copied! Toggle word wrap Toggle overflow
4.6.1.5. 使用 pg_dumpall 恢复转储的数据库 复制链接链接已复制到粘贴板!
要从使用 pg_dumpall 工具转储的数据库集群中恢复数据,请按照以下步骤。
先决条件
-
您必须以
postgres超级用户或具有数据库管理员特权的用户身份运行命令。
流程
- 确保所有拥有对象的用户或对转储数据库中的对象赋予了权限的用户都已存在。如果这样的用户不存在,恢复将无法重新创建具有原始所有权和权限的对象。
运行 psql 工具来恢复由 pg_dumpall 工具创建的文本文件转储:
psql < dumpfile
$ psql < dumpfileCopy to Clipboard Copied! Toggle word wrap Toggle overflow 其中
dumpfile是pg_dumpall命令的输出。
4.6.1.6. 在另一服务器上执行数据库的 SQL 转储 复制链接链接已复制到粘贴板!
将数据库从一台服务器直接转储到另一台服务器是可能的,因为 pg_dump 和 psql 可以写入管道并从管道读取。
流程
要从一个服务器到另一个服务器转储数据库,请运行:
pg_dump -h host1 dbname | psql -h host2 dbname
$ pg_dump -h host1 dbname | psql -h host2 dbnameCopy to Clipboard Copied! Toggle word wrap Toggle overflow
4.6.1.7. 在恢复过程中处理 SQL 错误 复制链接链接已复制到粘贴板!
默认情况下,如果出现 SQL 错误,psql 会继续执行,从而导致数据库只部分恢复。
要修改默认行为,在恢复转储时使用以下任一方法:
先决条件
-
您必须以
postgres超级用户或具有数据库管理员特权的用户身份运行命令。
流程
请设置
ON_ERROR_STOP变量,使 psql 在发生 SQL 错误时退出,且有一个为 3 的退出状态码:psql --set ON_ERROR_STOP=on dbname < dumpfile
$ psql --set ON_ERROR_STOP=on dbname < dumpfileCopy to Clipboard Copied! Toggle word wrap Toggle overflow 指定整个转储作为一个事务来恢复,以便要么全部完成,要么全部取消。
使用
psql工具恢复文本文件转储时:psql -1
$ psql -1Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用
pg_restore工具恢复非文本文件转储时:pg_restore -e
$ pg_restore -eCopy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,在使用这个方法时,即使一个小的错误也可以取消已经运行了很长时间的恢复操作。
4.6.2. 使用文件系统级别备份来备份 PostgreSQL 数据 复制链接链接已复制到粘贴板!
要创建文件系统级别备份,请将 PostgreSQL 数据库文件复制到另一个位置。例如,您可以使用以下任一方法:
- 使用 tar 工具创建归档文件。
- 使用 rsync 工具将文件复制到其它位置。
- 创建数据目录的一致快照。
4.6.2.1. 文件系统备份的优点和限制 复制链接链接已复制到粘贴板!
文件系统级别备份与其他 PostgreSQL 备份方法相比有以下优点:
- 文件系统级的备份通常比 SQL 转储要快。
与其它 PostgreSQL 备份方法相比,文件系统级备份有以下限制:
- 当您要从 RHEL 8 升级到 RHEL 9 时,这个备份方法不合适,并将您的数据迁移到升级的系统。文件系统级别备份特定于架构和 RHEL 主版本。如果升级不成功,但无法在 RHEL 9 系统中恢复数据,则可以在 RHEL 8 系统中恢复数据。
- 在备份和恢复数据前,必须关闭数据库服务器。
- 无法备份和恢复某些独立文件或表。备份文件系统只适用于完全备份和恢复整个数据库集群。
4.6.2.2. 执行文件系统级别备份 复制链接链接已复制到粘贴板!
要执行文件系统级别备份,请使用以下步骤。
流程
选择数据库集群的位置,并初始化该集群:
postgresql-setup --initdb
# postgresql-setup --initdbCopy to Clipboard Copied! Toggle word wrap Toggle overflow 停止 postgresql 服务:
systemctl stop postgresql.service
# systemctl stop postgresql.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用任意方法创建文件系统备份,如
tar归档:tar -cf backup.tar /var/lib/pgsql/data/
$ tar -cf backup.tar /var/lib/pgsql/data/Copy to Clipboard Copied! Toggle word wrap Toggle overflow 启动 postgresql 服务:
systemctl start postgresql.service
# systemctl start postgresql.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow
4.6.3. 通过持续存档来备份 PostgreSQL 数据 复制链接链接已复制到粘贴板!
PostgreSQL 将对数据库的数据文件所做的每项修改记录到预写日志(WAL)文件中,该文件位于集群数据目录的 pg_wal/ 子目录中。此日志主要用于崩溃恢复。崩溃后,可用上次检查点以后所记录的日志条目将数据库恢复到一致。
持续归档方法也称为在线备份,以在运行的服务器上执行的基础备份或文件系统级备份的形式,将 WAL 文件与数据库集群的副本结合起来。
如果需要进行数据库恢复,您可以从数据库集群的副本恢复数据库,然后从备份的 WAL 文件中重新执行日志,使系统恢复到当前状态。
使用持续归档方法时,您必须保持所有归档的 WAL 文件的连续顺序,这些文件至少可扩展到上一次基础备份的开始时间。因此,基本备份的理想频率取决于:
- 归档 WAL 文件的存储卷。
- 需要恢复时数据恢复的最可能持续时间。如果自上次备份起已有较长时间,系统会重新执行更多的 WAL 段,因此恢复需要更长的时间。
您不能将 pg_dump 和 pg_dumpall SQL 转储用作持续归档备份解决方案的一部分。SQL 转储生成逻辑备份,但所包含的信息不足以供WAL重新执行。
4.6.3.1. 持续归档的优点和缺陷 复制链接链接已复制到粘贴板!
与其它 PostgreSQL 备份方法相比,持续归档具有以下优势:
- 使用持续备份方法时,可以使用不完全一致的基础备份,因为备份中的任何内部不一致都可以被重新执行日志所修正。因此,您可以在正在运行的 PostgreSQL 服务器上执行基础备份。
-
不需要文件系统快照;
tar或类似的归档工具就足够了。 - 持续备份可以通过继续归档 WAL 文件来实现,因为日志重播的 WAL 文件序列可能会无限期地延长。这对大型数据库尤其重要。
- 持续备份支持点恢复。不需要将 WAL 条目重新显示到结尾。可在任何时间点停止重新执行,并且数据库可以恢复到执行基础备份以后的任何状态。
- 如果已经加载了相同的基础备份文件的另一台机器可以连续使用WAL文件系列,那么可以在任何时候用数据库几乎当前的副本来恢复其它机器。
与其他 PostgreSQL 备份方法相比,持续归档有以下缺点:
- 持续备份方法只支持恢复整个数据库集群,而不是子集。
- 持续备份需要广泛的归档存储。
4.6.3.2. 设置 WAL 归档 复制链接链接已复制到粘贴板!
运行的 PostgreSQL 服务器会生成一系列预写日志(WAL)记录。服务器物理上将该序列分成 WAL 段文件,这些文件被指定了数字名称,以反映它们在 WAL 序列中的位置。如果不进行 WAL 归档,段文件将被重新使用,并被重命名为更高的段号。
在归档 WAL 数据时,在重用段文件之前,都会捕获每一个段文件的内容,并将其保存在一个新的位置。您有多个保存内容的选项,例如其他机器上的 NFS 挂载目录、磁带驱动器或 CD。
请注意,WAL 记录不包括对配置文件的修改。
要启用 WAL 归档,请使用以下流程:
流程
在
/var/lib/pgsql/data/postgresql.conf文件中:-
将
wal_level配置参数设置为replica或更高的值。 -
将
archive_mode参数设置为on。 在
archive_command配置参数中指定 shell 命令。您可以使用cp命令、其它命令或 shell 脚本。例如:
archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'Copy to Clipboard Copied! Toggle word wrap Toggle overflow 其中
%p参数替换为归档文件的相对路径,%f参数替换为文件名。此命令将可归档的 WAL 段复制到
/mnt/server/archivedir/目录中。替换%p和%f参数后,执行的命令如下所示:test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065
test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065Copy to Clipboard Copied! Toggle word wrap Toggle overflow 对每个归档的新文件都会生成类似的命令。
注意归档命令只对已完成的 WAL 段执行。生成小 WAL 流量的服务器在交易完成和其归档存储中的安全记录之间可能会有很长时间的延迟。要限制未归档数据可保留多久,您可以:
-
设置
archive_timeout参数,来强制服务器以给定频率切换到新的 WAL 段文件。 -
使用
pg_switch_wal参数强制段切换,以确保交易在完成后立即归档。
-
设置
-
将
重启
postgresql服务以使修改生效:systemctl restart postgresql.service
# systemctl restart postgresql.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 测试您的归档命令,并确保它不会覆盖现有文件,如果失败了,它将返回一个非零退出状态。
- 要保护您的数据,请确保将段文件归档到不具有组或全局读权限的目录中。
4.6.3.3. 进行基础备份 复制链接链接已复制到粘贴板!
您可以通过多种方法创建基础备份:执行基础备份的最简单方法是在运行的 PostgreSQL 服务器上使用 pg_basebackup 工具。
基础备份进程会创建一个备份历史记录文件,该文件存储在 WAL 归档区,并以基础备份所需的第一个 WAL 段文件来命名。
备份历史记录文件是一个小文本文件,其包含开始和结束时间,以及备份的 WAL 段。如果您使用标签字符串来标识关联的转储文件,那么您可以使用备份历史记录文件来确定要恢复哪个转储文件。
请考虑保留多个备份集,以确保您可以恢复数据。
先决条件
-
您必须以
postgres超级用户身份、具有数据库管理员特权的用户身份或至少具有REPLICATION权限的其他用户身份来运行命令。 - 您必须保留在基础备份期间和之后生成的所有 WAL 段文件。
流程
使用
pg_basebackup工具执行基础备份。将基础备份创建为单个的文件(纯格式):
pg_basebackup -D backup_directory -Fp
$ pg_basebackup -D backup_directory -FpCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用您选择的备份位置替换 backup_directory。
如果您在与服务器相同的主机上使用表空间并执行基础备份,那么也必须使用
--tablespace-mapping选项,否则当试图将备份写入到同一位置时,备份将失败。将基础备份创建为一个
tar归档(tar和压缩格式):pg_basebackup -D backup_directory -Ft -z
$ pg_basebackup -D backup_directory -Ft -zCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用您选择的备份位置替换 backup_directory。
要恢复此数据,您必须手动提取正确位置中的文件。
要指定serverpg_basebackup将与哪个数据库联系,请使用以下命令行选项:
-h选项用来定义主机的。默认主机要么是本地主机,要么是
PGHOST环境变量所指定的主机。-p选项用来定义端口。默认端口是由
PGPORT环境变量或编译后的默认值指明的。
- 基础备份进程完成后,将备份历史记录文件中指定的数据库集群副本和备份过程中使用的 WAL 段文件进行安全归档。
- 删除比基础备份中使用的 WAL 段文件数值更低的WAL段,因为这些比基础备份旧,并且不再需要进行恢复。
4.6.3.4. 使用持续归档备份来恢复数据库 复制链接链接已复制到粘贴板!
要使用持续备份来恢复数据库,请使用以下流程:
流程
停止服务器:
systemctl stop postgresql.service
# systemctl stop postgresql.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow 将必要的数据复制到临时位置。
最好复制整个集群数据目录和任何表空间。请注意,这需要系统上有足够的可用空间来保存现有数据库的两个副本。
如果您没有足够的空间,就保存集群的
pg_wal目录的内容,其中可能包含系统关闭前没有归档的日志。- 删除集群数据目录下的所有现有文件和子目录,并在您要使用的任何表空间的根目录下删除。
从您的基础备份恢复数据库文件。
确保:
-
恢复的文件具有正确的所有权(数据库系统用户,而不是
root)。 - 恢复的文件具有正确的权限。
-
pg_tblspc/子目录中的符号链接被正确恢复。
-
恢复的文件具有正确的所有权(数据库系统用户,而不是
删除
pg_wal/子目录中的任何文件。这些文件源自基础备份,因此已过时。如果您没有归档
pg_wal/,请重新创建它,并使其具有正确的权限。-
将你在步骤 2 中保存的任何未归档的 WAL 段文件复制到
pg_wal/中。 在集群数据目录中创建
restore.conf恢复命令文件,并在restore_command配置参数中指定 shell 命令。您可以使用cp命令、其它命令或 shell 脚本。例如:restore_command = 'cp /mnt/server/archivedir/%f "%p"'
restore_command = 'cp /mnt/server/archivedir/%f "%p"'Copy to Clipboard Copied! Toggle word wrap Toggle overflow 启动服务器:
systemctl start postgresql.service
# systemctl start postgresql.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow 服务器将进入恢复模式,并继续读取所需的存档 WAL 文件。
如果恢复因为外部错误而终止,那么可以重启服务器,它将继续进行恢复。恢复过程完成后,服务器将
restore.conf重命名为restore.done。这可以防止服务器在启动正常的数据库操作后意外重新进入恢复模式。检查数据库的内容,确保数据库已恢复到所需的状态。
如果数据库尚未恢复到所需状态,请返回到第 1 步。如果数据库已恢复到所需的状态,那么通过恢复
pg_hba.conf文件中的客户端身份验证配置来允许用户进行连接。