标题:MySQL InnoDB数据恢复,丢失ibdata1时怎么安全恢复
废话在前:
恭喜你,当你看到这篇文章的时候,说明有可能 你心里已经有一万匹🐎在奔腾了。千万不要乱删除ibdata1,有些博客无脑抓取、复制其他人的博客乱发文章,比如:
在磁盘满了的情况下,不能删除ibdata1文件,或者在删除的时候该备份(但是磁盘都满了,一般都备份不到了,本人血泪教训)。
原因:由于innoDB将表数据字典存储在ibdata1中,当ibdata1改变时,ID就无法对应上,所以就会找不到表。
再来说怎么解决
如果你的mysql在删除ibdata1后还没有启动的时候,这个时候还可以靠进程试着恢复:
# 误删数据文件和重做日志文件
[root@dba ~]# cd /mysqldata/data/
[root@dba data]# ll ib*
-rw-r----- 1 mysql mysql 809 Nov 19 03:22 ib_buffer_pool
-rw-r----- 1 mysql mysql 79691776 Feb 23 07:17 ibdata1
-rw-r----- 1 mysql mysql 50331648 Feb 23 07:18 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 Feb 23 07:18 ib_logfile1
-rw-r----- 1 mysql mysql 12582912 Feb 23 07:06 ibtmp1
[root@dba data]# rm -f ib*
[root@dba data]# ll ib*
ls: cannot access ib*: No such file or directory
# 查找MySQL进程pid
[root@dba data]# netstat -ntlp | grep mysqld
tcp6 0 0 :::3306 :::* LISTEN 7424/mysqld
# 确认进程具柄还没释放
[root@dba data]# ll /proc/7424/fd | egrep 'ib_|ibdata'
lrwx------ 1 root root 64 Feb 23 07:33 10 -> /mysqldata/data/ibdata1 (deleted)
lrwx------ 1 root root 64 Feb 23 07:33 4 -> /mysqldata/data/ib_logfile0 (deleted)
lrwx------ 1 root root 64 Feb 23 07:33 9 -> /mysqldata/data/ib_logfile1 (deleted)
# 前端关闭业务或甚至只读模式
flush tables with read lock;
# 将脏页尽快刷入磁盘
set global innodb_max_dirty_pages_pct = 0;
# 查看binlog日志写入情况,确保File和Position值没变化
show master status;
# 查看InnoDB状态信息确保脏页已刷入磁盘
show engine innodb status\G;
# 将未释放的具柄号复制回原目录文件
[root@dba data]# cp /proc/7424/fd/10 /mysqldata/data/ibdata1
[root@dba data]# cp /proc/7424/fd/4 /mysqldata/data/ib_logfile0
[root@dba data]# cp /proc/7424/fd/9 /mysqldata/data/ib_logfile1
# 修改用户属性
[root@dba data]# chown mysql.mysql ib*
[root@dba data]# ll /mysqldata/data/ib*
-rw-r----- 1 mysql mysql 79691776 Feb 23 07:41 /mysqldata/data/ibdata1
-rw-r----- 1 mysql mysql 50331648 Feb 23 07:41 /mysqldata/data/ib_logfile0
-rw-r----- 1 mysql mysql 50331648 Feb 23 07:41 /mysqldata/data/ib_logfile1
# 解锁,看是否需要重启MySQL服务
mysql> unlock tables;
如果你已经启动了mysql,那么再次恭喜你 又加大了难度,ibdata1在mysql启动和关闭的时候写入数据,如果在删除了ibdata1文件下,启动了mysql,那么ibdata1文件会自动创建。那么就需要想别的办法来恢复数据:
此时你所有的数据都还是存在的,只是缺少了一个ibdata1文件,而innoDB将表数据字典存储在ibdata1中,所以你需要重新建立表字段、结构等(注意:所有格式、编码都需要和以前一致)
CREATE TABLE table_name ...; # 这里的表格式 必须和之前的严格一致,否则会造成数据乱码
ALTER TABLE table_name DISCARD TABLESPACE; # 去除表空间( 会删除 table_name.idb )
# 复制原数据 table_name.idb 到数据目录下 ( 这一步建议先停止MySQL服务器,复制完成再开启 )
ALTER TABLE table_name IMPORT TABLESPACE; # 导入表空间
# DISCARD TABLESPACE 相当于清空新表数据
# IMPORT TABLESPACE 相当于从文件导入数据
最后还是希望你能完整快速的恢复数据。