使用undrop-for-innodb恢复MySQL数据

深度链接 / 2023-12-06 21:47:55 / 97

一不小心鬼使神差地删除了数据库中的一个表,花了几个小时获取的数据不想就这么算了。由于没有数据备份,所以得尝试其它方式恢复数据。不扯了,下面开始数据恢复之旅。

1、前言

undrop-for-innodb 是针对 innodb 的一套数据恢复工具,可以从文件级别恢复诸如:DROP/TRUNCATE table, 删除表中某些记录,innodb 文件被删除,文件系统损坏,磁盘 corruption 等几种情况。本文简单介绍下使用方法和原理浅析。

2、系统环境

[root@wrx ~]# uname -sir
Linux 2.6.32-696.el6.x86_64 x86_64
You have new mail in /var/spool/mail/root
[root@wrx ~]# mysql --version
mysql  Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1
[root@wrx ~]#

3、表"xxxx_ns_by_jhb_yp"数据恢复

#下载undrop-for-innodb
[root@wrx ~]# git clone https://github.com/twindb/undrop-for-innodb.git 
[root@wrx ~]# make

#执行脚本
[root@wrx ~]# ./recover_dictionary.sh

#执行完上面脚本会创建一个test的数据库,数据库内含有数据恢复需要使用到的数据
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

#查找xxxx_ns_by_jhb_tp的table_id
mysql> select * from SYS_TEBLES where name like "%xxxx/xxxx_ns_by_jhb_tp%";
ERROR 1146 (42S02): Table 'test.SYS_TEBLES' doesn't exist
mysql> select * from SYS_TABLES where name like "%xxxx/xxxx_ns_by_jhb_tp%";
+----------------------------+-----+--------+------+--------+---------+--------------+-------+
| NAME                       | ID  | N_COLS | TYPE | MIX_ID | MIX_LEN | CLUSTER_NAME | SPACE |
+----------------------------+-----+--------+------+--------+---------+--------------+-------+
| xxxx/xxxx_ns_by_jhb_tp | 910 |      8 |    1 |      0 |       0 |              |     0 |
+----------------------------+-----+--------+------+--------+---------+--------------+-------+
1 row in set (0.05 sec)

#根据表ID查找INDEX ID
mysql> select * from SYS_INDEXES where table_id = 910;
+----------+------+-----------+----------+------+-------+------------+
| TABLE_ID | ID   | NAME      | N_FIELDS | TYPE | SPACE | PAGE_NO    |
+----------+------+-----------+----------+------+-------+------------+
|      910 | 1973 | PRIMARY   |        1 |    3 |     0 | 4294967295 |
|      910 | 1974 | ns        |        1 |    0 |     0 | 4294967295 |
|      910 | 1975 | ns_prefix |        1 |    0 |     0 | 4294967295 |
|      910 | 1976 | zd        |        1 |    0 |     0 | 4294967295 |
+----------+------+-----------+----------+------+-------+------------+
4 rows in set (0.00 sec)

mysql> 

#查看pages-ibdata1/FIL_PAGE_INDEX/目录下是否存在0000000000001973.page

#-t参数后跟的是xxxx_ns_by_jhb_tp表创建命令
[root@wrx ~]# ./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000001973.page -t xxxx/xxxx_ns_by_jhb_tp_create.sql > xxxx/xxxx_ns_by_jhb_tp 2> xxxx/xxxx_ns_by_jhb_tp.sql

#将数据导入数据库,注意修改xxxx/xxxx_ns_by_jhb_tp.sql中的load路径

#创建数据恢复数据库
mysql> create database recover;
Query OK, 1 row affected (0.01 sec)

mysql> use recover;
Database changed

#创建数据恢复表
mysql> CREATE TABLE `xxxx_ns_by_jhb` (
    -> `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    -> `ns_prefix` VARCHAR(16) NOT NULL,
    -> `ns` VARCHAR(16) NOT NULL,
    -> `region` VARCHAR(255) NOT NULL,
    -> `city` VARCHAR(255) NOT NULL,
    -> `zd` VARCHAR(8) NOT NULL,
    -> `operator` VARCHAR(128) NULL DEFAULT NULL,
    -> `mp_type` VARCHAR(128) NULL DEFAULT NULL,
    -> PRIMARY KEY (`id`),
    -> INDEX `ns` (`ns`),
    -> INDEX `ns_prefix` (`ns_prefix`),
    -> INDEX `zd` (`zd`)
    -> )
    -> COLLATE='utf8_general_ci'
    -> ENGINE=InnoDB
    -> ;
 
#导入数据
mysql> source /usr/local/lib/undrop-for-innodb-master/xxxx/xxxx_ns_by_jhb_tp.sql
Query OK, 0 rows affected (0.00 sec)

Query OK, 381437 rows affected (12.92 sec)
Records: 381437  Deleted: 0  Skipped: 0  Warnings: 0

mysql> select count(distinct `ns`) from xxxx_ns_by_jhb;
+----------------------+
| count(distinct `ns`) |
+----------------------+
|               360111 |
+----------------------+
1 row in set (0.86 sec)

#至此数据恢复完成