¥
立即购买

数据库故障恢复操作指南

29 浏览
1 试用
0 购买
Dec 3, 2025更新

本提示词专为数据库管理员和系统运维人员设计,提供专业、系统化的数据库故障恢复解决方案。通过明确的角色设定和工作流程,能够针对不同类型的数据库制定详细的恢复步骤,涵盖故障诊断、数据恢复、完整性验证等关键环节。该提示词采用技术文档写作风格,确保输出内容结构清晰、逻辑严谨、操作性强,帮助用户在紧急情况下快速有效地恢复数据库服务,最大限度减少业务中断时间。

故障分析总结

  • 故障原因:主库所在磁盘损坏导致宕机,无法继续对外提供写服务。
  • 环境特征:MySQL 启用 GTID;存在只读从库;有最近全量备份与完整 binlog 可用。
  • 影响范围:主库写入中断;从库可读但可能尚未完全追平主库最后提交事务;需要在 15 分钟内完成主从角色切换,并用 binlog 做到最新时间点恢复,随后校验复制一致性与业务连通性。
  • 主要风险:
    • 副本未消费完中继日志或与主库有微小差距,直接提升可能丢失少量事务。
    • 在未补齐缺失事务前对外开放写入,可能与后续补齐产生冲突。
    • binlog 时间点选择错误(时区/时间边界)导致少恢复或多恢复。

恢复步骤详情

说明:

  • 下文同时给出 MySQL 8.0 新术语(SOURCE/REPLICA)与 5.7 旧术语(MASTER/SLAVE),任选与你版本相符的命令。
  • 为满足 15 分钟 RTO:先让从库完全追平可得数据,再用 binlog 精确补齐缺口,最后提升为主并切换业务。
  • 所有操作先在候选新主(当前只读从库)执行,确保有运维窗口内的应用写入冻结。
  1. 现场准备(并行进行,T+0 ~ T+2 分钟)
  • 在业务侧开启维护或将写流量切走,确保对数据库无新写入。
  • 在候选新主(从库)开启强只读保护,防止误写:
    • SET GLOBAL super_read_only = ON;
    • 确认:SELECT @@global.read_only, @@global.super_read_only;
  • 收集关键信息以便对账与恢复:
    • 记录当前 GTID 集:SELECT @@GLOBAL.gtid_executed \G
    • 记录二进制日志配置:SHOW VARIABLES LIKE 'log_bin%'; SHOW VARIABLES LIKE 'gtid%';
    • 记录复制状态:
      • SHOW SLAVE STATUS\G(5.7)
      • SHOW REPLICA STATUS\G(8.0)
  • 确认可访问“完整 binlog 存储”(归档/NAS/对象存储等),并确定主库崩溃截止时间点 T_fail(注意时区)。
  1. 让从库消费完中继日志(不再向上游拉取新日志,T+2 ~ T+4 分钟) 目的:确保已获取到的主库事务全部应用,缩小缺口。
  • 在从库停止 I/O 线程,仅保留 SQL 线程继续回放:
    • STOP SLAVE IO_THREAD; 或 STOP REPLICA IO_THREAD;
  • 读取当前已获取的 GTID 集(Retrieved_Gtid_Set):
    • SHOW SLAVE STATUS\G 中的 Retrieved_Gtid_Set(5.7)
    • SHOW REPLICA STATUS\G 中的 Retrieved_Gtid_Set(8.0)
  • 让 SQL 线程追平已获取的 GTID:
    • START SLAVE SQL_THREAD; 或 START REPLICA SQL_THREAD;
    • SELECT WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS('<Retrieved_Gtid_Set>', 60);
      • 返回 0 表示在 60 秒内追平;返回 1 表示超时,可根据 Relay 应用量决定是否适当延长等待。
  • 全部追平后,停止复制(冻结状态以便做 PITR):
    • STOP SLAVE; 或 STOP REPLICA;
  1. 基于 binlog 执行按时间点恢复(PITR 到最新可用点,T+4 ~ T+10 分钟) 前提:已有“完整 binlog”文件集(从上游主库归档得来)。将涉及的 binlog 文件拷贝到从库本地安全路径(例如 /data/binlog_archive)。

关键原则:

  • 使用 GTID 跳过已执行事务,仅回放缺失事务,避免重复与冲突。
  • 恰当选择截止时间:若需严格截止到主库宕机前最后一刻,可用 --stop-datetime='YYYY-MM-DD HH:MM:SS'(注意使用与 binlog 记录一致的时区,通常为服务器本地时间)。
  • 如确认归档 binlog 仅包含宕机前事件,也可不加 stop-datetime,直接全量回放(GTID 会自动跳过已执行事务)。

