用心打造
VPS知识分享网站

云服务器明明做了快照,为什么恢复后还是丢数据?这个坑值得提前了解

以前用云服务器的时候,我对快照的理解很简单。

只要定期在控制台创建快照,哪天系统出了问题,直接恢复不就行了?网站文件、数据库、系统配置应该都能回到之前的状态。

后来认真研究了一下才发现,事情没这么简单。

尤其是服务器上跑着MySQL、Docker、WordPress这些需要持续写入数据的程序时,快照创建成功,不代表里面所有数据都处于可以直接恢复的状态。

这也是为什么有些人明明每天都在做快照,真正需要恢复的时候,还是会碰到数据库异常、文件缺失,甚至网站无法启动的问题。

云服务器明明做了快照,为什么恢复后还是丢数据?这个坑值得提前了解

快照保存的到底是什么

先搞清楚一个概念。

云服务器快照主要保存的是磁盘在某个时间点的数据状态,而不是给正在运行的程序拍一张完整照片。

例如一台云服务器有50GB系统盘,里面装了Ubuntu、Nginx、MySQL和WordPress。

创建磁盘快照以后,云平台会按照自己的存储机制保存相应的数据块,后续可以基于快照恢复磁盘或者创建新磁盘。

但这里有个容易被忽略的细节。

磁盘上的数据,不一定等于程序此刻所有已经处理的数据。

Linux有文件缓存,MySQL有Buffer Pool、Redo Log,应用程序也可能把数据暂时放在内存里。

某些数据还没完全写入磁盘,快照就开始创建了。

恢复以后,文件系统或者数据库可能需要执行崩溃恢复。数据库具备一定的恢复能力,但不代表每一种应用都能完整恢复,也不能保证最后几次写入一定保留下来。

所以快照成功,更准确地说是磁盘层面的备份动作成功,而不是应用数据已经全部经过验证。

为什么数据库比普通网站文件更容易遇到问题

静态文件相对好理解。

一张已经上传完成的图片,一个很久没有修改的HTML文件,只要所在磁盘被快照覆盖,恢复起来一般比较直接。

数据库则完全不同。

例如用户刚提交一笔订单,MySQL需要修改多条记录,同时处理事务、日志和索引。

假设快照恰好发生在数据库持续写入的时候,磁盘上不同数据块的写入状态就可能处于一个比较复杂的阶段。

成熟的数据库有事务日志和崩溃恢复机制,能够处理不少意外中断场景,但这里仍然存在边界。

尤其应用涉及多个数据库、多个磁盘,或者数据库写入需要与外部文件保持一致时,恢复难度会明显增加。

这也是为什么我现在不太喜欢把数据库备份完全交给云平台快照。

快照适合快速恢复整块磁盘,数据库还应该有自己的独立备份。

MySQL可以单独导出,不一定非要停掉网站

对于数据规模不大的WordPress网站,最容易上手的方案就是定期导出MySQL。

例如使用

mysqldump --single-transaction --quick -u backup_user -p wordpress > wordpress.sql

这里的wordpress需要替换成实际数据库名称,backup_user也需要有相应的备份权限。

其中--single-transaction比较值得注意。

对于使用InnoDB事务表的数据库,它可以在不长时间锁住正常业务写入的情况下,获得一个相对一致的逻辑备份视图。

但如果数据库还存在MyISAM表,或者备份过程中有其他连接执行修改表结构的操作,就不能简单认为所有内容都能保持一致。

这个命令也不会自动包含网站上传的图片、插件文件以及其他数据库之外的数据。

导出SQL只是数据库备份,不能代替整个网站的备份。

WordPress真正要备份的,不止一个数据库

拿WordPress来说,我现在至少会把两类数据分开保存。

一类是MySQL数据库,里面有文章、评论、用户、站点设置,以及部分插件数据。

另一类是网站文件,包括上传的图片、主题、插件和配置文件。

比如wp-content/uploads目录,文章里显示的图片很多都保存在这里。

