MySQL数据库[ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous tablespace XXX

问题背景

昨天老师告诉我,客户的网站打开不了,让我帮忙解决下,我上服务器看了下负载,发现数据库的服务器cpu都百分100%,大多数是mysqld 这个进程。于是,我打算把数据库服务停掉重新启动,发现竟然停止不了,也启动不了,启动就报错。错误信息如下:

 2018-04-12 12:00:11 15563 [ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous tablespace reg/datadict uses space ID: 5 a
t filepath: ./reg/datadict.ibd. Cannot open tablespace mysql/slave_worker_info which uses space ID: 5 at filepath: ./mysql/slave_worker_info.ibd。。
InnoDB: Error: could not open single-table tablespace file ./mysql/slpwd
InnoDB: We do not continue the crash recovery, because the table may become
InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.
InnoDB: To fix the problem and start mysqld:
InnoDB: 1) If there is a permission problem in the file and mysqld cannot
InnoDB: open the file, you should modify the permissions.
InnoDB: 2) If the table is not needed, or you can restore it from a backup,
InnoDB: then you can remove the .ibd file, and InnoDB will do a normal
InnoDB: crash recovery and ignore that table.
InnoDB: 3) If the file system or the disk is broken, and you cannot remove
InnoDB: the .ibd file, you can set innodb_force_recovery > 0 in my.cnf
InnoDB: and force InnoDB to continue crash recovery here.
180412 12:00:11 mysqld_safe mysqld from pid file /tmp/mysqld.pid ended

解决办法

看报错信息,说是数据库损坏了,并且也给我了错误修复的办法
这里写图片描述
于是我按照第三种方案来,设置innodb_force_recovery的值,我先设置成1,貌似不太起作用。遂上网查了下,看到有人说设置成4,于是我就抱着试试的态度,把innodb_force_recovery设置成4,结果神奇的一幕出现了,数据库启动了,真TM带尽。

后续问题

数据库虽然启动了,但是应用登录不上去,登录报错,报Failed to read auto-increment value from storage engine,我以为是数据库自增主键超了,看错误信息,是登录的时候插入日志出现问题,于是我就去看数据库看日志表的自增主键,发现才2000多,不可能超呀,于是我打算先把自增去掉,再设置自增步伐为1,但是我一操作完毕,就发现保存不了,就报

MySQL:Error : Tablespace for table '`reg`.`#sql-279b_1`' exists. Please DISCARD the tablespace before IMPORT

一脸懵逼态,于是又去搜索这个错误的答案,发现没有一个解决能解决问题,折腾了很久,一度想删库跑路。后来我想是不是所有的表都不能写操作,只能读,我就去实验了下,发现我的猜想是对的。这就奇怪了,我啥也没有做呀,凭啥就只可读不可写,想不通。于是我就出去接杯水,毕竟坐太久了。我冷静思考了下,发现整个从数据库坏死到数据库重新启动,再到数据库只能读不能写,我只动了innodb_force_recovery 这个值,我是我就去搜索innodb_force_recovery的用法,结果真TM发现问题了。

innodb_force_recovery可以设置为1-6,大的数字包含前面所有数字的影响。当设置参数值大于0后,可以对表进行select,create,drop操作,但insert,update或者delete这类操作是不允许的

innodb_force_recovery 各个数字的含义

级别 含义
1 (SRV_FORCE_IGNORE_CORRUPT)忽略检查到的corrupt页
2 (SRV_FORCE_NO_BACKGROUND)阻止主线程的运行,如主线 程需要执行full purge操作,会导致crash
3 (SRV_FORCE_NO_TRX_UNDO)不执行事务回滚操作。
4 (SRV_FORCE_NO_IBUF_MERGE)不执行插入缓冲的合并操作。
5 (SRV_FORCE_NO_UNDO_LOG_SCAN)不查看重做日志,InnoDB存储引擎会将未提交的事务视为已提交
6 (SRV_FORCE_NO_LOG_REDO)不执行前滚的操作。

解决办法

既然知道问题的根源,就需要寻找解决办法,这个我给我一种解决办法。
1. 备份数据

mysqldump -uroot -p123 test > test.sql

一定要确保数据备份成功,因为下面的操作会删除数据库的数据,没有备份成功,到时候就准备跑路吧!!!
2.删除数据文件
为了保险起见,先备份mysql 数据目录下的ib_logfile0ib_logfile1ibdata1 这三个文件(这三个文件存储着数据库的数据,可以进行后续的数据修复),然后将这三个文件删除。
3.配置my.cnf
将my.cnf中innodb_force_recovery =4(或者其他大于0的数字) 这行配置删除或者配置为innodb_force_recovery =0,重启MySQL 数据库
4.恢复数据

mysql -uroot -p123 test < test.sql

总结

当我们看到网上的答案时,一定要先弄清楚这个参数的含义时什么,用法是怎么样的,如果只是一味的复制粘贴,有可能会引发后续不可预知的错误。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011242657/article/details/79948832
个人分类: 数据库
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