前两天一个站长朋友半夜给我打电话,说他的论坛数据库崩了,几万个帖子眼看就要打水漂。电话那头的声音都在发抖,我隔着屏幕都能感受到那种绝望。Discuz作为国内最老牌的开源论坛系统,从2002年走到今天,撑起了无数个社区和论坛,但数据库这东西,说白了就是论坛的心脏,心脏一停跳,整个站点就跟死了一样。

我见过太多站长在数据库出问题时手足无措,有的直接瘫在椅子上不知从何下手,有的病急乱投医乱点一通反而把局面搞得更糟。其实Discuz数据库恢复没有想象中那么玄乎,只要搞清楚故障类型,按步骤来,大部分情况都能救回来。今天我就把这些年积累的经验掰开揉碎了讲给你听,遇到事儿别慌,照着我说的做就行。
先说说最常见的几种数据库故障。第一种是“服务起不来”,就是MySQL或MariaDB服务直接挂掉,报错信息五花八门,什么“Can't connect to MySQL server”啦,“Table is full”啦,看着吓人,但很多时候只是磁盘满了或者内存不足。第二种是“数据表损坏”,论坛前台打开一片空白,或者报错说“Table './discuz/forumthread' is marked as crashed”,这种通常是服务器突然断电或者强制重启导致的。第三种最要命,就是误操作删了数据或者被黑客拖库,这种情况心里要有数,能恢复多少算多少。
先说服务起不来的问题。遇到这种情况,第一步不是去动数据库文件,而是先看磁盘空间和系统日志。用命令看一下磁盘是不是满了,很多Discuz站点的数据库文件动辄几个G,日志文件也疯狂增长,磁盘一满服务就自动停了。如果磁盘确实满了,先清理掉不需要的日志和备份文件,给数据库腾出空间。然后查看MySQL的错误日志,默认在,重点看几十行,里面会明确告诉你挂掉的原因。如果是内存不足,可以在配置文件里调低的值,或者干脆升级服务器配置。
再说数据表损坏的问题。这个在Discuz里太常见了,尤其是那些访问量大的表,比如、这些核心表,使用频率高,损坏概率也大。修复方法很简单,用MySQL自带的工具就行。在命令行下进入MySQL,执行,如果提示成功,那问题就解决了。如果是MyISAM引擎的表,也可以用工具在停掉MySQL服务的情况下直接修复,命令是。修复完重启服务,论坛基本就能恢复正常访问了。
但有时候表损坏得比较严重,REPAIR TABLE也搞不定,这时候就得考虑用备份来恢复了。我强烈建议每个Discuz站长都养成定期备份的习惯,最理想的状态是每天自动备份一次。备份方式有两种,一种是在后台用Discuz自带的备份功能,另一种是用mysqldump命令手动备份。mysqldump的命令很直观:,这样就能把整个数据库导出成一个SQL文件。恢复的时候就用,一条命令搞定。
还有一种情况是误删了数据,比如不小心执行了DELETE语句没带WHERE条件,或者被入侵者清空了表。这时候如果开启了MySQL的binlog日志,就有机会通过binlog来恢复。先说怎么开启binlog,在的[mysqld]段下加一行,重启MySQL服务就生效了。恢复的操作稍微复杂一些,需要先用工具把binlog文件解析成SQL语句,然后找到误操作的那条语句之前的位置,把前面的SQL重新执行一遍。具体命令是。这个方法对时间点要求比较高,最好在发现问题后马上停止对数据库的写入操作,免得新的数据覆盖了旧的数据。
另外还有一个比较土但很实用的方法,就是直接用物理文件恢复。Discuz的数据库文件默认存放在目录下,每个表对应一个(表结构)、(数据)和(索引)文件。如果只是某个表坏了,而且你有这个表的备份文件,直接拷贝回去覆盖原文件就行。但这里有个大坑要提醒你,MySQL的版本必须一致,不同版本之间的文件格式可能不兼容,覆盖上去反而会导致更严重的错误。
聊完技术层面的恢复方案,我特别想说几句掏心窝子的话。我见过太多站长在数据库出问题后才追悔莫及,早干嘛去了?备份这件事,成本极低,收益极高,但就是没人愿意认真做。有些站长觉得服务器稳定就不会出问题,结果硬盘说坏就坏,一点征兆都没有。还有些站长用虚拟主机,空间商提供的备份服务时灵时不灵,自己又不做二次备份,真出了事哭都来不及。
我自己的习惯是双保险:服务器本地每天自动备份一次,同时用脚本把备份文件同步到云存储上,比如阿里云OSS或者腾讯云COS,异地存储的好处就是即使整个机房都挂了,数据还在。另外每隔一周,我还会手动下载一份备份到自己的电脑上,这样就算云存储账号被盗了,手里还有一份底牌。
再强调一遍,Discuz数据库恢复这件事,七分靠备份,三分靠技术。备份做好了,恢复就是按部就班的事;备份没做好,再牛的技术也只能干瞪眼。记住,冷静下来,一步步排查,大部分问题都有解。


