收到很久没联系的一个客户留言,我预感应该是有什么事情发生了,问他啥事:跟我说有人rm -rf他们某表的数据文件了,也没有备份,尝试修复了一番,现在数据库起来了,但是一查那张表就卡住了。
我一听这个事情挺有意思的,于是就有了接下来的一番操作。
07:23:01 UTC - mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
Attempting to collect some information that could help diagnose the problem.
As this is a crash and something is definitely wrong, the information
collection process might fail.
key_buffer_size=16777216
read_buffer_size=8388608
max_used_connections=0
max_threads=3000
thread_count=0
connection_count=0
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 30776532 K bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
Thread pointer: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0 thread_stack 0x40000
/usr/local/mysql/bin/mysqld(my_print_stacktrace+0x35)[0xf4fbe5]
/usr/local/mysql/bin/mysqld(handle_fatal_signal+0x4a4)[0x7d1f54]
/lib64/libpthread.so.0(+0xf630)[0x2b7f2a490630]
/lib64/libc.so.6(gsignal+0x37)[0x2b7f2b943387]
/lib64/libc.so.6(abort+0x148)[0x2b7f2b944a78]
/usr/local/mysql/bin/mysqld(_Z18ut_print_timestampP8_IO_FILE+0x0)[0x7c131e]
/usr/local/mysql/bin/mysqld(_ZN2ib5fatalD1Ev+0xb3)[0x11ae4c3]
/usr/local/mysql/bin/mysqld[0x124f009]
/usr/local/mysql/bin/mysqld[0x124fae8]
/usr/local/mysql/bin/mysqld(_Z6fil_ioRK9IORequestbRK9page_id_tRK11page_size_tmmPvS8_+0x29e)[0x125528e]
/usr/local/mysql/bin/mysqld[0x120c326]
表结构是研发提供的,.ibd文件是在数据目录当中拿到的,但是确没有.frm文件。
测试过程
1.执行rm -rf k1.frm k1.ibd
2.重启数据库
3.进入mysql,执行create table 创建了表结构
此时实例中提示报错,提示k1表已存在,同时数据目录出现了k1.ibd文件
这也就可以推测,他最后在数据目录里面拿到了.ibd 确没有出现.frm文件
进一步测试
1.将此时的k1.ibd文件备份k1.ibd.bak
2.mysql实例中卸载k1表空间,alter table k1 discard tablespace;
3.删除k1表
4.重新创建k1表,生成了k1.frm k1.ibd
5.卸载此时的k1.ibd 并重新加载之前k1.ibd.bak (重命名为k1.ibd)
6.此时就提示了lost connections,并且日志中出现了他给我的报错
整个事情的过程,就复盘出来了。了解了此时的ibd文件,并不是最开始的,也挂在不上去,就只能解析ibd文件试试。
其实最开始,如果没有重启,mysql实例登录上去,也是可以获得结构跟数据的,会省很多事情。
工具
percona-data-recovery-tool-for-innodb-0.5,但是这个工具太久远了.2011年。我尝试进行了安装,提示了报错,果断放弃。因为提示的报错,应该是内核什么过高,这种问题不要太纠结了,就是不适合当下的环境。
TwinDB
InnoDB数据恢复的工具——TwinDB介绍
简单的过了一眼介绍,跟percona-data-recovery-tool-for-innodb-0.5的恢复过程类型,决定上手试试。
make时,需要yum gcc flex bison 顺利完成。
并跟着文档进行.ibd数据恢复。
重点提示
-t 是跟上表结构,而这个表结构,需要是该工具解析出来的
# ./sys_parser -u root -p dingjia -d data_recovered world/city 生成的内容,写入city.sql
# ./c_parser -6f pages-city.ibd/FIL_PAGE_INDEX/0000000000000041.page -t city.sql \ > > dumps/default/city \ > 2>dumps/default/city.sql 最后顺利完成数据修复。
https://github.com/twindb/undrop-for-innodb