如果只恢复数据库,没有恢复上传文件,就可能出现文章正常显示,图片却全部失效的情况。

反过来,只有网站文件,没有数据库,文章和后台数据也可能恢复不回来。

所以单独备份WordPress时,我不会只留一份SQL。

还会保留网站文件,并记录数据库配置、PHP版本以及其他恢复时需要的信息。

快照应该在什么时候使用

说了这么多,并不是说云服务器快照没有价值。

恰恰相反,我觉得快照非常值得保留,只是要用对地方。

比如准备升级PHP、修改系统环境、调整磁盘分区,或者进行一次风险比较高的系统操作。

动手之前先创建一份快照,出了问题以后就有机会把磁盘恢复到操作前的状态。

这比重新安装系统、手动恢复所有配置方便不少。

但正式业务最好进一步确认云平台有没有提供应用一致性快照,是否需要暂停写入,以及多个磁盘能不能保持同一恢复时间点。

有些云平台支持配合脚本暂停或刷新IO,再创建应用一致性快照。它和直接对正在写入的磁盘拍快照,并不是完全相同的保护级别。

尤其是数据库业务,这一点值得提前弄清楚。

备份放在同一台服务器里,我也不太放心

这是另一个容易踩的坑。

有些人会每天把数据库导出到服务器的/backup目录。

脚本运行得很好,每天都能看到新的SQL文件。

但数据库、网站和备份全部放在同一块磁盘上。

哪天磁盘损坏、实例被误删,或者服务器遭到恶意破坏,这些备份可能跟着一起消失。

所以我现在至少会把一份重要备份放到独立的存储位置。

对象存储、另一台备份服务器,或者其他具备独立权限控制的存储空间都可以考虑。

而且备份存储最好有单独的访问权限,条件允许还可以开启版本保留或防删除机制。

备份和源数据放在同一个故障范围内,并不能解决所有数据丢失风险。

真正让我改变习惯的是恢复测试

以前看到备份任务显示成功,我就觉得安心了。

现在我更在意另一个问题。

这份备份到底能不能恢复?

例如某个WordPress网站每天凌晨自动导出数据库,但脚本实际上早就因为权限问题失败了。

备份目录里可能还留着上个月的SQL文件,看起来有备份,实际却根本不是最新数据。

还有一些备份文件大小正常,真正导入的时候才发现内容不完整。

所以我现在更愿意定期找一台独立测试服务器,把备份真正恢复一次。

数据库能不能导入,网站图片是否完整,后台能否正常登录,文章和订单有没有缺失。

这些检查比单纯看备份文件是否存在有意义得多。

另外,恢复测试最好隔离邮件发送、支付回调、定时任务和其他真实业务接口,避免测试站意外触发生产操作。

毕竟备份的最终目的不是产生一个文件。

而是在需要的时候,真的能把业务恢复起来。

我现在更倾向把快照和独立备份一起使用

快照用来处理整机或磁盘级别的恢复需求。

数据库逻辑备份用来保存应用数据,方便单独恢复、迁移或者检查内容。

网站文件则另外保存,避免只有数据库没有图片和程序文件。

重要数据再留一份异地副本,减少单个服务器或者存储位置故障带来的损失。

这几种手段并不冲突,反而可以互相补充。

对于更新频繁的业务,还需要按照能接受的数据丢失时间来决定备份频率。每天备份一次,意味着仅靠这些备份恢复时,最坏情况下可能损失接近一天的新数据。

业务越重要,越不能只凭感觉安排备份。

以前我觉得云服务器有快照功能,就已经算比较安全了。

现在我的想法变了。

快照是恢复手段之一,但真正可靠的备份,需要数据完整、存储独立,而且经过实际恢复验证。

备份任务执行成功只能算完成了一半。

剩下的一半,要等你真正把数据恢复出来,才知道有没有做好。

赞(0)
未经允许不得转载;国外VPS测评网 » 云服务器明明做了快照,为什么恢复后还是丢数据?这个坑值得提前了解
分享到