步骤:

  • 导出当前从库的 GTID 集到文件,避免命令行长度/转义问题:
    • mysql -NBe "SELECT @@GLOBAL.gtid_executed" > /tmp/gtid_executed.txt
  • 评估需要回放的 binlog 文件清单(例:mysql-bin.000123 ~ mysql-bin.000130),准备命令:
    • 仅根据 GTID 补齐(推荐):
      • mysqlbinlog --verify-binlog-checksum
        --exclude-gtids="$(cat /tmp/gtid_executed.txt)"
        /data/binlog_archive/mysql-bin.000123 /data/binlog_archive/mysql-bin.000124 ...
        | mysql --binary-mode -u -p -h <从库主机> -P <端口>
    • 按时间点精确截止(可选):
      • mysqlbinlog --verify-binlog-checksum
        --exclude-gtids="$(cat /tmp/gtid_executed.txt)"
        --stop-datetime="YYYY-MM-DD HH:MM:SS"
        /data/binlog_archive/mysql-bin.000123 ...
        | mysql --binary-mode -u -p -h <从库主机> -P <端口> 注意事项:
  • 请使用具备足够权限的用户(建议仅本地管控账号),并确保目标实例已保持 super_read_only=ON,防止外部写入。
  • 如回放过程中出现错误(如缺失文件、校验失败),立即中止,不要贸然继续;复核 binlog 集是否连续完整。
  • 不要使用 set-gtid-purged 手工改写目标实例(运行实例不应设置 GTID_PURGED),让 mysqlbinlog 自动输出 GTID_NEXT 事件即可。

完成后,验证 GTID 是否已追至最新:

  • 再次记录:SELECT @@GLOBAL.gtid_executed \G
  • 对比归档中最后一个 binlog 的末尾时间与事务,确认已覆盖。
  1. 快速提升从库为主库(T+10 ~ T+12 分钟)
  • 确认仍为只读:SELECT @@global.super_read_only; 应为 ON。
  • 最终冻结复制(已经 STOP 状态):确认 SHOW SLAVE/REPLICA STATUS\G 中 IO/SQL 线程均为 No。
  • 清理复制元数据(避免后续误启动回连旧主):
    • RESET SLAVE ALL;(5.7)
    • RESET REPLICA ALL;(8.0) 注意:此操作不会删除数据,但会清空复制位点与通道配置。仅在确认要提升为主时执行。
  • 开启写入:
    • SET GLOBAL read_only = OFF;
    • SET GLOBAL super_read_only = OFF;
  • 确认二进制日志开启以供其他从库复制:SHOW VARIABLES LIKE 'log_bin'; 应为 ON。
  • 建议轮转日志以便新的主库产生新的 binlog 文件:
    • FLUSH BINARY LOGS;
  1. 业务切换(T+12 ~ T+14 分钟)
  • 将应用连接指向新主(本从库主机)。如使用中间层(VIP/代理),切换后立即进行健康检查。
  • 核心校验(详见下方“验证检查清单”):
    • 基础连通、写入可用性、关键读写路径、GTID 状态、只读状态已关闭等。
  1. 其余从库回挂至新主(如有) 对每个其他从库执行(确保其数据与新主在同一时间点或更早,且启用 GTID):
  • STOP SLAVE; 或 STOP REPLICA;
  • CHANGE MASTER TO MASTER_HOST='<新主地址>', MASTER_USER='repl', MASTER_PASSWORD='***', MASTER_AUTO_POSITION=1, MASTER_PORT=<端口>, MASTER_SSL=1;(5.7)
  • 或 CHANGE REPLICATION SOURCE TO SOURCE_HOST='<新主地址>', SOURCE_USER='repl', SOURCE_PASSWORD='***', SOURCE_AUTO_POSITION=1, SOURCE_PORT=<端口>, SOURCE_SSL=1;(8.0)
  • START SLAVE; 或 START REPLICA;
  • 验证 Seconds_Behind_Master、Replica_IO_Running/Replica_SQL_Running 均为 Yes,且无报错。 注意:若某从库比新主“更新”,可能包含新主不具备的 GTID,会导致回挂失败。此时需先对该从库进行回滚到一致基线或重建(建议后续安排,不在 15 分钟紧急窗口内执行)。
  1. 旧主恢复与重新加入(窗口外安排)
  • 修复/更换旧主硬件后,不要直接回到主位。使用最新全量备份 + 新主的 binlog 将其重建为新主的从库:
    • 使用备份恢复数据至目标主机
    • 通过设置 @@GLOBAL.gtid_purged(仅在初始化空实例且无任何事务时)或使用 CHANGE MASTER/SOURCE TO ... MASTER_AUTO_POSITION=1/SOURCE_AUTO_POSITION=1 来接入复制
    • START REPLICA 并验证追平
  • 确保 server_id、server_uuid 唯一,避免复制环路。
  1. 常见问题快速处理
  • mysqlbinlog 回放报重复键或“已存在”错误:若为 GTID 模式且使用 --exclude-gtids,通常不会出现该类错误;如出现,检查是否以非 GTID 模式回放或 binlog 不连续。
  • 报“could not find GTID”或“master has purged required binary logs”:表示回挂的从库需要的事务不在新主可提供范围。对该从库执行基于备份的重建。
  • 时间点恢复时区不一致:确认 mysqlbinlog 显示时间与服务器时区,使用 --stop-datetime 时请用与 binlog 记录一致的时间。

验证检查清单

