数据库备份与诊断操作手册
本页目录
先确认数据库类型、实例、库名与备份目标。备份文件存在不是恢复成功;本篇把一致性、备份覆盖范围和隔离恢复验证放在同一条操作链中。应用内部表的迁移与删除应由该应用的受支持工具完成。
| 当前任务 | 入口 |
|---|---|
| SQLite 文件备份 | WAL 与在线备份 |
| PostgreSQL 导出恢复 | 库与全局对象 |
| MySQL / MariaDB | 事务快照的前提 |
| 自动备份是否可靠 | 恢复演练与保留策略 |
不要只复制正在使用的主数据库文件
只读确认实例、模式与结构
# 确认打开的是预期 SQLite 文件
核对 main 的真实路径;-readonly 在路径写错时不创建空数据库。后续路径保持一致。
# 读取当前日志模式以确定备份边界
返回 wal 时已提交内容可能仍在伴随 WAL 文件中;不要只复制主库,也不通过删 WAL 来“整理文件”。
# 发现实际表名,避免猜业务表
需要表结构时另用 .schema TABLE_NAME,TABLE_NAME 从这里取得;.tables/.schema 是 CLI 指令,不能作为 SQL 发给其他驱动。
路径替换为实际库。-readonly 可避免路径写错时创建空库;dot 命令是 sqlite3 客户端指令,不是 SQL。WAL 模式的已提交数据可能仍在 -wal 中,只 cp 主文件可能得到缺失数据或不一致副本;不要在活跃库上随意删 -wal/-shm。
在新的受限目录生成一致副本
# 为本次备份创建未使用的受限目录
在备份客户端的受控目录执行;db-review 已存在时换新名称并同步后续路径,不覆盖上一份副本。umask 作用于当前 shell 的后续新文件。
# 使用 SQLite backup API 读取在线库并写入新副本
heredoc 内为 sqlite3 命令;.bail on 遇错退出,.timeout 毫秒级等待锁。检查 shell 退出码,失败副本不标记为成功;源连接只读不妨碍 backup 写目标。
# 检查副本的结构一致性
正常预期输出 ok;错误需保留诊断并重新备份/恢复,不把文件存在作为成功。
# 检查副本中已定义外键的违规行
无违规时无输出;它不检查未声明的业务关系。再核对代表性记录、关键时间点和应用启动;在隔离环境中用副本启动应用,不覆盖正在使用的主库。
使用新的备份目标,避免覆盖唯一已验证副本。.backup 使用备份 API 获取一致副本,但仍可能受锁竞争影响;超时或退出失败不能当成功。integrity_check 预期为 ok,foreign_key_check 正常应无违规行;二者不能证明业务数据完整,仍需应用级核对。
单库 dump 不包含整个集群身份
PostgreSQL:先确认连接配置
客户端需已有 service=app 配置,指向源实例与数据库;凭据从受保护的 pgpass 等机制读取。restore 必须配置为另一套隔离实例。以下导出文件放入本次专用受限目录,示例文件名均不能覆盖已有副本。
# 确认源库、认证用户与服务端版本
-X 不读取个人 psqlrc,便于减少额外会话行为。客户端 pg_dump 版本需与服务端兼容,尤其不能用较旧主版本导出较新服务端。
# 导出单库为可选择恢复对象的 custom archive
检查退出码和文件大小;custom 使用 pg_restore,不交给 psql < 文件。导出期间有 DDL 或锁等待先读诊断。
# 另行导出角色和表空间等全局对象
需要相应读取权限;内容可能含敏感角色信息。隔离演练不自动执行 globals.sql,先审阅角色冲突、路径和权限;全库恢复时把它纳入专门计划。
# 检查 archive 中包含哪些对象
确认关键 schema、表、序列、函数等在预期范围;可列目录不证明数据可完整恢复。
service=app 需先在 pg_service.conf 配置,凭据放受保护的 pgpass 等机制,Unix 上 .pgpass 权限 0600。pg_dump 提供该库的一致视图,可与普通读写并行,但锁与 DDL 仍可能互相等待;不包含角色、表空间定义、服务器配置或 WAL 连续恢复链。globals 导出可能含敏感角色信息,权限和备份位置同样保护。
在隔离实例新建恢复库
# 写入前再次核对恢复实例身份
核对服务文件中的 host/socket 路径,确保不是生产实例;Unix socket 时 inet_server_addr 可能为 NULL。
# 在隔离实例创建尚不存在的空库
已存在则先检查而不直接删除。名称 app_restore 在后续恢复和验证保持一致。
# 恢复到新库,遇错停止并由恢复用户持有对象
--no-owner/--no-privileges 故意不复现源 ownership/ACL;正式恢复另行设计。失败可能已留下部分对象,应保留日志并重建新的演练库后重试,不向半成品反复叠加导入。
# 确认验证查询确实落在恢复库
随后用项目提供的只读查询比较关键记录与约束,检查扩展、序列及应用兼容性;记录恢复耗时。仅 SELECT current_database() 不算恢复验收。
性能诊断先看等待,不先杀连接
# 只读定位长事务与等待类型
state、事务开始时间与等待一起判断;取消查询 pg_cancel_backend 与断开会话 pg_terminate_backend 影响不同,需按确认的 PID 和业务意图单独执行。
restore 指向隔离测试实例,绝不是生产服务的别名。示例故意将对象归于恢复用户并不恢复原授权;正式灾难恢复需计划角色、ownership、ACL、扩展与版本兼容。不要直接在正在服务的库上使用 --clean 覆盖。性能故障先查看 pg_stat_activity 的状态、等待事件和长事务;取消单个查询与终止连接影响不同。
single-transaction 有存储引擎前提
MySQL:先准备源与恢复 login-path
以下针对 Oracle MySQL 客户端;先用 mysql_config_editor 为 app、restore 设置不同实例的登录信息,交互输入密码。MariaDB 使用匹配的 mariadb/mariadb-dump 与受保护 option file,不混用 MySQL 专有选项。
# 确认源数据库、身份和版本
--database 明确库名,避免 DATABASE() 返回 NULL 后还误以为目标已确定。
# 检查源表是否满足事务快照前提
若包含 MyISAM 等非事务表,single-transaction 不能保证它们一致,需要维护窗口/锁或对应物理备份方案。
# 为独立恢复演练导出事务库及程序对象
在专用受限目录执行,检查退出码后才接受文件。GTID OFF 是本例独立演练的选择,不适用于需要恢复复制身份的方案;DDL、DEFINER、权限和字符集需审阅。
恢复前确认另一实例,恢复后做业务检查
# 确认恢复连接指向隔离实例
同时核对 login-path 的 host/socket;服务端 hostname 不能单独证明环境隔离。
# 创建新恢复库,拒绝覆盖同名既有库
按源库字符集/collation 适配创建语句,名称已存在先停下检查。
# 仅把审阅过的 SQL 导入隔离恢复库
检查退出码和日志,再用指定 app_restore 的查询核对表、记录、例程、事件与应用。SQL 文件可能含 USE/CREATE/DEFINER 等改变目标或权限的语句,导入前必须审阅;不使用 --force 忽略错误。
login-path 需先用 mysql_config_editor 设置;MariaDB 按安装版本选 mariadb/mariadb-dump 和受保护的 option file。single-transaction 针对事务引擎(如 InnoDB),不能保证 MyISAM 表一致;导出期间避免相关 DDL。确认例程、事件、触发器、字符集、权限与 GTID/复制需求,跨版本恢复先演练。逻辑 dump 不等于二进制日志的时间点恢复。
恢复到独立环境才算验证备份
| 自动化必须记录 | 验收意义 |
|---|---|
| 开始/结束、退出码、文件大小与校验和 | 检测命令失败、空文件与传输损坏,不能替代恢复 |
| 实例、库名、版本、覆盖对象 | 避免拿错库或遗漏角色/配置 |
| 隔离恢复耗时与业务核对 | 判断 RTO 与恢复点是否满足需求 |
用 systemd timer 调度时,任务先写唯一临时文件、检查成功后在同一文件系统重命名,再传独立副本;失败不得覆盖上一份有效备份。保留策略在确认新备份可恢复后执行。Grafana 还要备份配置、插件及加密 secret key 等,不能直接修改内部 resource/history 表,见 Grafana。
SQLite backup · SQLite CLI · PostgreSQL dumps · MySQL mysqldump