背景:
很多时候因为 MySQL 数据库不能启动而造成数据无法访问,但应用的数据通常没有丢失,只是系统表空间等其它文件损坏了,或者遇到 MySQL 的 bug。这个时候如果没有备份,很多人就以为数据丢失了,但实际上大部分时候数据还是有救的。对于 MyISAM 引擎的表空间,直接把对应的数据文件拷贝到一个新的数据库就行了,数据就可以恢复了。对于 InnoDB 引擎的数据库表空间可以采用传输表空间的方式把数据救回来。
1、安装软件,回已经丢失的表结构
rpm -Uvh https://cdn.mysql.com/archives/mysql-utilities/mysql-utilities-1.6.5-1.el7.noarch.rpm
假设db1为原数据库目录且里面有多表,那么我能用命令mysqlfrm就能找回库下.frm 文件的表结构
[root@slave1 ~]# mysqlfrm --diagnostic db1 >createtb.sql
[root@slave1 ~]# grep "CREATE TABLE" createtb.sql |wc -l
10 #可以看到一共生成了 10 个建表语句
2、新建数据库导入建表语句
Query OK, 0 rows affected (0.03 sec)
...
3、恢复阶段1:先将新建的表没有包括数据的 .ibd 表空间文件抛弃
语句:alter table table_name discard tablespace;
mysql -S /data/socket/mysql16100.sock -e "show tables from db1"|grep -v Tables_in_db1 \
|while read a ;do mysql -S /data/socket/mysql16100.sock -e " alter table db1.$a discard tablespace";done
4、恢复阶段2:将db1为原数据库目录下的*.idb 拷贝到新的数据库目录下,然后添加对应mysql.mysql 权限,再把这些数据文件 import 到数据库中。
语句:alter table table_name import tablespace;
mysql -S /data/socket/mysql16100.sock -e "show tables from db1"|grep -v Tables_in_db1 \
|while read a ;do mysql -S /data/socket/mysql16100.sock -e " alter table db1.$a import tablespace";done
5、使用 mysqlcheck 对数据库db1 下的所有表进行检查
[root@localhost db1]# mysqlcheck -S /data/socket/mysql16100.sock -c db1
db1.t1 OK
...