技术验证

  • 实例状态
    • SELECT @@global.read_only=0, @@global.super_read_only=0
    • SHOW VARIABLES LIKE 'gtid_mode' 应为 ON;SHOW VARIABLES LIKE 'enforce_gtid_consistency' 应为 ON
    • SHOW BINARY LOGS 可正常显示新主 binlog 列表
  • 数据一致性(快速校验)
    • 关键表行数/主键范围抽样对比(在新主与至少一个从库):SELECT COUNT(*),MAX(id),MIN(id) 等
    • 对关键表执行 CHECKSUM TABLE QUICK;(在线且较轻量,注意对超大表的开销)
    • 重要业务数据点抽查(如近 5 分钟内订单数、金额汇总)
  • 复制健康(其他从库)
    • SHOW SLAVE/REPLICA STATUS\G:Replica_IO_Running/Replica_SQL_Running = Yes
    • Seconds_Behind_Master 稳定在 0 或可接受范围
    • GTID 集对等:在新主与某从库分别执行
      • SELECT GTID_SUBSET(@@GLOBAL.gtid_executed, '<对端gtid_executed>') AND GTID_SUBSET('<对端gtid_executed>', @@GLOBAL.gtid_executed);
      • 两者均为 1 表示集合相等
  • 性能与错误
    • SHOW GLOBAL STATUS LIKE 'Threads_connected'; QPS/TPS 观察
    • 错误日志无新报错(InnoDB、复制、权限)

业务验证

  • 应用能成功读写(新建/更新/查询一条核心业务记录)
  • 关键接口 2-3 个冒烟用例通过(下单、支付、查询等)
  • 权限/账号生效(应用账号可写,审计账号只读)

预防建议

  • 硬件与存储
    • 为主库数据与 binlog 使用独立、冗余的企业级存储(RAID/双盘/多副本),启用磁盘健康监控与预警
    • 启用文件系统与块层告警(SMART、I/O 延迟、坏块)
  • 事务持久性
    • 建议 innodb_flush_log_at_trx_commit=1,sync_binlog=1(提升崩溃一致性,代价是少量性能开销)
    • 保持 binlog_format=ROW,降低复制与恢复歧义
  • 备份/归档
    • 固化全量+增量(binlog)备份策略,确保 binlog 持续、连续地归档至独立介质;定期做恢复演练
    • 备份、binlog 与参数文件(my.cnf)同一批次归档,记录版本/时区/校验和
  • 高可用架构
    • 最少 1 主 2 从,读写分离;复制通道启用加密与专用复制账号
    • 引入自动化故障转移组件和仲裁机制(具备漂移/脑裂保护、只读保护、健康检查、择优提升策略)
    • 对关键只读从库启用 super_read_only 并加 DDL 审核,避免误写破坏复制
  • 观测与演练
    • 标准化切换与恢复 Runbook(本指引可作为模板),季度演练
    • 完成关键指标告警:复制延迟、binlog 积压、磁盘健康、慢查询、连接数、错误日志

紧急联系方式

  • 官方文档与支持
    • MySQL Reference Manual(GTID、复制、mysqlbinlog 使用)
    • MySQL 官方支持(如有商业支持合同)
  • 社区与资源
    • 官方论坛与知识库(检索关键字:GTID failover、mysqlbinlog PITR、RESET REPLICA)
  • 内部联络
    • 存储/硬件团队:磁盘/主机故障排查与更换
    • 运维与网络团队:VIP/代理/防火墙切换与连通性
    • 应用负责人:应用端流量切换与功能回归

补充说明:上述流程避免了高风险操作(如 RESET MASTER、强制跳过事务)并严格依托 GTID 与官方工具(mysql、mysqlbinlog、内置复制命令)。如任何一步出现异常,请保持实例只读与业务写入冻结状态,先定位问题再继续,以确保零或可控的数据风险。

故障分析总结

  • 原因:开发误操作删除了订单表并提交事务,导致生产库中该表及其数据缺失。
  • 环境特征:PostgreSQL 已开启归档与 WAL。具备进行基于归档的时间点恢复(PITR)的条件。
  • 影响范围:订单表本身及依赖对象(索引、约束、触发器、序列等)。若为 DROP TABLE,依赖对象同时丢失;若为 DELETE,结构存在但数据丢失。
  • 恢复策略:在隔离实例基于最近一次可用基线备份+WAL执行 PITR,恢复到误删前 5 分钟;在只读窗口校验数据;确认无误后将隔离实例提升为可写,使用逻辑复制将订单表回灌至生产库;回灌期间对生产库相关对象维持只读。

恢复步骤详情(操作清单)

以下步骤按顺序执行。命令以占位符表示,请替换为您的实际路径、主机、端口、实例名和凭据。示例适配 PostgreSQL 12–16(请以您的主版本为准)。

