数据库备份恢复:静默损坏怎么查?页校验和与指纹比对
大家好我是数据库小学妹 我踩过的坑你别再踩。刚入行那会儿我特别信备份任务后面那个绿色对勾。它每天按时变绿我就当数据没事了。直到有次恢复演练备份导出来服务是起来了。可一核对才发现某张表的一批关键行值居然是错的。更麻烦的是这个错上一次备份里就已经有了不是这回才坏的。从那之后我就不敢只盯着那个勾了。备份成功顶多说明文件写出来了。数据对不对那是另一回事得自己另外验一遍。先分两层看可靠性数据可靠性得拆成两层。一层是可用性备份能不能把服务拉起来RTO 够不够短。另外一层是正确性拉起来的数据是不是你要的那份。多数团队在监控和演练里只验了前一层。这两层出问题的原因不一样。可用性的敌人是流程备份失败、恢复脚本跑不通。正确性的敌人更隐蔽是数据在没人碰的时候自己坏了。数据怎么会悄悄坏损坏的来源大致有三类。第一类是存储层的位翻转磁盘、控制器、固件上的偶发错误。第二类是内核或异常路径上的 bug某些边角逻辑写坏了页。最后一类是人为的操作比如半截的 DDL、直接改数据文件的误操作等。这三类统称静默损坏。静默损坏得跟断电丢不丢数据分开看。断电是提交语义的问题日志能兜住。静默损坏不一样是数据本身变了系统却以为自己对。日志也救不了它因为错误一开始就被当成了正常写入。怎么发现坏页日志兜不住静默损坏就只能靠数据自己去发现。常用的是两个机制。一个是页校验和每个数据页带一段校验值读页的时候顺带验一遍对不上就报坏页。另一个是双写写页之前先写一份到专门的区域防止写到一半断电页只写了一半。校验和也有它的边界。它通常要读到那一页才会去验。一个页几个月没人碰坏了也没人知道直到哪天被读到问题才露出来。还有不少引擎的校验和默认开着也有默认关的。接手一套老库需要先确认它属于哪种情况。# PostgreSQL离线校验数据文件的页校验和需停机或在副本上做pg_checksums--check-D/var/lib/pgsql/data为什么备份也跟着坏坏页不只在库里备份也会把它一起带走这点最容易被忽略。物理备份是把数据文件原样拷走坏页也一起拷走。你以为拿到的是一份干净副本其实坏的地方一个不少。如果是增量或日志备份损坏还可能沿着时间线一直传下去越传越深。所以备份成功和数据可恢复之间隔着一次真的验证。我现在的底线是校验和扫描要定期跑备份恢复演练要验数据本身。怎么验才算数验数据本身比只看行数麻烦得多。行数对得上不代表内容对得上。金额被截断、状态映射错条数照样一条不差。我一般做三层比对。第一层是行数与主键范围快但最粗。第二层是字段级指纹把关注字段拼起来算个校验值主从比、新旧比。第三层是抽样明细指纹对不上时抽样定位到具体是哪些行。-- 字段级指纹不只看行数把关键字段一起算进去SELECTCOUNT(*)ASrows,BIT_XOR(CRC32(CONCAT_WS(#,id,status,amount,updated_at)))ASfingerprintFROMt_order;避坑清单说了这么多落到日常就下面这几条。都是我以前踩过的坑。别把备份任务的成功当成数据安全的证明。成功只覆盖了文件写出来这一步数据对不对、能不能恢复它一个字都没说。备份恢复演练必须验数据正确性不能只验服务能不能启动。我见过演练报告写恢复成功其实是数据库起来了数据对不对没人比过那等于没验。最后一条是我自己搞错的。我以前对账只看行数对上了就签字。后来才发现金额被截断了条数照样一条不差。现在至少加一步字段级指纹宁可多跑一遍。写在最后数据可靠性是两层账。可用性的账备份和演练能算清。正确性的账得靠校验和、指纹还有一次次真恢复去算。这两层账最大的不同是前一层坏了会喊后一层坏了不说话。它只会安安静静地错下去等你自己发现。只算前一层等于把后一层交给了运气。你上次恢复演练是只看了服务起没起还是真比过数据评论区聊聊。我是数据库小学妹帮你少走弯路少踩坑咱们下篇见