当前位置: 首页 > 科技观察

无法恢复数据库?不存在的!

时间:2023-03-21 20:27:08 科技观察

我们在工作中经常会用到存储服务,比如mysql、mongo、redis等,如果我们有一个DBA就好了,可以帮我们管理维护,定期备份等等,但是我们经常开发数据库自己开发工具平台时,忽略了定期备份,留下了安全隐患。果不其然,我最近收到了一位团队成员的求助。服务器挂了,重启后mysql服务无法启动。关键是没有备份!!折腾了很多,总结了处理过程和坑,供大家参考。MySQL崩溃或MySQL数据库服务器崩溃会导致日志损坏、数据文件损坏等各种问题,本案例就是其中之一。仔细从日志中找到相关错误提示,逐步解决。首先在出现问题的机器A上启动mysql,查看情况。查看mysql错误日志找出原因。从日志内容分析,本机数据库崩溃,文件损坏。这里使用非常规手段。首先修改innodb_force_recovery参数让mysqld跳过恢复步骤,然后启动mysqld,导出数据,然后重新创建数据库。先科普下知识:innodb_force_recovery可以设置为1-6,默认为0,较大的数字包含前面所有数字的影响。1.(SRV_FORCE_IGNORE_CORRUPT):忽略检测到的损坏页面。2.(SRV_FORCE_NO_BACKGROUND):阻止主线程运行。如果主线程需要执行全清除操作,就会导致崩溃。3.(SRV_FORCE_NO_TRX_UNDO):不执行事务回滚操作。4.(SRV_FORCE_NO_IBUF_MERGE):不执行insertbuffer的merge操作。5.(SRV_FORCE_NO_UNDO_LOG_SCAN):在不查看重做日志的情况下,InnoDB存储引擎会将未提交的事务视为已提交。6.(SRV_FORCE_NO_LOG_REDO):不执行前滚操作。注意,当参数值设置大于0时,可以对表进行select、create、drop操作,但不允许insert、update、delete等操作。修改/etc/my.cnf下的innodb_force_recovery值为4后,启动mysql,立即导出数据/usr/local/mysql/bin/mysqldump-uroot-hlocalhost-P3306-p--default-character-set=latin1--添加删除数据库--锁定表--单事务-q--触发器-A--结果文件=/home/fuhaitao/3306。sql导出成功后,找一台B机,在mysql实例中导入这个sql文件。mysql-uroot-p-S/tmp/mysql3333.sock--default-character-set=latin1<3306.sql搞定了,我们看看数据是否正常。..乱码,查看mysql的编码方式,编码是utf8,但是我在A机导出的时候指定了字符集为latin1,所以我把编码改成Latin1,看看数据是否还是乱码,说明导入的数据编码和数据库编码不一致,发现由于机器用户较多,各个数据库的编码不一致,有utf8和latin1,只能一一导入。回到A机将指定utf8编码的乱码数据库导出,并将sql文件传输到B机,导入后在B机上执行,查看数据是否正常。哎呀,成功了。然后停止机器A的mysql,修改/etc/my.cnf中innodb_force_recovery的值为0,经过一番折腾,终于解决了问题,恢复了5年的数据。***给大家一些建议:1.如果公司有DBA团队,尽量使用DBA团队的存储服务,他们可以提供专业的支持。2、数据库要定期备份,以免因特殊情况造成文件损坏和数据丢失。3、导入数据时,检查编码方式,确保数据库、数据文件、编辑器的编码方式一致。