0. 前置准备与冻结窗口

  1. 明确误删时间点:
    • 如果为 DROP TABLE/DELETE 的执行时间记入了审计/应用日志/数据库日志,请获取准确时间戳 T_drop。
    • 目标恢复时间 T_target = T_drop - 5 分钟。
  2. 在生产库冻结与订单表相关的写入(保证回灌一致性):
    • 如果表已被 DROP:无需额外冻结,但需冻结与之相关的写入逻辑(避免提前重建/写入同名表)。
    • 如果是 DELETE:对该表设为只读(回收 DML 权限),并约束应用不再写入。 示例(按需调整角色名、模式名与表名,下同):
      • 记录原权限: SELECT pg_get_userbyid(relowner) owner, relacl FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace WHERE n.nspname='public' AND c.relname='orders';
      • 撤销应用角色写权限(保留超级/DBA权限): REVOKE INSERT, UPDATE, DELETE ON TABLE public.orders FROM app_role;
  3. 确认可用备份链:
    • 找到早于 T_target 的最近一次基线备份(物理全备,称为 BaseBackup)。
    • 确认从该基线备份点到 T_target 的 WAL 归档完整可用。

1. 准备隔离恢复实例

  1. 准备同主版本 PostgreSQL 的隔离主机/实例(CPU/内存/磁盘足够,区域/时区/本地化与生产一致,尤其 encoding/collation/ctype)。
  2. 创建数据目录并设置权限: sudo mkdir -p /pgdata/recovery sudo chown postgres:postgres /pgdata/recovery sudo chmod 700 /pgdata/recovery
  3. 从备份介质恢复基线备份至数据目录(以文件级拷贝为例,替换为您的备份工具恢复命令): rsync -a /backup/basebackup/YYYYMMDD/ /pgdata/recovery/
  4. 准备 WAL 归档挂载点(供 restore_command 读取):
    • 假设归档目录为 /pgwal/archive,确保 postgres 用户可读。

2. 配置并执行 PITR 到目标时间

  1. 编辑 /pgdata/recovery/postgresql.conf(如使用 include,请按需调整位置):
    • hot_standby = on # 恢复期间允许只读查询
    • restore_command = 'cp /pgwal/archive/%f %p' # 从归档取 WAL 文件的可靠命令(保证失败返回非 0)
    • recovery_target_time = '2025-12-03 10:25:00+08' # 示例:替换为 T_target
    • recovery_target_timeline = 'latest'
    • recovery_target_action = 'pause' # 到达目标点后暂停,保持只读窗口 注意:
    • 时间戳请使用明确时区或与系统时区一致。
    • 若归档在其他介质,请将 restore_command 替换为相应可用的安全命令,确保校验/失败返回码正确。
  2. 创建恢复信号文件:
    • touch /pgdata/recovery/recovery.signal
  3. 启动实例: pg_ctl -D /pgdata/recovery -l /pgdata/recovery/logfile start
  4. 监控恢复进度:
    • tail -f /pgdata/recovery/logfile
    • 期望日志出现 “reached recovery target, paused” 字样。
    • 会处于只读、已暂停状态: psql "host=... port=... dbname=... user=... sslmode=prefer" -c "select pg_is_in_recovery();" 返回:t
    • 可确认回放 LSN: SELECT pg_last_wal_replay_lsn();

3. 只读窗口内的数据验证(初检)

  1. 确认对象存在(若为 DROP TABLE 场景尤其重要): \dt+ public.orders
  2. 基础核对(替换条件与列名):
    • 行数: SELECT count(*) FROM public.orders;
    • 主键/业务键样本抽查: SELECT * FROM public.orders WHERE id IN (....);
    • 时间边界(确保数据早于 T_drop): SELECT min(created_at), max(created_at) FROM public.orders;
  3. 如需重复 PITR(目标时间不理想):
    • 停库并清空数据目录,重新从基线备份恢复,调整 recovery_target_time,重复 2–3 步骤。
    • 注意:PITR 不是可回退操作,需从备份重新开始一次新的恢复流程。

4. 提升为独立可写(为逻辑复制做准备)

  1. 确认 wal_level=logical(发布端要求)。如当前为 replica 或 minimal:
    • 在只读恢复状态下无法更改,需先提升,再重启生效。
  2. 提升实例(结束暂停,成为新时间线的独立主库): pg_ctl -D /pgdata/recovery promote 或 SELECT pg_promote(); 此时:SELECT pg_is_in_recovery(); 返回 f
  3. 设置逻辑复制相关参数(如未满足)并重启: ALTER SYSTEM SET wal_level = 'logical'; ALTER SYSTEM SET max_wal_senders = 10; ALTER SYSTEM SET max_replication_slots = 10; SELECT pg_reload_conf(); 如 wal_level 由非 logical 升至 logical 需重启: pg_ctl -D /pgdata/recovery restart
  4. 确保网络连通与访问权限(pg_hba.conf 允许生产库作为订阅端连接;仅开放必要白名单与最小权限账户)。

5. 在恢复实例上创建发布(仅发布订单表)

  1. 确认表的复制标识(REPLICA IDENTITY)。若需要基于主键的 UPDATE/DELETE,请确保主键或唯一索引存在;若无,设置为 FULL 会有性能代价: -- 若无合适主键,谨慎使用: ALTER TABLE public.orders REPLICA IDENTITY FULL;
  2. 创建发布: CREATE PUBLICATION p_orders FOR TABLE public.orders WITH (publish = 'insert,update,delete');

