ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

数据库恢复技术:从WAL日志到崩溃恢复的全面解析

数据库恢复技术:从WAL日志到崩溃恢复的全面解析 凌晨两点半电话响了。值班同学的声音带着明显的困意“哥库挂了。”我翻身下床一边开电脑一边在心里快速过了一遍排查清单是内存里的脏数据没刷下去还是磁盘上的数据文件坏了有没有可用的备份最近的日志在哪个位置这几句话问完事故性质其实就清楚了一半。你会发现数据库恢复技术从来不是考卷上的简答题而是每个接触数据库的人迟早要面对的一次“抢救现场”。这一章讲的数据库恢复技术核心就一句话当数据库因为各种故障导致数据丢失或逻辑混乱时如何借助日志、备份等手段让已提交事务所做的修改最终持久化让未提交事务所做的修改彻底回滚最终把数据库拉回一个稳定可用的状态。它解决的是数据一致性和系统可用性这两个最根本的问题。适合刚学完事务理论的在校生、每天写SQL的业务开发、也包括刚接手生产环境的运维朋友——只要你手上管的库有哪怕一条业务数据这章知识都属于“迟早要用到”的那类。1. 凌晨报警电话背后的恢复技术先别急着掉进日志、检查点这些细节里。我们退一步想想数据库恢复技术到底在解决什么问题。你想象一下数据库的正常工作方式数据长期躺在磁盘上但是为了性能读写操作基本都发生在内存缓冲区里。也就是说一个UPDATE语句执行完后新数据可能只出现在内存中磁盘上对应的数据页还是旧值。这不是偷懒而是为了减少磁盘I/O次数——磁盘随机读写比内存慢几个数量级如果每次提交事务都立刻把数据页写回磁盘数据库吞吐量会惨不忍睹。但这引出了一个致命问题如果操作系统崩溃或突然断电内存里那些“还没来得及写回磁盘”的修改就会彻底消失。你的事务明明返回了“提交成功”结果重启后数据却不见了。这就是恢复技术要对付的第一个敌人——内存与磁盘之间的数据落差。另一个敌人是日志本身的不完整性。就算你坚持“每次提交都把日志写到磁盘”如果日志记录本身顺序错了、缺了一段恢复时一样会得出错误的结论。所以数据库恢复技术的本质是一套“如何在出错之后依据已经落盘的日志和备份准确判断每个事务该被重做还是该被撤销”的规则体系。我在生产环境里见过很多次这样的场景一个事务刚开始执行程序异常退出数据库里留下了一半写入的数据或者服务器突然断电内存里一堆数据没来得及落盘。这两种情况都会让数据库进入一个“不好说”的状态。恢复技术要做的就是把这个“不好说”的状态根据提交点强行拉回“一致性状态”已提交的生效未提交的全部抹掉。理解了这个目标下面所有细节其实都是围绕它展开的。2. 事务与故障分类先搞清楚“病根”在哪里恢复技术离不开事务概念。数据库里的事务Transaction是一组操作的集合这组操作要么全部成功、要么全部失败不允许中间状态。教科书里用转账举例子从A扣100元、给B加100元这两件事必须打包成一个整体。如果只执行了第一步第二步因为断电没执行账就不平了。事务这种“要么全做要么不做”的特性叫做原子性。事务还有个特性叫持久性一旦事务提交COMMIT修改就必须永久生效即使接下来马上断电数据也不能丢。恢复技术主要保障的就是原子性和持久性。你在网上搜“数据库恢复技术”相关的内容翻来覆去看到的就是这两个词一是保证没提交的事务能回滚二是保证已提交的事务能持久化。搞明白这一点后面所有机制都有一个清晰的落点。2.1 事务ACID属性与恢复的关系事务有四个标准属性即ACID原子性Atomicity事务中的操作要么全部完成要么全部不发生。一致性Consistency事务执行前后数据库都处于一致状态。隔离性Isolation并发事务之间互不干扰看到的数据不能是互相交叉的半成品。持久性Durability事务提交后修改必须永久保存下来。在这四个属性里原子性和持久性与恢复技术关系最紧密。隔离性主要靠并发控制锁、MVCC保证一致性则是设计层面要保证的事情。很多人刚学的时候会把它们混在一起实际上恢复技术主要操心的是那两个“保险”属性出了故障后事务怎么“撤销”才能保证原子性怎么“重放”才能保证持久性。我在实际工作中习惯把事务想象成“一段有明确边界的工作流”。边界就是BEGIN和COMMIT/ROLLBACK。只要边界清楚了恢复系统才知道要撤销哪些操作、重放哪些操作。边界不清晰恢复就无从谈起。2.2 事务怎么结束COMMIT与ROLLBACK事务的结束方式只有两种。一是COMMIT也就是正常提交。此时事务对数据库的所有修改都已生效数据库系统需要保证这些修改在后续任何故障中都不丢失。二是ROLLBACK也就是主动回滚。可能因为代码逻辑判断出错也可能是用户手动取消事务自行放弃所有修改数据库恢复到事务开始前的样子。从数据库内部来看COMMIT其实不只是返回“成功”那么简单。它背后往往涉及一系列动作把该事务产生的日志强制落盘确保崩溃后可以重放、释放此事务占用的锁、通知其他等待该锁的事务可以继续了。只要这一步做到了这个事务就算“铁板钉钉”。很多刚入行的开发以为COMMIT只是客户端收到的确认消息实际上它意味着数据库内部已经完成了持久化准备。一个容易忽略的细节是事务内任何一条SQL的执行失败比如插入数据违反唯一约束并不一定导致整个事务自动回滚。InnoDB默认行为下SQL错误只会回滚出错的语句而不是整个事务。只有你显式执行ROLLBACK或者事务提交时发现日志写不上盘这类致命问题才会发生整体回滚。这个行为差异会导致很多“莫名其妙丢了一半修改”的错觉其实是应用层没有正确控制事务边界。2.3 三张表理清故障类型做数据库恢复之前必须先判断故障属于哪一类因为不同故障的恢复策略是完全不同的。教科书里通常把故障分成三类事务故障、系统故障、介质故障。我用一张表把它整理清楚故障类型典型原因影响范围恢复重点事务故障程序异常、死锁、约束冲突单个事务本身只撤销这个未提交事务UNDO系统故障断电、操作系统崩溃、数据库实例宕机内存数据全部丢失磁盘数据基本完好重做已提交事务REDO撤销未提交事务UNDO介质故障磁盘损坏、数据文件被误删或损坏磁盘上的数据文件丢失依靠备份加上归档日志恢复REDO事务故障的恢复最轻量只是某一个事务的“烂尾楼”需要拆除不影响其他已完成的工作。系统故障是最常见的“硬启动”场景机器重启后磁盘内容还在但内存缓冲区里的数据全没了需要靠日志把已提交但未落盘的修改重新写回磁盘。介质故障是最严重的灾难磁盘物理损坏或文件被删光靠日志已经不够了必须有一份备份在手里再配合归档日志把数据库推进到故障前一刻。我在排查问题时习惯先判断这个“病”是单条数据的逻辑错误还是整个实例起不来还是磁盘上的文件真没了。三类问题的解决方案完全不在一个量级上。判断错了后面操作就是白忙甚至可能加重损坏。3. 日志系统恢复技术的核心基础设施数据库恢复技术里最核心的机制就是日志。日志的作用很像记账用的流水账本——每一项你做过什么修改都按顺序记录下来。万一账本出现问题就可以凭着流水把账重新捋一遍。但日志不是随便记记就行它要满足非常严格的写入要求。数据库界把这套要求称为WALWrite-Ahead Logging预写式日志。说人话就是在修改数据文件之前必须先把对应的日志记录写入持久化存储。这个顺序不能反。为什么因为日志是唯一可靠的证据。如果先改数据文件日志还没落盘就断电重启后数据库根本不知道这步修改是来自哪个事务也不知道该不该撤销而只要日志在先即使数据文件里的修改没来得及发生恢复时也能根据日志“重做”出来。3.1 WAL的硬性要求WAL的规则可以拆成两条。第一数据页的修改落盘之前该修改对应的日志记录必须先落盘。第二事务提交时该事务的日志记录必须先落盘提交才能被确认。这两条规则保证了日志与数据文件的先后关系既支持REDO也支持UNDO。我把WAL理解为“先留下证据再干活”。就像出门办事前先跟家里人说清楚去哪里、办什么万一中途失联家人也能凭这条信息找到你。数据库如果不做WAL那缓冲区里的脏页写盘顺序一旦错乱系统崩溃后谁都说不清哪个页面是新的、哪个是旧的整个恢复过程就彻底没依据了。生产环境里很多DBA调优时会把日志刷盘策略改来改去但WAL的“先日志后数据”这条底线永远不能碰。碰了稳定性的根基就没了。你可以放宽日志的落盘频率换取性能但不能让日志的写入顺序晚于数据文件。3.2 UNDO日志撤销还是撤销UNDO日志记录的是“操作之前的值”。当系统需要回滚一个事务时就根据UNDO日志把被修改的数据恢复到修改前的样子。比如事务要把账户余额从100改成80那么UNDO日志里记录的就是“余额原本是100”。一旦事务需要回滚就把100写回去。UNDO日志主要用于事务故障恢复。系统的逻辑很简单发现事务未提交就沿着该事务的日志链从后往前逆序执行撤销。这里有一个细节值得注意为什么是从后往前逆序因为后写的修改可能依赖前面写的中间状态必须按照“最后改的先撤销”的顺序才能回到事务开始时的原始状态。就像拆积木你得从顶部开始一块块拆不能直接从地基下手。我对UNDO的另一个体会是它不只是给“主动回滚”服务的。现代数据库里有一类被广泛使用的能力叫作MVCC多版本并发控制它让读操作不用加锁也能看到某个时刻的历史快照而历史快照的数据来源就是UNDO日志。所以说UNDO是一条“后悔药”既是回滚的底气也是并发控制里提供旧版本数据的关键材料。3.3 REDO日志重做还是重做REDO日志则相反它记录的是“操作之后的值”。数据库在恢复时会顺着日志重放已提交事务的修改把那些还没来得及写回磁盘的更新重新写到数据页上。比如事务已经提交把余额从80改成了200REDO日志里就记录“新值是200”。断电后即使磁盘上仍是80恢复时一看到这条REDO日志照样可以把200写回去。REDO日志的关键使用场景是系统故障恢复断电了内存里一堆“已提交但还没落盘”的修改全丢了怎么办从日志里找出已提交事务的REDO记录全部重放一遍数据就捡回来了。这里你可能会问既然修改最终才落盘那我直接把所有数据都及时刷盘不行吗答案是可以但代价太高。每次事务提交都强制把相关数据页写回磁盘性能损失巨大。用REDO日志转嫁这个成本可以让数据页的落盘变得“松散”甚至延迟只要日志先落盘数据库就能在崩溃后重演修改。我在讲解WAL时经常用一个比喻数据文件是一张白纸上的答案日志是草稿纸上的演算过程。考试交卷时答案写没写全不重要草稿纸还在评委就能帮你把答案重新推出来。3.4 为什么日志要先落盘这里必须展开讲一下“落盘”这件事。开发同学往往觉得把内容写入文件就算持久化了其实写文件一般只是写入了操作系统的页缓存page cache还没真正写到磁盘硬件上。要真正持久化必须调用fsync这类强制刷盘操作。数据库日志的“落盘”指的就是从内存经过页缓存最终抵达磁盘的完整链路。所以WAL的落盘顺序包含两层含义日志记录要先于数据页进入日志缓冲区事务提交时日志缓冲区要刷到磁盘。第一层是顺序上的约束第二层是持久化程度上的约束。缺了任何一层恢复的可靠性都得不到保证。我实操过的数据库产品里基本都提供了“日志刷盘频率”的调优参数。比如MySQL InnoDB的innodb_flush_log_at_trx_commit可以设为0、1、2。设为0时每秒刷一次日志性能最好但断电可能丢失1秒的已提交数据设为1时每次提交都刷最安全设为2时日志写入系统页缓存但不主动刷盘跨操作系统崩溃会丢数据但数据库实例崩溃不会丢。怎么选完全取决于你的业务对RPO恢复点目标的容忍度也就是允许丢多少数据。这也是数据库恢复技术落到生产环境时最真实的取舍。4. 检查点技术给日志画一条“安全线”日志是好东西但问题在于日志会无限增长。如果每次系统恢复都要从磁盘上最老的一条日志开始扫描随着运行时间变长恢复过程会越来越慢最后慢到不可接受。于是数据库引入了检查点Checkpoint机制。检查点的作用是周期性在日志序列上画一条“安全线”。安全线之前的日志内容对应的数据修改已经全部落盘恢复时不需要再往前追溯安全线之后的日志才需要在故障恢复时重点关注。相当于一个进度标记看到这个标记就知道活干到哪儿了后面不用回头看。4.1 没有检查点的恢复过程你可以试想一下一套没有检查点的恢复流程会是什么样。数据库已经连续跑了一周日志文件累积了海量记录。某天凌晨突然断电重启实例恢复系统必须从头扫描这周的日志找出每个已提交事务进行重放。这一周里的事务数量可能上百万扫描和重放的时间会长到无法接受。期间数据库虽然启动了但处于恢复状态不能提供完整的读写服务。有了检查点后恢复系统直接从最近一次检查点开始处理之前的日志数据已经通过检查点动作固化到了磁盘可以安全忽略。恢复时间从“按天计算”缩短到“按分钟甚至秒计算”。生产数据库能快速恢复可用很大程度上靠的就是这套机制。4.2 检查点的工作流程课本上介绍检查点通常包含这几个步骤把内存中所有脏页被修改过还没写盘的数据页尽量写回磁盘在日志文件中写入一条检查点记录记录当前正在执行的活动事务列表以及它们的日志位置持久化这条检查点记录让安全线真实“落锚”。检查点之后恢复系统从哪里开始扫描日志呢从最后一条检查点记录开始。扫描过程中会遇到三种典型事务检查点之前已经提交的不用管检查点之后才提交的需要REDO检查点发生时还活跃、随后一直没有提交的需要UNDO。具体的判定逻辑下一节结合恢复流程再说。实际操作中检查点不是越频繁越好。每次检查点都要把大量脏页写回磁盘非常消耗I/O。如果每秒都做一次检查点系统性能会受到明显影响。数据库产品一般会根据日志量、脏页比例、时间间隔自动触发检查点。我给刚入行的朋友的建议是默认参数先用着除非你明确遇到了“脏页堆积太多导致恢复时间过长”这类问题否则不要手贱去乱调检查点频率。我见过很多“优化”反而是把系统调崩溃的。5. 三类故障的恢复流程从原理到操作把日志和检查点搞清楚之后就可以进入恢复流程的实操层了。这里我按故障类型来拆对应教科书里的三个经典场景每一步都讲清楚“为什么这么做”而不是只背流程。5.1 事务故障恢复事务故障是最轻量的一类。比如某个事务在运行过程中因为死锁被选为牺牲者或者应用中抛出了异常导致事务无法继续但其他事务一切正常。此时要做的只有一件事撤销这个未提交事务的修改把该事务动过的数据恢复到它开始之前的状态。具体恢复步骤可以概括成三步从日志中找到该事务的所有操作记录按事务标识过滤出来。从最后一条操作记录开始逆序执行UNDO日志记录的旧值回写。把该事务标记为“已回滚”然后释放它占用的所有锁资源。为什么逆序遍历前面已经说过。需要强调的是系统故障恢复时也会执行UNDO但只针对那些在故障发生时尚未提交的事务。事务故障恢复更像是“定点清除”目标明确不影响其他事务。5.2 系统故障恢复系统故障比如断电、操作系统崩溃是恢复技术里最典型的场景。数据库实例重启后内存缓冲区的内容全部丢失磁盘上的日志文件完整数据文件大部分完整。这时需要做的事有两件REDO掉所有已提交的事务UNDO掉所有未提交的事务。常见的顺序是先从头扫描日志定位最后一次检查点然后基于检查点开始扫描收集两类事务名单——已提交事务和未提交事务。对已提交事务顺序执行REDO把新值写入数据页对未提交事务逆序执行UNDO把旧值回写。这个过程通常被称为“崩溃恢复”或“前滚恢复”。很多人以为REDO就是把日志从头到尾放一遍其实不是。它只重放“检查点之后且已提交”的事务因为检查点之前的修改已经落盘了。还要注意执行的顺序REDO必须按日志原始顺序正向执行因为有些事务之间存在数据依赖后执行的修改可能依赖先执行的中间结果。这也是为什么日志记录里往往有一个全局递增的日志序号LSN恢复系统靠它维护顺序。你可以把系统故障恢复理解成一次“手术”先把已经确定有益的修改重新做一遍再把不确定的、未提交的修改全部清掉。手术之后数据库回到一个干净的一致性状态。5.3 介质故障恢复介质故障是最麻烦的一种磁盘损坏或数据文件被误删。这种情况下内存日志也救不了你——日志可能已经被轮转清理磁盘上的数据文件直接没了。恢复流程分两步走第一步加载最近的一份全量备份第二步把这份备份之后产生的日志归档日志按顺序重新应用到数据库上。完整流程可以这样写确认备份文件有效把全量备份恢复到指定目录。启动数据库实例让它进入恢复模式。从备份点之后的时间戳开始按日志序号顺序应用所有归档日志把数据库推近到故障前的状态。检查是否有未完成的活跃事务做最后的UNDO清理。校验数据确认无误后恢复对外服务。这里最关键的一点是日志链必须连续。哪怕中间缺少一段日志恢复过程就会“断链”后面的日志无法继续应用数据只能恢复到断点位置。所以我一直提醒运维的同学备份和日志归档要一起规划缺了任何一个介质故障恢复就成了无米之炊。从备份策略角度看全量备份就像是快照而归档日志则把快照之后的每个变化都录了下来。两者结合才能实现大家常说的PITRPoint-In-Time Recovery时间点恢复——你可以把数据库恢复到过去任意一个时间点只要那个时间点之后的日志还在。这个能力在做误删数据恢复时极为好用。6. 教科书理论如何落到现代数据库看完了抽象的恢复原理如果不去看看真实产品怎么实现总感觉有点虚。这一节我以最常见的MySQL/InnoDB和PostgreSQL为例把理论对上号。你会发现教科书上那一套在现代数据库里有着非常清晰的对应物。6.1 MySQL/InnoDB的redo log和undo logInnoDB把REDO和UNDO分得很清楚。Redo log是物理日志记录的是“某个数据页、某个偏移量、被改成了什么内容”主要用于崩溃恢复保证已提交事务不丢。Undo log则是逻辑日志记录的是行记录的修改链路除了用于事务回滚还承担MVCC的历史版本读取职责。值得说的是InnoDB的redo log是固定大小、循环写入的。它被分成一组文件写满后覆盖最老的未被检查点刷盘释放的部分。所以redo log不是无限的它只保留从“上次检查点落盘位置”之后的部分。数据页一旦通过检查点安全落盘对应的redo log空间就能被覆盖重用。理解了检查点之后你就会明白为什么InnoDB的redo log可以做成“环形缓冲”而不担心丢失数据——因为它保证在覆盖之前该日志对应的数据修改已经落盘。Undo log在InnoDB里存放在系统表空间或独立的undo表空间中。你可能会好奇事务一旦提交undo log是不是马上删掉不是。因为还有MVCC在用它如果有长事务/快照读还在使用某个历史版本那个版本的undo记录就必须保留。这也是为什么生产环境里会出现“undo膨胀”的问题本质上是旧版本无法清理。从这个角度看UNDO日志不只是恢复技术的事它和隔离级别、事务生命周期都纠缠在一起。6.2 PostgreSQL的WAL与PITRPostgreSQL里的WAL机制对应MySql的redo log它记录的也是页面级的修改用于崩溃恢复。PG的WAL在逻辑上可以认为是一个无穷的归档序列如果不做清理会一直保留下去。PG也提供了检查点机制定期将共享缓冲区里的脏页刷盘然后切换WAL段文件旧的段可以被归档工具拿走成为PITR的基础。PG的PITR恢复流程很有代表性先用一份基础备份base backup把数据目录恢复到某个时间点然后配置recovery.conf或recovery.signal新旧版本配置方式不同指定要重放的WAL归档目录以及恢复目标时间点。启动数据库后PG会按顺序重放WAL直到目标点。这种能力在数据误删后的“倒带”场景特别好用比MySQL的物理恢复过程更直观。我在讲解PG的PITR时总会强调三点基础备份要跟WAL归档配套归档要连续恢复目标要精确。很多同学平时备份做得勤但从未真正演练过PITR恢复真出事时才发现归档从某个时间点就断了只能恢复到更早的位置。这是运维层面的深刻教训。6.3 组提交与刷盘策略现代数据库对WAL还做了一个很重要的性能优化叫组提交Group Commit。简单说多个事务提交的时间窗口很接近数据库就把它们合并成一批用一次fsync刷盘而不是每个事务分别刷一次。这样既保证了日志先落盘的语义又大大减少了磁盘I/O次数。这个优化有一个本质原因fsync的代价非常高磁盘每秒能完成的同步刷盘次数有限。一次刷盘能带上多个事务的日志平均到每个事务上的I/O成本就低多了吞吐量自然上去了。但是组提交会增加事务提交的响应延迟——提交快的那个事务可能要等一等同伴。这个权衡在数据库产品里通常会有参数去调节团队可以根据业务场景在吞吐和时延之间做取舍。我分享一个实践判断方法如果核心业务对单事务提交延迟非常敏感比如金融交易的扣款可以用每次提交都刷的方式换低延迟如果业务追求吞吐量能容忍提交稍有延迟用组提交模式更合适。没有绝对正确的参数只有适合你业务场景的选择。7. 日常运维必须养成的恢复习惯最后聊点“软件工程之外、但比软件更救命”的事情。数据库恢复技术的理论再扎实落到生产环境时真正决定生死的是备份策略、恢复演练和常见误区。这三样不是课本第几页能教完的但我在项目里看出的事故有一半都栽在这上面。7.1 备份策略恢复的起点备份是恢复的起点。没有备份介质故障恢复就是空谈。但“有备份”不等于“备份可用”。我觉得一个合格的备份策略至少要回答三个问题备份周期是多久保留几份存放在哪里常见的策略是全量加增量定期全量备份两次全量之间做增量备份。日志归档则单独保存保留周期取决于业务对“可回退深度”的需求。业内有个“3-2-1原则”值得借鉴至少保留3份数据存放在2种不同介质上其中1份跨机房或异地保存。我所在的项目还特别坚持每个季度做一次恢复演练不是检查备份文件能不能读而是真正把备份恢复到一台测试机上执行数据校验。只有经过完整演练的备份才能在故障发生时让人放心。7.2 恢复演练别让备份变成“纸上备份”很多研发团队把备份做得很勤脚本定时跑日志有告警但从来没真正把备份恢复出来过。我第一次组织恢复演练时就被坑过备份文件大小看着正常恢复时发现某个表的索引文件损坏数据文件解压到一半报错。幸好是演练如果是生产事故那就真成事故了。恢复演练的常规动作是找一台与生产配置相近的机器使用最新的全量备份加归档日志执行一遍完整恢复流程比对恢复后的数据总量、关键表行数、关键字段分布与生产历史数据是否吻合最后验证应用能否正常连接和读写。这个流程每季度至少过一遍过程中发现的脚本BUG、归档缺失、磁盘空间不足之类的问题全部要修掉并再次验证。从成本角度看恢复演练的确占资源但它换来的是故障时的确定性。我在项目里会把“恢复演练报告”作为数据库变更上线的必要提交物之一。数据库版本升级、备份策略调整之后更是要第一时间做一轮演练确认新配置下恢复链路依然通畅。7.3 常见误区盘点最后梳理几个日常运维中最常见的误区都是我亲眼见过或者踩过的。一是把RAID当作备份。RAID能防单块磁盘物理损坏但对误删除、逻辑损坏、软件BUG造成的数据破坏无能为力。你执行一条DROP TABLERAID阵列根本拦不住日志也救不回。真正能救你的是备份。二是觉得“日志文件不重要可以随手清理”。日志是崩溃恢复的命脉。清理日志前必须确认对应的数据页已经通过检查点安全落盘或者日志已经被归档保存。否则恢复时发现日志断链数据就只能停在断点之前。三是把binlog和redo log搞混。MySQL里binlog用于主从复制和审计redo log用于崩溃恢复。两者目的不同、写入时机不同、格式也不同。有些同学以为开了binlog就高枕无忧结果实例崩溃后才发现binlog对崩溃恢复没有帮助崩溃恢复靠的是redo log和undo log。四是接口只有备份没有恢复方案。前两条做好之后再配一份每位值班人员都能看懂的“恢复手册”包括备份位置、归档日志位置、恢复命令、验证SQL、联系人。故障发生的那一刻大家都很紧张一张清晰的操作清单比什么都管用。我在实际项目中见过不少平时理论背得滚瓜烂熟的同事一遇到介质故障因为备份断档、日志被误删或恢复顺序不对硬生生把可用性指标拉垮。反而是那些只要守住WAL顺序、坚持恢复演练、文档齐全的团队遇到再大的故障也能在不眠之夜的两三个小时内把库拉起来。数据库恢复技术说到底是一套“兜底”能力。你可以祈祷永远不要用到但你必须确保需要它的那个凌晨整套链路是通的。最后再分享一个我自己很喜欢的做法把日常备份脚本的恢复结果和告警接在一起——备份成功不是一个脚本执行完就算数而是“恢复演练成功率”这一指标长期维持在100%。这套思路建议你拿回去也试一试。
返回列表