3.8. 通过持续存档来备份 PostgreSQL 数据
PostgreSQL 将对数据库的数据文件所做的每个更改都记录到预写日志(WAL)文件中,该文件位于集群数据目录的 pg_wal/
子目录中。此日志主要用于崩溃恢复。崩溃后,可用上次检查点以后所记录的日志条目将数据库恢复到一致。
持续归档方法也称为在线备份,以在运行的服务器上执行的基础备份或文件系统级备份的形式,将 WAL 文件与数据库集群的副本结合起来。
如果需要进行数据库恢复,您可以从数据库集群的副本恢复数据库,然后从备份的 WAL 文件中重新执行日志,使系统恢复到当前状态。
使用持续归档方法时,您必须保持所有归档的 WAL 文件的连续顺序,这些文件至少可扩展到上一次基础备份的开始时间。因此,基本备份的理想频率取决于:
- 归档 WAL 文件的存储卷。
- 需要恢复时数据恢复的最可能持续时间。自上次备份以来的很长一段时间,系统重新运行了更多 WAL 段,因此恢复需要更长的时间。
您不能使用 pg_dump
和 pg_dumpall
SQL 转储作为持续归档备份解决方案的一部分。SQL 转储生成逻辑备份,但所包含的信息不足以供WAL重新执行。
3.8.1. 持续归档的优点和缺陷 复制链接链接已复制到粘贴板!
与其他 PostgreSQL 备份方法相比,持续归档具有以下优点:
- 使用持续备份方法时,可以使用不完全一致的基础备份,因为备份中的任何内部不一致都可以被重新执行日志所修正。因此,您可以对运行的 PostgreSQL 服务器执行基础备份。
-
不需要文件系统快照;
tar
或类似的归档工具就足够了。 - 持续备份可以通过继续归档 WAL 文件来实现,因为日志重播的 WAL 文件序列可能会无限期地延长。这对大型数据库尤其重要。
- 持续备份支持点恢复。不需要将 WAL 条目重新显示到结尾。可在任何时间点停止重新执行,并且数据库可以恢复到执行基础备份以后的任何状态。
- 如果已经加载了相同的基础备份文件的另一台机器可以连续使用WAL文件系列,那么可以在任何时候用数据库几乎当前的副本来恢复其它机器。
与其他 PostgreSQL 备份方法相比,持续归档有以下缺点:
- 持续备份方法只支持恢复整个数据库集群,而不是子集。
- 持续备份需要广泛的归档存储。
3.8.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/00000001000000A900000065
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 对每个归档的新文件都会生成类似的命令。
注意归档命令只对已完成的 WAL 段执行。生成小 WAL 流量的服务器在交易完成和其归档存储中的安全记录之间可能会有很长时间的延迟。要限制未归档数据可保留多久,您可以:
-
设置
archive_timeout
参数,来强制服务器以给定频率切换到新的 WAL 段文件。 -
使用
pg_switch_wal
参数强制段切换,以确保交易在完成后立即归档。
-
设置
-
将
重启
postgresql
服务以使修改生效:systemctl restart postgresql.service
# systemctl restart postgresql.service
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 测试您的归档命令,并确保它不会覆盖现有的文件,如果失败,它将返回一个非零退出状态。
- 要保护您的数据,请确保将段文件归档到不具有组或全局读权限的目录中。
3.8.3. 进行基础备份 复制链接链接已复制到粘贴板!
您可以通过多种方法创建基础备份:执行基础备份的最简单方法是对运行的 PostgreSQL 服务器使用 pg_basebackup
工具。
基础备份进程会创建一个备份历史记录文件,该文件存储在 WAL 归档区,并以基础备份所需的第一个 WAL 段文件来命名。
备份历史记录文件是一个小文本文件,其包含开始和结束时间,以及备份的 WAL 段。如果您使用标签字符串来标识关联的转储文件,那么您可以使用备份历史记录文件来确定要恢复哪个转储文件。
请考虑保留多个备份集,以确保您可以恢复数据。
先决条件
-
您必须以
postgres
超级用户身份、具有数据库管理员特权的用户身份或至少具有REPLICATION
权限的其他用户身份来运行命令。 - 您必须保留在基础备份期间和之后生成的所有 WAL 段文件。
流程
使用
pg_basebackup
工具执行基础备份。将基础备份创建为单个的文件(纯格式):
pg_basebackup -D <backup_directory> -Fp
$ pg_basebackup -D <backup_directory> -Fp
Copy 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 -z
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用您选择的备份位置替换 backup_directory。
要恢复此数据,您必须手动提取正确位置中的文件。
要指定serverpg_basebackup将与哪个数据库联系,请使用以下命令行选项:
-h
选项用来定义主机的。默认主机要么是本地主机,要么是
PGHOST
环境变量所指定的主机。-p
选项用来定义端口。默认端口是由
PGPORT
环境变量或编译后的默认值指明的。
- 基础备份进程完成后,将备份历史记录文件中指定的数据库集群副本和备份过程中使用的 WAL 段文件进行安全归档。
- 删除比基础备份中使用的 WAL 段文件数值更低的WAL段,因为这些比基础备份旧,并且不再需要进行恢复。
3.8.4. 使用持续归档备份恢复数据库 复制链接链接已复制到粘贴板!
要使用持续备份恢复数据库,请使用以下流程:
流程
停止服务器:
systemctl stop postgresql.service
# systemctl stop postgresql.service
Copy 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.service
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 服务器将进入恢复模式,并继续读取所需的存档 WAL 文件。
如果恢复因为外部错误而终止,那么可以重启服务器,它将继续进行恢复。恢复过程完成后,服务器将
restore.conf
重命名为restore.done
。这可以防止服务器在启动正常的数据库操作后意外重新进入恢复模式。检查数据库的内容,以验证数据库是否已恢复到所需的状态。
如果数据库尚未恢复到所需状态,请返回到第 1 步。如果数据库已恢复到所需的状态,那么通过恢复
pg_hba.conf
文件中的客户端身份验证配置来允许用户进行连接。