6. 在生产库准备订阅与只读窗口

  1. 生产库上创建与源一致的表结构(DROP TABLE 场景必做;DELETE 场景建议 TRUNCATE 再回灌):
    • 从恢复实例导出表结构并在生产执行: pg_dump -s -t public.orders -h <recovery_host> -p <recovery_port> -U | psql -h <prod_host> -p <prod_port> -U <prod_db>
    • 如存在序列、触发器、索引、检查/外键约束,同样会包含在 -s 的定义中(注意跨表外键顺序与依赖,必要时先不验证约束,回灌后再 VALIDATE)。
  2. 维持/加强生产只读窗口(避免竞态写入):
    • 确保应用层面阻止对 public.orders 的写操作。
    • 数据库侧撤销 DML 权限: REVOKE INSERT, UPDATE, DELETE ON TABLE public.orders FROM app_role;
    • 若存在引用该表的外键,考虑暂时将相关 DML 限制到最小,避免约束校验异常。
  3. 创建用于订阅的最小权限账号(在恢复实例上):
    • 仅授予连接、复制所需权限与对发布表的 SELECT: CREATE ROLE sub_user LOGIN PASSWORD '***'; GRANT SELECT ON TABLE public.orders TO sub_user; -- 如使用物化初始快照,不需要对所有对象授权,仅发布表需读权限。
  4. 在生产库创建订阅(pull 模式,从恢复实例拉取): CREATE SUBSCRIPTION s_orders CONNECTION 'host=<recovery_host> port=<recovery_port> dbname= user=sub_user password=*** sslmode=prefer' PUBLICATION p_orders WITH (copy_data = true, create_slot = true, enabled = true); 注意:
    • 若生产上表已有部分数据且需先清空,请在创建订阅前执行 TRUNCATE public.orders;(谨慎!确认已做全量备份与只读窗口)
    • 如果需要限制带宽/批量大小,可在网络与资源侧做限流;避免影响生产。

7. 监控复制、完成回灌与解除只读

  1. 监控复制进度(生产库): SELECT subname, status, received_lsn, latest_end_lsn, sync_state, stats_reset FROM pg_stat_subscription; 检查初始快照是否完成(状态变为 replicating,且无报错)。
  2. 基础校验(生产库 vs 恢复实例):
    • 行数对比(大表可抽样分段对比): -- 生产: SELECT count() FROM public.orders; -- 恢复: SELECT count() FROM public.orders;
    • 关键指标对比(替换列为业务关键字段): SELECT min(created_at), max(created_at) FROM public.orders; SELECT count(distinct customer_id) FROM public.orders; SELECT sum(total_amount) FROM public.orders;
    • 序列值(如有自增主键): -- 恢复端: SELECT setval('public.orders_id_seq', (SELECT max(id) FROM public.orders)); -- 生产端(回灌完成后同样设置一次,确保后续写入不回卷): SELECT setval('public.orders_id_seq', (SELECT max(id) FROM public.orders));
    • 抽样一致性(相同采样条件): SELECT md5(string_agg(id::text, ',' ORDER BY id)) FROM (SELECT id FROM public.orders ORDER BY id LIMIT 100000) t; -- 大表可分段或分桶比对
  3. 如存在约束在建表时设为 NOT VALID,回灌完成后进行验证(生产库): ALTER TABLE public.orders VALIDATE CONSTRAINT ;
  4. 解除订阅并保留数据(生产库): ALTER SUBSCRIPTION s_orders DISABLE; DROP SUBSCRIPTION s_orders WITH (drop_slot = true);
  5. 恢复生产库应用角色对该表的写权限: GRANT INSERT, UPDATE, DELETE ON TABLE public.orders TO app_role;
  6. 更新统计信息(生产库): ANALYZE public.orders;

验证检查清单

  • 元数据一致性
    • 表、索引、触发器、约束、序列是否与恢复实例一致(pg_dump -s 对比)。
    • 所有相关 schema/search_path 与所有权、权限正确。
  • 数据一致性
    • 行数、关键汇总字段(金额/数量)、时间边界一致。
    • 随机/分段抽样校验(按主键范围或哈希分桶)。
    • 序列当前值 setval 已与最大主键同步。
  • 外键与完整性
    • 相关外键 VALIDATE 通过,无孤儿记录。
    • 触发器状态正常(未被禁用或误保留为 replica 触发器的特殊状态)。
  • 性能与可用性
    • 索引可用(无 invalid 索引),reindex 非必需但可按需做。
    • 查询计划合理(ANALYZE 后检查关键 SQL 的执行计划)。
    • 应用读写恢复正常,错误日志无异常。
  • 复制链路收尾
    • 订阅已删除、复制槽已释放。
    • 恢复实例保留/下线策略明确(避免被误连)。

