月度归档:2016年05月

误删ibdata1,通过ibd找回丢失的数据。

事件起因:昨晚凌晨对落伍数据库主从服务器进行常规维护的时候,因为鼠标不好用,误删了mysql下的ibdata1。因为落伍主题表thread用的是innodb数据存储,瞬间丢数据了。
面临两个选择连:
1.恢复定时备份的数据,但是因为数据不是实时的,会丢失部分帖子
2.从ibd里面找回数据。

考虑了一下还是执行第二个选项,时值半夜,有足够时间来。
原理很简单,INNODB的数据存储在ibd文件里面,只要建立空白的新表,把这空白的ibd文件跟表的关联去掉,然后复制有数据的ibd文件回来,在建立关联即可。
马上动手了:
先建立一个空白数据库来操作,导入表结构,落伍的主题表做了存档和partition的,得分两步了。
mysql aaa < pre_forum_thread.sql mysql aaa < pre_forum_thread_1.sql

好,把ibd文件的关联去掉吧
mysql> use aaa
Database changed
mysql> alter table pre_forum_thread discard tablespace;
ERROR 1031 (HY000): Table storage engine for 'pre_forum_thread' doesn't have this option
mysql>

在空白的表上都能出错,Google一下,发现没有相关解析。这下傻眼了。考虑了很久,我估计是因为分区的问题,分表之后会有多个ibd文件,这个discard tablespace的操作可能无法识别全部ibd文件。
/var/lib/mysql/im286/pre_forum_thread#P#p3.ibd
/var/lib/mysql/im286/pre_forum_thread#P#p4.ibd
/var/lib/mysql/im286/pre_forum_thread#P#p5.ibd
/var/lib/mysql/im286/pre_forum_thread#P#p6.ibd
/var/lib/mysql/im286/pre_forum_thread#P#p7.ibd
/var/lib/mysql/im286/pre_forum_thread#P#p8.ibd

那就试试没分区的原始thread表看看。果然在没分区的时候,成功discard tablespace了
mysql> use aaa
Database changed
mysql> alter table pre_forum_thread discard tablespace;
Query OK, 0 rows affected (0.10 sec)

既然不分区的能用,那就简单了。把分区ibd文件当做没分区的来import即可,反正表结构是一致的,import之后导出表里面的数据。
mysql> use aaa
Database changed
mysql> alter table pre_forum_thread discard tablespace;
Query OK, 0 rows affected (0.10 sec)

mysql> quit

cp -p /var/lib/mysql/im286/bak/pre_forum_thread#P#p3.ibd /var/lib/mysql/im286/aaa/pre_forum_thread.ibd

mysql> use aaa
Database changed
mysql> alter table pre_forum_thread import tablespace;
Query OK, 0 rows affected, 1 warning (11.57 sec)


没问题了,导出数据:
mysqldump -d aaa pre_forum_thread >> thread.sql

所有分区的ibd文件都重复一次上面的操作,全部主题数据都导出来了,回到论坛的数据库,创建空白的thread表,然后导入数据即可。大功告成,睡觉。