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

从删除数据库到运行或恢复,记一次MySQL数据库文件损坏恢复的心得

时间:2023-03-12 19:58:05 科技观察

1.前言2018年5月28日,北京下了一场小沙尘暴。坐在公交车上,走路上班,想起老罗常说的一句话:我想做盛田昭夫时代的索尼,我想做乔布斯时代的苹果,于是继续学习《日本制造:盛田昭夫的日式经营学》.到了人民大学西门,在西区食堂吃早餐,穿过人民大学,很快就来到了公司。坐在工位,打开电脑登录QQ,操作CC的头像过了一会开始闪动,“无法登录慕课平台”,“看看”。过了一会儿,领导的头像开始闪动,“xxx说MOOC平台无法登录”。呃……这是不是惊动了领导?2、检查问题打开chrome浏览器开始预览,等待代理服务器反馈时间较长。暂停!使用SecureCRT连接服务器,首先重启Nginx代理服务器。servicenignxstop//关闭Nginx服务servicenginxstart//开启Nginx服务,去前台刷新几次没有恢复。然后重启php,so:servicephp-fpmstop//关闭PHP服务servicephp-fpmstart//打开PHP服务去前台试了一下,还是没有恢复。(可能有人会问为什么不直接用servicexxxrestart来重启服务呢?我也不知道为什么,个人喜好!)那么只有一种可能是数据库有问题。打开Navicat连接数据库,发现可以正常连接,可以看到所有的表。随便打开一个表可以看到里面的数据,但是弹出错误信息。goterror28fromstorageengine大概是错误提示,当时也没在意。心想反正提示错了就重启物理服务器吧。这是物理服务器!!!然后我就执行了这个命令(为什么不直接重启MySQL服务?想了想也不知道为什么。而且如果我当时注意这个错误,是磁盘空间问题导致的,可能不会有'以后不会有那么多惊心动魄的事情了。已经!)reboot//重启物理服务器执行后,所有服务正常关闭,只有Mysql数据库服务。关闭MySQL………………………………………………。引号已经5排了,实在等不及了。断电!!!(MySQL没有安全关闭,直接断电会有问题!!!)。3.恢复过程稍等,物理服务器启动。所有的应用服务都正常启动,只有mysql数据库启动的时候。theserverquitwithoutupdatingpidfile(/var/lib/mysql/localhost.localdomain.pid)等到所有服务都加载完毕,再次手动启动MySQL数据库:servicemysqlstart还是报和之前一样的错误,这时候心里就紧张了。google了一下这个错误,网上提供了几种解决方法:1、mysql权限问题chown-Rmysql:mysql/var/lib/mysql/*chmod-R660/var/lib/mysql/*2。mysql服务开启ps-ef|grepmysqld//查看是否有mysqld进程kill-9进程号//强行杀掉进程3.残留数据影响Mysql服务启动删除数据库目录(我的数据库目录是rpm安装默认目录:/var/lib/mysql)mysql-bin.index文件下4.mysql配置文件(默认:/etc/my.cnf)配置文件中没有配置数据库目录。这个问题一般在MySQL刚安装的时候出现5.skip-Federated字段问题注释掉MySQL配置文件中的skip-federated字段6.Selinux问题CentOS6.8及以上会默认开启selinux服务,增强版的军用级防火墙。为了检查问题,可以直接关闭/usr/sbin/setenforce0。以上方案都用过,都没有解决问题。如果该服务仍处于开启状态,则会报错。这时我的心开始变冷了。回头看之前的备份,xxxx_20171208.sql。快2018年6月了,我上一次备份是2017年12月,半年前!半年没备份!(隐约感觉前段时间有备份,备份的服务器硬盘好像已经被我清理干净了)。进入数据库目录后,看到除了上面提到的mysql-bin.index文件外,还有几个文件:mysql-bin.~rec~、ib_logfile1、ib_logfile0、ibdata1。我想了想这些是不是也有一些尝试删除所有剩余的文件。尝试将这些文件转移到其他目录(使用mv命令)来模拟删除效果,也相当于备份。servicemysqlstart居然正常启动了MySQL数据库服务!心中的喜悦涌上来,赶紧用Navicat连接看,能正常连接,看到数据库了。打开数据库后,所有的表都没有了!这时,我的心又酸了。一转眼就11点30分了,时间过得真快,同事叫我一起吃饭,此时我根本没有心情吃饭。恢复表结构就是将刚才删除的文件恢复到原来的目录。既然恢复MySQL进程无望,那就想办法恢复数据吧。进入数据库目录(/var/lib/mysql),发现我的数据库名是以目录的形式存放的。进入目录后发现里面全是扩展名为:xxxxtable.frm的文件。这些不都是我的数据库表吗?它是否将所有数据存储在其中?是否可以通过获取这些文件直接恢复数据?google了一下,果然有这方面的文章,大致说:“frm可以恢复表结构,InnoDB数据库引擎和MyISAM数据库引擎的恢复方法不同。”1、InnoDB数据库引擎在一个正常的MySQL数据库服务器(new_server)下创建一个数据库(new_db),数据库名称与异常服务器(old_server)数据库(old_db)的名称一致。使用与old_db相同的表名(t_user)在new_db数据库中创建一个表。关闭new_server服务器的MySQL数据库服务。将old_server服务器下的old_db数据库目录下的t_user.frm文件复制到new_server服务器下的new_db数据库目录下,替换t_user.frm文件。启动new_server服务器的MySQL数据库服务。使用连接工具连接new_server,可以看到new_db下的表和表结构。2、MyISAM数据库引擎其他与InnoDB数据库引擎基本相同,只是在new_server服务器下的new_db数据库目录下创建了两个空文件:t_user.MYD和t_user.MYI。我使用的数据库是InnoDB引擎。无奈只能用上面两种方法,但是我没有恢复任何表结构,也没有数据。可能是我的操作有问题。这时看到目录下有一个文件:ibdata1google了一下,可以配合xxx.frm使用,再次关闭new_server服务器的mysql数据库服务。直接将old_server服务器下的old_db数据库目录下的ibdata1文件复制到new_server服务器下的new_db数据库目录下,替换ibdata1文件。servicemysqlstart的新服务器也有这样的错误,错误的主要原因可能是ibdata1文件损坏导致的。今天北京的天气已经达到了摄氏35度,此时我的心却凉了一半。虽然没有按时备份数据、服务器异常宕机导致数据丢失的责任比直接删除数据库要轻一点,但还是有办法向公司交代的,你真的需要开始准备“辞职申请”吗?微信打开binlog日志我:你们公司用的是什么数据库,是不是MySQL朋友LZ:是我:公司的MySQL坏了,启动不了;数据未备份;有什么好的方法可以取回数据吗?朋友LZ:你之前数据的binlog还有吗?通过这个,你应该可以恢复我:我有一个朋友LZ:我没做过数据恢复,都是DBA做的,我觉得应该可以;大家可以上网查一下有没有解决办法,我这就直播了。我:嗯,我想说:“请问你的朋友LZ你们的DBA有没有遇到过这样的情况,给个解决办法”;结果还是没好意思说。但是binlog这个名字让我想起了数据库目录(/var/lib/mysql)下的几个比较大的文件。这几十个文件就是binlog日志文件。每个服务器的数量应该不同。只有在每次重启MySQL服务或刷新日志(MySQL命令:showmasterlogs)时才会添加此文件。我看了看我最近的文件。2018年1月16日、2018年3月18日、2018年4月18日、2018年5月28日均有新文件生成,说明MySQL服务器Dates已经关闭和开启。Binlog使用:binlog文件介绍(摘自网络)MySQL的二进制日志可以说是MySQL最重要的日志。它以事件的形式记录了所有的DDL和DML(数据查询语句除外)语句,也包括执行的语句。消耗的时间,MySQL的二进制日志是事务安全的。binlog的作用(摘自网上)MySQLReplication在Master端开启binlog,Master将自己的二进制日志传递给slave,以达到主从数据一致性的目的。数据恢复,使用mysqlbinlog工具恢复数据。在使用binlog恢复数据之前,需要判断MySQL是否开启了binlog日志:showvariableslike'log_%';状态OFF表示未启用,状态ON表示启用。binlog日志可以通过MySQL配置文件(默认路径:/etc/my.cnf)开启或关闭。vi/etc/my.cnf加#可以关闭,去掉可以打开。修改后需要重启MySQL服务(servicemysqlrestart)才能生效。恢复数据(binlog日志方式)先测试mysqlbinlog工具,看到上面这么多mysql-bin文件,很明显centos6.5下rpm方式安装的MySQL默认打开了binlog日志。这时候就需要用到MySQL的mysqlbinlog工具了。要使用它,我们首先需要确保已经安装了MySQL服务,然后我们需要找到它的位置。find/-namemysql2表示MySQL可执行文件的目录3表示MySQL数据库的目录,那么我们先简单的使用一下:cd/var/lib/mysqlmysqlbinlogmysql-bin.000001>mysql-bin.000001.sql显然我使用mysqlbinlog时,直接执行mysqlbinlog命令,不加任何路径。因为默认的centos系统会将/usr/bin目录配置成环境标量,如果我们使用rpm方式安装的MySQL,默认会安装在/usr/bin目录下。/usr/bin目录下的文件在任意路径下都可以直接使用。执行完上面的语句,你会发现在当前目录下生成了一个mysql-bin.000001.sql文件,打开文件可以看到很多sql语句。对于我现在的情况,不需要处理所有的binlog。上面说了,我最后一次备份是在2017年12月8日(xxxx_20171208.sql),所以只需要从mysql-bin启动即可。000009这个binlog文件可以启动。首先,我在另一台服务器上重建了一个MySQL服务,将mysql-bin.000009之后的几个binlog复制到这台新服务器上。(如果服务器出现问题,建议不要对服务器进行任何操作,换一台新的电脑或服务进行处理,以保护数据的完整性!)使用备份文件来恢复数据并新建同名MySQL。数据库。mysql-u数据库用户名-p数据库密码数据库名--default-character-set=utf8mysql-bin.000009.sql此时打开包含大量SQL语句的mysql-bin.000009.sql,发现此时有很多SQL语句。用参数来控制好像不行。好在mysqlbinlog工具为我们提供了另外两个参数,start-position和end-position,修改命令:mysqlbinlog--start-position="123456"mysql-bin.000009|mysql-uroot-proot果然一切很正常,执行这条命令需要很长时间,它会执行这段时间你所做的所有增删改查。这里可能还有另一个问题。我的MySQL服务器中有一个数据库。MySQLbinlog文件记录了所有数据库的增删改查记录。如何只针对某个数据库进行操作?这时候我们就需要用到mysqlbinlog这个数据库参数。mysqlbinlog--database=xxxx--start-position="123456"mysql-bin.000009|mysql-uroot-proot半年的数据由binlog文件一个一个处理,从下午6点开始。至中午12:00完成所有文件的恢复后,数据量不是很大,服务器的性能也不是太高。中间出了点问题,不过都是服务器中断造成的。最后,所有数据都恢复了,真是恐怖的一天!这是近7年工作以来发生的最大事故。去年,我给自己定下目标,今年要写出12篇高质量的文章回馈网络。已经快半年了,我还没有写一篇。没想到第一篇文章就是基于此。以某种方式写的。不知道这篇文章质量好不好,希望能帮到更多的人。总结遇到问题不要盲目,保持清醒的头脑,找出问题所在,整理思路,才能更有效地解决问题。对于数据,不要怕麻烦,注意备份。备注我的服务器和各个软件的版本操作系统:**centos6.5MySQL:**5.5.49MySQL安装方式:**rpm

最新推荐
猜你喜欢