预防建议

  • 权限与保护
    • 生产库对 DROP/DELETE 等高危操作实施更严格权限与变更流程;引入行级/对象级审计。
    • 在变更窗口启用“保护模式”(禁止 DDL 或需审批)。
  • 备份与恢复演练
    • 固化基线全备与 WAL 归档合规性巡检(可自动校验备份链完整性)。
    • 定期在隔离环境演练 PITR 与单表回灌流程,记录目标时间选择与操作手册。
  • 逻辑复制与单表恢复预案
    • 为关键大表预置逻辑复制参数(wal_level=logical、replication slots 额度),降低紧急恢复配置时间。
    • 为关键表维护最新结构脚本(含序列/索引/约束),便于一键重建。
  • 变更审计与告警
    • 启用 pgaudit/日志增强,关键 DDL/DML 变更触发告警,缩短发现误操作与恢复窗口。
  • 最小化业务中断
    • 在应用层实现只读切换开关;预置按租户/业务域的细粒度写入冻结能力。
    • 为大表复制设定维护时段与性能隔离(I/O/网络限流、并发控制)。

紧急联系方式(官方资源)


附:回退计划(异常场景应对)

  • PITR 校验失败(目标点不理想)
    • 停止恢复实例,清空数据目录,重新从相同基线备份恢复;调整 recovery_target_time,重复恢复与校验。
  • 生产端回灌异常(如冲突/复制失败)
    • 立即 DISABLE 订阅:ALTER SUBSCRIPTION s_orders DISABLE;
    • 记录错误,必要时 DROP SUBSCRIPTION s_orders WITH (drop_slot = true);
    • 将生产表重命名备份:ALTER TABLE public.orders RENAME TO orders_bak_yyyymmdd;
    • 重新以 schema 脚本创建空表,重新创建订阅并回灌;或用 pg_dump/pg_restore 从恢复实例直接导入数据。
  • 数据验收不通过
    • 撤销本次回灌:在生产删除回灌所得表或回滚到回灌前快照(若有);保持只读,重新核对 T_target 与数据来源后再执行。
  • 安全兜底
    • 在回灌前对生产目标库(或目标表)做一次快速逻辑备份: pg_dump -h -p -U -Fc -t public.orders -f /backup/prod_orders_pre_restore.dump
    • 保留恢复实例,不要立即销毁,直到生产验收通过一段时间。

故障分析总结

  • 根因:主节点 AOF(Append Only File)尾部损坏,导致 Redis 启动加载 AOF 失败。哨兵(Sentinel)已将业务切换到从节点,新主已在服务。
  • 影响:新主上的数据可能缺失主节点上最后一段未复制的写入(RPO≈秒级)。旧主上的 AOF 不可直接加载,直接启动可能加剧损坏或污染数据。
  • 目标:在不影响线上新主稳定性的前提下,基于损坏前的 AOF 可恢复部分,回补丢失/热点键;校验一致性;重建主从与持久化策略,降低未来风险。

恢复步骤详情

以下步骤默认新主已稳定对外服务。所有修复操作均在隔离环境对“文件副本”进行,避免二次损坏。

0. 稳定与准备

  • 确认当前主从角色:
    • 新主:稳定对外,拒绝在旧主恢复前进行任何拓扑变更。
    • 旧主:保持关闭状态,禁止自动拉起和对外服务。
  • 备份与留痕(务必执行):
    • 备份新主当前持久化文件(RDB/AOF,如有):冷拷贝保存。
    • 备份旧主所有持久化文件:appendonly.aof、appendonly.aof.*、appendonly.aof.manifest、dump.rdb 等。
    • 收集应用侧或监控侧热点 Key 列表(若无,后续可临时扫描估计)。

示例(在旧主机器):

mkdir -p /tmp/redis_aof_recovery
cp -a /data/redis/appendonly.aof* /tmp/redis_aof_recovery/ 2>/dev/null || true
cp -a /data/redis/dump.rdb /tmp/redis_aof_recovery/ 2>/dev/null || true

1. 在隔离环境修复 AOF(只对副本操作)

  • 校验并尽可能修复(修复实际是“截断到最后一个完整命令”,可能丢弃损坏尾部;仅在副本上操作,避免直接损失):

    • 单文件 AOF:
      redis-check-aof --fix /tmp/redis_aof_recovery/appendonly.aof
      
    • 多分段 AOF(Redis 7+,带 manifest):
      redis-check-aof --fix /tmp/redis_aof_recovery/appendonly.aof.manifest
      

    注意:

    • 该修复会截断不完整尾部,属于最小破坏性、官方工具支持的安全做法,但仍可能无法包含最后极少量未落盘写入。
  • 启动隔离“恢复实例”(不对外,回环地址/受保护)加载修复后的 AOF:

    cat > /tmp/redis_aof_recovery/redis-recovery.conf <<'EOF'
    port 6390
    bind 127.0.0.1
    protected-mode yes
    dir /tmp/redis_aof_recovery
    dbfilename dump-recovery.rdb
    appendonly yes
    appendfilename appendonly.aof
    daemonize yes
    EOF
    
    redis-server /tmp/redis_aof_recovery/redis-recovery.conf
    redis-cli -p 6390 PING   # 期望返回 PONG
    

    验证加载是否正常:

    redis-cli -p 6390 INFO persistence | egrep 'loading|aof_last_write_status|aof_rewrite_in_progress'
    redis-cli -p 6390 DBSIZE
    

