有几个朋友,论坛搞得都比较大,几位朋友都属于那种只会运营网站但几乎不懂任何网站技术的那种类型,现在这样类型的成功站长越来越多,相反,像Linker这样的崇拜技术至上的半吊子,总是在初级阶段,不断徘徊,不能不说是一种讽刺。由于接触时间长了,关系都比较要好,因此这些论坛在技术支持上,几乎全部都由Linker来维护,这问题倒也不大,几年都过来了,一直按计划有条不紊的维护、升级,期间有些小问题,都有惊无险的度过了,但这次,虽然事后也可以说是有惊无险,但不能不说是,是近几年来,比较险的一次了。
其中一位朋友的综合论坛,运营已经有快三年了,会员达到了十几万,每天也有上万的ip,几万的会员浏览登陆,近几天他说,论坛运行可能有些问题,主要体现在速度上,在执行写入、浏览页面时,页面会有明显的停顿现象,并且还有会员反映,会看到打不开页面,页面出现sql乱码的情况。针对这些情况,Linker心中已经有些概念,于是今晚午夜,决定对数据库进行一下例行维护。
在修复论坛错误“is marked as crashed and last (automatic?) repair failed”的几种方法一文中(有些朋友可不大厚道,摘录了此文,作为自己的原创,更有甚至,改头换面,取其精华,作为自己的投稿、原创来做,让人汗颜,今晚搜索有关这方面问题时,才知道竟然有了这么多的CP,在遗憾之余也有些欣慰),第三种方法来修复数据库中的一些碎片,优化数据库的效果还是比较好的,并且速度也比较快,使用phpmyadmin太麻烦,使用discuz论坛提供的tools集合工作,修复起来速度太慢不说,几乎没有起过作用的,可能对于一些小的表错误问题,会起些作用。
登陆上服务器,以前的例行维护,是按照以下方法来做:
停掉mysql:net stop mysql,然后cd命令符至mysql的bin目录,再执行命令:myisamchk -r D:\MySQL\data\数据库名称\*.MYI,回车确定后,修复进程就在不断的一个表一个表,一行一行的修复中,这是discuz论坛上的童虎推荐的方法,效果比较好,推荐拥有独立服务器的使用,长期以来,Linker也一直在使用此方法来优化数据库,效果很好。但这次使用时,犯了一个错误。
也许是例行维护时间太长了吧,有些麻痹大意了,登陆上去以后,首先作了一些其它系统维护,然后就直接打开cmd,执行:myisamchk -r D:\MySQL\data\数据库名称\*.MYI,突然之间,本地主板的小喇叭连串的响了起来,这一报警不打紧,Linker立刻想起来,mysql服务还没有停掉,这样修复会直接破坏掉表的。马上关掉命令行窗口,然后立刻停掉mysql服务,再次打开cmd,执行:myisamchk -r D:\MySQL\data\数据库名称\*.MYI,本地主板小喇叭依然在响了七八次以后,然后才正常修复其它表,直至结束。心中有感不妙。
开启mysql服务,打开网站,惨了’members’ is marked as crashed and last (automatic?) repair failed,很明显,members表坏掉了,并且使用myisamchk 命令还修复不好。登陆phpmysql,显示cdb_members表在使用中,查看物理路径下表,对比了一下,一个月以前的备份,大小似乎正常。
到google、百度上搜索有关修复mysql数据库表crashed的文章,发现有关这方面的话题,除了Linker的“修复论坛错误“is marked as crashed and last (automatic?) repair failed”的几种方法”外,就属discuz论坛的这个页面流行度比较广,不外勿文初所述的三种方法,这三种方法,皆不能解决这个问题。查到国外的vbulletin.com论坛,看到有关帖子,并且还是由总版主、管理员回答的这方面问题,都是说此表已经损坏,修复几乎不可能,建议用备份来恢复,看到这些“权威”的论断,Linker心里真是“拔凉拔凉”的,由于朋友的论坛数据库比较大,因此Linker就有些懈怠,一个月左右才备份一次,这要把这个cdb_members表恢复到一个月前去,上万名会员数据就这样没了,并且可能还有着其它一些不可知的问题。
有关修复mysql数据库,还有一个命令:mysqlcheck
mysqlcheck -a -c -o -r –all-databases -uroot -p //这条命令是即可最佳化所有db数据库。
参数的意义如下:
-a = Analyse given tables.
-c = Check table for errors
-o = Optimise table
-r = Can fix almost anything except unique keys that aren’t unique
如果是在win主机下,修复指定的表,使用:mysqlcheck -o -r 数据库名称 -u root -p,在提示输入密码的框中,输入mysql的root管理密码,mysqlcheck即会对数据库进行检测修复。但很遗憾,Linker在使用了这个命令后,虽然成功执行了,但论坛表错误依旧,没有解决问题。
难道真的只有使用备份数据表来恢复了?……
打开备份的数据库目录,打开当前使用的数据库目录,看cdb_members三个表,两个目录切换来切换去,但突然感觉到,怎么有点不对?备份中的是:cdb_members.MYD,但有问题的数据库中,这个名称的表却是:cdb_members.TMD,奇怪了?正常情况下,没有看到TMD扩展名的表啊?这个TMD的扩展名可是味够浓的。
mysql数据库,数据表有三个文件支持,比如表 a041574875:
a041574875.MYI –> 索引文件
a041574875.MYD –> 数据内容文件
a041574875.frm –> 表结构文件
这个时候,却变成了
a041574875.MYI –> 索引文件
a041574875.TMD –> ?
a041574875.frm –> 表结构文件
mysql的TMD表究竟是什么文件?TMD文件是执行myisampack后生成的压缩文件,它可使文件压缩40%—70%。Linker也没查到更多的相关说明,只是发现有评论,称此文件出现,可能与硬盘问题有关,比如逻辑坏道等。Linker由此想来,估计和没有停掉mysql服务而执行myisamchk有关,这个TMD文件可能是一个备份或者待恢复机制下产生的文件。
不管那么多,通过扩展名排列目录结构,把所有TMD扩展名结尾的表全部修改为MYD结尾,然后再次执行“myisamchk -r D:\MySQL\data\数据库名称\*.MYI”(这些操作是在停掉mysql服务情况下进行的),这次没有再出现小喇叭报警的情况,执行完毕后,打开论坛,天啊,论坛页面打开正常了。赶快停掉数据库,重新备份数据库至其他服务器。至此,数据库总算给修复回来了。另:如果数据库表修复后,还会有出现TMD扩展名表的情况,就要真的查一查是否是硬盘的问题了。
这里说明一下,mysqlcheck 用在数据库服务器在运行的时候,而 myisamchk 必须是在数据库服务器被关闭的时候,因为它可能会和数据库本身的操作起冲突,会导致你的错误还没被修复,而新的损坏确已经出现。务必务必!
在有关使用mysql的TMD表恢复数据库的方法中,Linker最终查到的是知盾安全论坛中,2006年的一个帖子:用 TMD 文件修复损坏的 mysql 的数据库某个表,Linker到最后才发现,作者和Linker的问题几乎一致,并且解决思路也一样
,只是有一点点区别,Linker修改表的扩展名由TMD修改为MYD,执行Myisamchk后,数据库正常了,而知盾论坛文中,却没有解决,而是在使用mysqldump恢复数据库了以后,然后修改扩展名,数据库才正常的。
直到最后,总结一下,经历了那么多,查询了很多解决方案和实例,想了那么多思路,尝试了很多方法,事实上最终解决方法也是比较简单的。其中,也确实有幸运的成份。
给自己提个醒,硬盘有价,数据无价,再上两个硬盘,组Raid,专用来备份数据,使用计划任务来自动备份。另外,在处理长年累月的例行维护时,千万要头脑清醒,有条不紊、按步就班的持续进行,千万不要自恃已经非常熟悉了,而马虎大意;往往给事情造成重大损失的,不是什么也不会的生手,反而是有比较高权限的熟手。
上述的教训和敬告,要千万注意了。
来源:http://blog.chinaunix.net/space.php?uid=405749&do=blog&id=28215