让首次演练刻意保持小规模
本演练创建一个玩具笔记数据库和一个附件,捕获两者,然后将它们恢复到新的数据库和目录中。使用一台一次性的 Linux 机器,搭配 PostgreSQL 17 服务器和匹配的客户端工具、Bash 和 GNU coreutils。它必须不包含生产数据,也不得与生产应用程序、外发邮件或计划任务有任何连接。仅使用本演练创建的归档。
这些命令假定有一个预配置的非超级用户数据库角色,名为 restore_lab,允许创建测试数据库,并且有一个同名操作系统登录名可以在本地认证。PostgreSQL 套接字位于 /var/run/postgresql 端口 5432。让管理员在一次性环境中准备好该账户;本指南不修改数据库访问规则。在创建任何内容之前检查端点:
psql -h /var/run/postgresql -p 5432 -U restore_lab -d postgres -c '\conninfo' &&
pg_dump --version &&
pg_restore --version
如果主机、账户或版本不符合预期,请停止。在本次首次演练中,让客户端和服务器保持相同主版本。 pg_dump 无法转储主版本高于自身的服务器,而较旧的恢复目标通常也不能保证兼容。参见 pg_dump 版本限制。分别运行每个代码块,并在出错时停止。 && 守卫可防止粘贴代码块中的后续命令在失败后继续运行;在数据库或目录创建失败后,绝不要继续下一个代码块。
创建一条记录及其对应文件
这些名称 offvps_restore_source 和 offvps_restore_target 必须未被使用。现有数据库应成为停止并选择新的隔离演练的理由,而不是删除它的理由。创建一个全新的文件系统工作区以及源数据库:
umask 077 &&
lab=$(mktemp -d "$PWD/offvps-restore.XXXXXX") &&
mkdir "$lab/source" "$lab/source/uploads" "$lab/bundle" "$lab/restore" &&
createdb -h /var/run/postgresql -p 5432 -U restore_lab \
--template=template0 offvps_restore_source
全新工作区可避免覆盖现有目录。 mktemp 会创建一个唯一目录; createdb 会从选定的模板创建一个新数据库。保存这两个标记:
psql -X -v ON_ERROR_STOP=1 -h /var/run/postgresql -p 5432 \
-U restore_lab -d offvps_restore_source \
-c "CREATE TABLE notes (
id integer PRIMARY KEY,
body text NOT NULL,
attachment text NOT NULL
);
INSERT INTO notes VALUES (1, 'restore-marker-01', 'marker.txt');" &&
printf '%s\n' 'restore-marker-01' > "$lab/source/uploads/marker.txt"
记录说明哪个文件属于该笔记,并且两者包含相同标记。这样可以直观发现缺失附件或不匹配的副本。 -X 避免个人 psql 启动设置,并且 ON_ERROR_STOP 在 SQL 错误时停止;参见 psql 脚本选项。没有应用程序写入这个玩具数据集。
将数据库和文件捕获为一个恢复集
pg_dump -h /var/run/postgresql -p 5432 -U restore_lab \
--format=custom --file="$lab/bundle/notes.dump" offvps_restore_source &&
cp -a "$lab/source/uploads" "$lab/bundle/uploads" &&
pg_restore --list "$lab/bundle/notes.dump"
自定义格式归档由 pg_restore读取;纯 SQL 转储遵循不同的恢复过程。列出归档内容有助于确认预期的表和数据条目存在。一致的数据库转储不会自动同步外部上传。对于真实应用,请使用其文档化的维护或写入暂停流程,使文件树和数据库描述同一时间点。玩具演练本身已经处于安静状态。
在捆绑包旁记录数据库版本、应用发布、捕获开始/结束时间和文件路径。将真实凭据单独保存在适当访问控制之下。按数据库转储不会捕获全局角色和表空间;真实恢复计划也必须考虑这些。范围说明见 PostgreSQL 的 SQL 转储指南.
恢复到新目标,而不清理现有目标
createdb -h /var/run/postgresql -p 5432 -U restore_lab \
--template=template0 offvps_restore_target &&
pg_restore -h /var/run/postgresql -p 5432 -U restore_lab \
--dbname=offvps_restore_target --no-owner --no-acl \
--single-transaction "$lab/bundle/notes.dump" &&
mkdir "$lab/restore/uploads" &&
cp -a "$lab/bundle/uploads/." "$lab/restore/uploads/"
目标数据库创建为空。恢复有意省略 --clean,因为这可能删除现有对象。 --single-transaction 使这个小型数据库恢复要么作为整体成功,要么停止且不应用其部分更改;它不能与并行作业结合使用。 --no-owner 和 --no-acl 为这个测试角色简化所有权,因此本次演练不会验证生产应用的角色或权限。参见 pg_restore.
文件复制到新的恢复目录,源保持完整。GNU cp -a 尝试保留文件属性;检查将运行真实应用的账户的所有权和访问权限。复制字节并不能测试应用权限。参见 cp 的归档选项.
检查关系,而不只是退出代码
psql -X -h /var/run/postgresql -p 5432 -U restore_lab \
-d offvps_restore_target -c "SELECT id, body, attachment FROM notes;" &&
cat "$lab/restore/uploads/marker.txt"
预期结果为一行,ID 为 1,正文为 restore-marker-01 以及附件 marker.txt,外加一个包含 restore-marker-01的文件。检查源仍然包含其原始行和文件。对于真实应用,还应将一个隔离实例指向恢复后的数据库和上传目录,打开代表性记录、获取一个附件并测试预期登录权限。在此过程中保持回调、邮件和作业受限。
写下你证明了什么以及还有什么待完成
| 记录 | 要捕获的内容 |
|---|---|
| 恢复点 | 捕获时间和预期的最新记录 |
| 恢复时长 | 开始/结束时间和手动步骤 |
| 检查 | 数据库行、附件内容和应用程序检查 |
| 例外情况 | 缺失的角色、权限、配置或依赖项 |
| 下次演练 | 由模式、存储或部署变更等触发 |
上述预期输出是演练标准,而不是 OffVPS 已经观察到的结果。由于首次演练将所有文件保留在一台机器上,它无法防止该机器丢失。真实计划需要在单独故障域中拥有受保护的副本、可用的解密密钥、保留策略和经过测试的检索路径。在之后清理前,请核对确切的临时数据库名称和目录;让生产环境远离该过程。
在重要变更后重复演练,并像记录成功一样仔细记录失败。可选的备份服务不能证明你应用的恢复时间。继续 规划计划任务 当你准备好自动化捕获时,同时保留单独的恢复演练。
使用的文档
本页的主要参考资料。检查您自己环境中安装版本的文档。