InnoDB数据字典操作进行故障排除
InnoDB数据字典操作进行故障排除
- 事情是这样的,因为昨天晚上停电,导致服务器全部关机,早上一到公司就把所有服务启动,当我启动爬虫任务的时候,发现采集提示数据库入库失败,mysql
提示连接失败。我一看这提示应该是mysql服务没启动,我赶忙进入宝塔看看MySQL什么情况,果然是关闭状态,马上重启却重启失败,我看了看错误日志,好像是缺少了启动需要文件,我突然记起前天我手动改了配置文件数据存储位置,而没有使用宝塔提供的数据迁移功能
-
可能手动修改会造成问题,但当时没有问题,我想切换回原来目录应该就可以启动了,说干就干,使用迁移功能切换回原来储存目录,果然能行,服务启动了。
但是第二个问题来,我切换回来后启动采集服务,mysql提示采集数据库表不存在,我马上打开数据库发现所有采集数据表都打不开提示表不存在,查看mysql错误日志提示:Cannot
open table bk_esf_xq/bk_esf_copy from the internal data dictionary
of InnoDB though the .frm file for the table exists. See
http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html
for how you can resolve the problem. -
它说无法从InnoDB的内部数据字典中打开表bk_esf_xq/bk_esf_copy,尽管表存在.frm文件,
.frm 是mysql数据表结构文件.
如果你没有数表结构备份可以使用dbsake提取.frm文件表结构,这是偶然发现的一个工具,文档中它这样介绍自己:dbsake - a (s)wiss-(a)rmy-(k)nif(e) for MySQL
作者一定是一个对 mysql 很有心得的人,工具从下载,安装到使用,简单,利落。
$ curl -s get.dbsake.net > dbsake
$ chmod u+x dbsake
$ ./dbsake frmdump [frm-file-path]
- MySQL提供了解决问题的连接http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html好评,查看官网文档发现问题解决办法,需要创建一个新库,用ibd文件数据导入新表 .idb 是mysql数据备份文件.
官网案例:在新的MySQL实例上,在同名数据库中重新创建表。
mysql> CREATE DATABASE sakila;
mysql> USE sakila;
mysql> CREATE TABLE actor (
actor_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
first_name VARCHAR(45) NOT NULL,
last_name VARCHAR(45) NOT NULL,
last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (actor_id),
KEY idx_actor_last_name (last_name)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
丢弃新创建的表的表空间。
mysql> ALTER TABLE sakila.actor DISCARD TABLESPACE;
将孤立.ibd文件从备份目录复制到新的数据库目录。
shell> cp /backup_directory/actor.ibd path/to/mysql-5.6/data/sakila/
确保.ibd文件具有必要的文件权限。
导入孤立.ibd文件。发出警告,指示InnoDB尝试在不进行模式验证的情况下导入文件。
mysql> ALTER TABLE sakila.actor IMPORT TABLESPACE; SHOW WARNINGS;
Query OK, 0 rows affected, 1 warning (0.15 sec)
Warning | 1810 | InnoDB: IO Read error: (2, No such file or directory)
Error opening './sakila/actor.cfg', will attempt to import
without schema verification
查询表以确认.ibd 文件已成功还原。
mysql> SELECT COUNT(*) FROM sakila.actor;
+----------+
| count(*) |
+----------+
| 200 |
+----------+
5.自此就可以恢复所有表结构与表数据,又开心的爬取数据入库了