2. 识别并回补“丢失/热点键”

优先处理业务关注的“热点 Key”,在线、无停机回补到新主。

  • 获取热点 Key 列表(优先使用应用/监控侧清单;若缺失可临时估算):

    • 方式A(推荐):从监控/日志/应用清单导出热点 keys -> hotkeys.txt
    • 方式B(谨慎使用,可能对大集群有开销):在新主估算热点
      redis-cli -h <new_master_ip> -p 6379 --hotkeys 2>/dev/null | awk '{print $2}' > hotkeys.txt
      
      注:该方法基于 SCAN + OBJECT FREQ,在未启用 LFU 策略时只是近似。
  • 对比恢复实例与新主,差异回补(仅迁移缺失或不一致的键,避免覆盖正确数据):

    • MIGRATE 可保留 TTL,整键原子拷贝,适合小批量关键键在线回补。
    • 若新主启用 ACL,请使用 AUTH2;无 ACL 用 AUTH 或省略。

示例(无 ACL):

# 逐键对比 DUMP(序列化值)与 TTL,不一致则从恢复实例迁移到新主
while read k; do
  # 恢复实例存在该键?
  if [ "$(redis-cli -p 6390 EXISTS "$k")" = "1" ]; then
    # 新主不存在则直接迁移
    if [ "$(redis-cli -h <new_master_ip> -p 6379 EXISTS "$k")" != "1" ]; then
      redis-cli -p 6390 MIGRATE <new_master_ip> 6379 "" 0 3000 REPLACE KEYS "$k"
    else
      # 均存在则比对序列化值,差异则覆盖
      d1=$(redis-cli -p 6390 --raw DUMP "$k" | base64)
      d2=$(redis-cli -h <new_master_ip> -p 6379 --raw DUMP "$k" | base64)
      if [ "$d1" != "$d2" ]; then
        redis-cli -p 6390 MIGRATE <new_master_ip> 6379 "" 0 3000 REPLACE KEYS "$k"
      fi
    fi
  fi
done < hotkeys.txt

示例(有 ACL):

redis-cli -p 6390 MIGRATE <new_master_ip> 6379 "" 0 3000 AUTH2 <user> <pass> REPLACE KEYS <k1> <k2> ...

说明:

  • MIGRATE 默认保留 TTL,REPLACE 仅在确认差异或缺失时使用,避免误覆盖。
  • 对于特别大的值或大量键,建议分批执行并监控时延。

3. 可选:扩大校验范围(非热点)

  • 若需要进一步降低数据差异风险,可在低峰期基于 SCAN 分批抽样比对(谨慎控制速率):
    • 在恢复实例 SCAN -> 对应新主 EXISTS/DUMP 对比 -> 差异再 MIGRATE。
    • 强烈建议批量、限速、离峰执行,避免影响线上。

4. 让旧主以“干净从库”身份重新加入

为避免旧主因损坏文件污染拓扑,建议以“空数据 + 全量同步”的方式重入。

在旧主机器:

# 停旧实例,隔离旧数据
systemctl stop redis || true
mkdir -p /data/redis.bad
mv /data/redis/appendonly.aof* /data/redis.bad/ 2>/dev/null || true
mv /data/redis/dump.rdb /data/redis.bad/ 2>/dev/null || true

# 配置为新主的从库(redis.conf 或运行时)
# redis.conf 增加:
# replicaof <new_master_ip> 6379
# replica-read-only yes
# appendonly yes

systemctl start redis
redis-cli -h <old_master_ip> INFO replication | egrep 'role|master_host|master_sync_in_progress'

等待 full sync 完成后,旧主即作为健康从库存在。

5. 重建持久化与基线备份(在新主)

  • 确认持久化策略(RDB + AOF):
redis-cli -h <new_master_ip> CONFIG SET appendonly yes
redis-cli -h <new_master_ip> CONFIG SET appendfsync everysec
redis-cli -h <new_master_ip> CONFIG SET auto-aof-rewrite-percentage 100
redis-cli -h <new_master_ip> CONFIG SET auto-aof-rewrite-min-size 64mb
redis-cli -h <new_master_ip> CONFIG REWRITE
  • 生成干净基线文件并落盘备份:
redis-cli -h <new_master_ip> BGREWRITEAOF
redis-cli -h <new_master_ip> BGSAVE
# 将新生成的 AOF/RDB 做离机/异地备份

6. Sentinel 与写安全加固

  • Sentinel 健康与仲裁:
redis-cli -p <sentinel_port> SENTINEL masters
redis-cli -p <sentinel_port> SENTINEL ckquorum <master_name>
redis-cli -p <sentinel_port> SENTINEL slaves <master_name>
  • 写安全(防止“零副本写入”导致再故障时丢数据):
redis-cli -h <new_master_ip> CONFIG SET min-replicas-to-write 1
redis-cli -h <new_master_ip> CONFIG SET min-replicas-max-lag 5
redis-cli -h <new_master_ip> CONFIG REWRITE

验证检查清单

  • 关键数据一致性
    • 抽样热点 Key(至少前 N 个)检查:TYPE、EXISTS、PTTL、DUMP 一致。
    • 执行过 MIGRATE 的键复查一次,确认值与 TTL 正确。
  • 主从与哨兵
    • 新主:INFO replication 中 role=master,connected_slaves ≥ 1。
    • 旧主:ROLE 返回 slave,master_link_status=up,master_sync_in_progress=0。
    • Sentinel:SENTINEL ckquorum 通过;仅有一个主节点。
  • 持久化健康
    • INFO persistence 中:
      • aof_enabled=1
      • aof_last_bgrewrite_status=ok
      • rdb_last_bgsave_status=ok
      • loading=0
  • 性能与稳定性
    • 延迟与慢查询:redis-cli --latency(或监控平台)无异常峰值;SLOWLOG 中无异常堆积。
    • 磁盘与文件系统:空间充足,IO 正常,AOF 文件大小与增长速率符合预期。

预防建议

  • 文件与落盘安全
    • 使用 Redis 7+ 多分段 AOF(manifest),开启 aof-use-rdb-preamble(默认开启),便于损坏时快速恢复。
    • 采用 appendfsync everysec(性能/安全折中),并保留 aof-load-truncated yes(默认)以在尾部截断情况下可自动加载,但需配合告警。
    • 定期 BGREWRITEAOF,设置合理阈值(如 100%、64MB)避免 AOF 过度膨胀。
    • 启用 stop-writes-on-bgsave-error yes(默认)防止持久化异常时继续写入。
  • 拓扑与写入保护
    • 设置 min-replicas-to-write / min-replicas-max-lag,确保至少有一个同步良好的副本在线时才接受写入,降低故障瞬间的数据丢失风险。
    • 哨兵参数合理化(down-after-milliseconds、failover-timeout、parallel-syncs),避免误判和长时间不可用。
  • 备份与演练
    • 定期冷备 AOF/RDB(含异地/对象存储),并进行真实恢复演练,确保 RTO/RPO 满足业务目标。
    • 监控 aof_last_write_status、aof_last_bgrewrite_status、rdb_last_bgsave_status、disk/IO 指标,异常及时告警。
  • 系统层面
    • 确保宿主机磁盘与文件系统稳定(磁盘健康、无频繁掉电、禁用不稳定硬盘缓存;生产环境建议使用稳定的存储阵列与电源保护)。
    • 限制操作系统层面对 Redis 进程的 OOM 风险,避免因内存压力触发进程被杀导致文件损坏。

紧急联系方式

示例详情

解决的问题

把“紧急、复杂、高风险”的数据库故障处理,变成一份人人可执行的标准化行动手册。通过输入数据库类型与故障场景,快速生成可落地的恢复步骤、核对清单与预防方案,帮助团队在关键时刻:更快定位问题、减少误操作、缩短停机时间、沉淀可复用SOP,并支持演练、交接与复盘,最终提升可用性与管理效率。

适用用户

数据库管理员(DBA)

在夜间突发宕机时,快速定位故障类型,生成分步恢复方案与校验清单,短时间内拉起核心业务,减少停机损失。

系统运维工程师

将恢复剧本嵌入值班流程,标准化故障处置,降低跨库差异导致的误操作,并沉淀可复用复盘记录与加固项。

业务连续性负责人(IT经理)

制定明确的恢复目标与时间承诺,演练核心系统切换路径,用数据化报表跟踪停机时长与加固进度,提升管理可控性。

特征总结

跨数据库即用:一键生成MySQL、Oracle、MongoDB等对应恢复方案,覆盖常见崩溃场景。
应急处置剧本:按诊断→准备→执行→验证分步输出,照单操作即可稳妥恢复服务。
风险防护护栏:自动标注高风险步骤与回滚点,默认规避数据丢失与二次损害。
业务优先恢复:给出系统切换与优先级策略,先保核心交易与登录等关键路径。
完整性校验清单:自动生成必查项与通过标准,避免“恢复成功但业务异常”。
可参数化定制:按数据库类型与故障描述,生成贴合现场的指令示例与注意事项。
复盘与预防建议:输出故障根因、加固清单与巡检频次,帮助持续降低同类风险。
团队协作友好:结构清晰的操作文档可直接放入工单与值班群,减少沟通往返。
学习曲线平滑:附带风险提示与执行顺序,新手当班也能独立完成关键恢复。
合规与审计友好:不包含未授权工具,强调数据边界与留痕,满足审计要求。

如何使用购买的提示词模板

1. 直接在外部 Chat 应用中使用

将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。

2. 发布为 API 接口调用

把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。

3. 在 MCP Client 中配置使用

在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。

AI 提示词价格
¥20.00元
先用后买,用好了再付款,超安全!

您购买后可以获得什么

获得完整提示词模板
- 共 601 tokens
- 3 个可调节参数
{ 数据库类型 } { 恢复场景 } { 输出偏好 }
获得社区贡献内容的使用权
- 精选社区优质案例,助您快速上手提示词
使用提示词兑换券,低至 ¥ 9.9
了解兑换券 →
限时半价

不要错过!

半价获取高级提示词-优惠即将到期

17
:
23
小时
:
59
分钟
:
59