mysql恢复测试报告_MySQL Drop Database之后的恢复测试

工具介绍

工具的名字叫做:  undrop-for-innodb

当MySQL 执行 Drop Table或者 Drop Database 的时候,InnoDB并没有删除数据,数据的Page还在磁盘上。

如果innodb_file_per_table被设置成了OFF,则数据库在ibdata1上,如果innodb_file_per_table被设置成了ON,则数据在.ibd文件中,MySQL已经删除了这个文件。

安装恢复软件首先安装软件所需要的包:  make  gcc flex  bison git

[root@centos~]# yum install make  gcc  flex bison git

下载代码

[root@centos~]# git clone https://github.com/twindb/undrop-for-innodb.git

Initializedempty Git repository in /root/undrop-for-innodb/.git/

remote:Counting objects: 221, done.

Receivingobjects: 100% (221/221), 1.10 MiB | 53 KiB/s, done.

remote: Total221 (delta 0), reused 0 (delta 0), pack-reused 221

Resolvingdeltas: 100% (53/53), done.

[root@centos~]# ls

anaconda-ks.cfg    MySQL-5.6.27-1.el6.x86_64.rpm-bundle.tar MySQL-embedded-5.6.27-1.el6.x86_64.rpm MySQL-shared-compat-5.6.27-1.el6.x86_64.rpm

install.log        MySQL-client-5.6.27-1.el6.x86_64.rpm     MySQL-server-5.6.27-1.el6.x86_64.rpm   MySQL-test-5.6.27-1.el6.x86_64.rpm

install.log.syslog  MySQL-devel-5.6.27-1.el6.x86_64.rpm      MySQL-shared-5.6.27-1.el6.x86_64.rpm   undrop-for-innodb

3.编译代码

[root@centos~]# cd undrop-for-innodb/

[root@centosundrop-for-innodb]# ls

check_data.c  dictionary    include         LICENSE   print_data.c recover_dictionary.sh sql_parser.l  stream_parser.c  tables_dict.c

c_parser.c    fetch_data.sh  innochecksum.c  Makefile README.md     sakila                 sql_parser.y  sys_parser.c     test.sh

[root@centosundrop-for-innodb]# make

cc-D_FILE_OFFSET_BITS=64 -Wall -g -O3 -pipe -I./include -c stream_parser.c

cc-D_FILE_OFFSET_BITS=64 -Wall -g -O3 -pipe -I./include  -pthread -lm  stream_parser.o -o stream_parser

flex  sql_parser.l

bison  -o sql_parser.c sql_parser.y

sql_parser.y:conflicts: 6 shift/reduce

cc-D_FILE_OFFSET_BITS=64 -Wall -g -O3 -pipe -I./include -c sql_parser.c

lex.yy.c:3084:警告:‘yyunput’定义后未使用

lex.yy.c:3125:警告:‘input’定义后未使用

cc-D_FILE_OFFSET_BITS=64 -Wall -g -O3 -pipe -I./include -c c_parser.c

./include/ctype-latin1.c:359:警告:‘my_mb_wc_latin1’定义后未使用

./include/ctype-latin1.c:372:警告:‘my_wc_mb_latin1’定义后未使用

cc-D_FILE_OFFSET_BITS=64 -Wall -g -O3 -pipe -I./include -c tables_dict.c

cc-D_FILE_OFFSET_BITS=64 -Wall -g -O3 -pipe -I./include -c print_data.c

cc-D_FILE_OFFSET_BITS=64 -Wall -g -O3 -pipe -I./include -c check_data.c

cc-D_FILE_OFFSET_BITS=64 -Wall -g -O3 -pipe  -I./include  sql_parser.oc_parser.o tables_dict.o print_data.o check_data.o -o c_parser -pthread -lm

cc -D_FILE_OFFSET_BITS=64-Wall -g -O3 -pipe   -I./include -oinnochecksum_changer innochecksum.c

测试恢复数据

测试环境

数据库的版本:MySQL-server-5.6.27

操作系统:Centos6.7 和 Windows 7

测试场景1:Drop Database (innodb_file_per_table=On)

创建数据库和测试表

我们先来看下创建好的数据库,有多少个文件。

[root@centos mysql]#ls

auto.cnf  centos.err centos.pid  ibdata1  ib_logfile0 ib_logfile1  mysql  mysql.sock performance_schema RPM_UPGRADE_HISTORY RPM_UPGRADE_MARKER-LAST  test

确认下我们的数据库的 innodb_file_per_table参数mysql> show variables like '%per_table%';+-----------------------+-------+| Variable_name         | Value |+-----------------------+-------+| innodb_file_per_table | ON   |+-----------------------+-------+1 row in set (0.00 sec)

说明:OFF代表mysql是共享表空间,也就是所有库的数据都存放在一个ibdate1文件中

ON代表,每个表的存储空间都是独立的。

接下来创建爱数据库 test1 并创建测试表 test1

mysql>create database test1;

Query OK, 1row affected (0.00 sec)

mysql> usetest1;

Databasechanged

mysql>create table test1(id int);

Query OK, 0rows affected (0.14 sec)

mysql>insert into test1 values('1');

Query OK, 1row affected (0.54 sec)

mysql>insert into test1 select * from test1;     -----反复运行多次,直到有足够的数据量

Query OK,131072 rows affected (2.28 sec)

Records:131072  Duplicates: 0  Warnings: 0

mysql>commit;

Query OK, 0rows affected (0.00 sec)

我们来看下数据文件多了哪些。

[root@centosmysql]# ls

auto.cnf  centos.err centos.pid  ibdata1  ib_logfile0 ib_logfile1  mysql  mysql.sock performance_schema RPM_UPGRADE_HISTORY RPM_UPGRADE_MARKER-LAST  test  test1

多了一个test1的目录。进入目录看下

[root@centosmysql]# cd test1

[root@centostest1]# ls

db.opt  test1.frm test1.ibd

可以看到 test1.frm 和 test1.ibd 这2个文件。

ibd是MySQL数据文件、索引文件,无法直接读取。frm是表结构文件,可以直接打开。

如果innodb_file_per_table 无论是ON还是OFF,都会有这2个文件,区别只是innodb_file_per_table为ON的时候,数据时放在 .idb中,如果为OFF则放在ibdata1中。

我们来看下数据文件的大小:

[root@centostest1]# du -sh *

4.0K    db.opt

12K     test1.frm

72M     test1.ibd

[root@centosmysql]# du -sh *

4.0K    auto.cnf

4.0K    centos.err

4.0K    centos.pid

76M     ibdata1

49M     ib_logfile0

48M     ib_logfile1

1.7M    mysql

0       mysql.sock

636K    performance_schema

4.0K    RPM_UPGRADE_HISTORY

4.0K    RPM_UPGRADE_MARKER-LAST

4.0K    test

8.0K    test2

发现 test1.ibd和ibdata1 都增长的很厉害,不知道为什么,这个之后再研究。

接下来删除数据库test1

drop databasetest1.

开始恢复数据

注意这里 -f 后面的参数是 裸盘 的地址,如果你不知道可以用 df -h 查看.

-t 是这个磁盘的大小。

[root@centos~]# df -h /var/lib/mysql

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/vg_centos-lv_root

50G  4.1G  43G   9% /

[root@centosundrop-for-innodb]#./stream_parser -f /dev/mapper/vg_centos-lv_root -t 50g

Opening file:/dev/mapper/vg_centos-lv_root

Fileinformation:

ID of devicecontaining file:            5

inodenumber:                         6454

protection:                          60660 (block device)

number of hardlinks:                    1

user ID ofowner:                        0

group ID ofowner:                       6

device ID (ifspecial file):         64768

blocksize forfilesystem I/O:         4096

number ofblocks allocated:              0

time of lastaccess:            1449240755 Fri Dec  4 22:52:35 2015

time of lastmodification:      1449240755 FriDec  4 22:52:35 2015

time of laststatus change:     1449240755 FriDec  4 22:52:35 2015

total size, inbytes:                    0 (0.000exp(+0))

Size to process:               53687091200 (50.000 GiB)

Worker(0):1.03% done. 2015-12-05 00:04:40 ETA(in 00:14:38). Processing speed: 57.700MiB/sec

Worker(0):2.04% done. 2015-12-05 00:06:18 ETA(in 00:16:06). Processing speed: 51.902MiB/sec

Worker(0):3.06% done. 2015-12-05 00:01:27 ETA(in 00:11:08). Processing speed: 74.221MiB/sec

Worker(0):4.07% done. 2015-12-05 00:04:39 ETA(in 00:14:11). Processing speed: 57.672MiB/sec

Worker(0):98.51% done. 2015-12-04 23:54:19 ETA(in 00:00:05). Processing speed: 129.971MiB/sec

Worker(0):99.53% done. 2015-12-04 23:54:15 ETA(in 00:00:00). Processing speed: 520.000MiB/sec

All workersfinished in 263 sec

spacer.gif

这里说明一下:

0000000000000001.page:  恢复出来的 SYS_TABLES 表

0000000000000003.page:  恢复出来的 SYS_INDEXES 表

创建存放恢复出来的文件的目录

[root@centosundrop-for-innodb]#mkdir -p dictionary dumps/default

[root@centosundrop-for-innodb]# ./c_parser -4Df./pages-vg_centos-lv_root/FIL_PAGE_INDEX/0000000000000001.page -t./dictionary/SYS_TABLES.sql  -o./dumps/SYS_TABLES.dmp  -l./dumps/SYS_TABLES.sql

恢复数据,因为我们是恢复删除掉的数据,所以一定要加参数D(注意是大写的D)。

然后查看生成出来的文件:

./dictionary/SYS_TABLES.sql     是创建表 SYS_TABLES的脚本。

./dumps/SYS_TABLES.dmp      是SYS_TABLES表里面的内容

./dumps/SYS_TABLES.sql        是恢复数据到SYS_TABLES的SQL语句。

这里我们查看 ./dumps/SYS_TABLES.dmp,可以看到我们删除掉的数据

spacer.gif

因为我们在test1数据库中只有1个test1表。所以这里只能看到一个 test1。

可以看到 table_id 是 20。

接下来我们看下索引的信息

spacer.gif

可以看到,索引的ID 是22

这里有个重点的地方,我们首先要有表结构的SQL语句。(如果没有的话,可以参考我另外的一篇文章来恢复表的结构)。

创建 test1/test1.sql , 输入如下内容

Create table test1

(

Id int

)

开始恢复数据:

./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000022.page-t test1/test1.sql -o dumps/test1.dmmp -l dumps/test1.sql

启动数据库,创建数据库test1

mysql> create database test1;

Query OK, 1 row affected (0.03 sec)

mysql> use test1;

Database changed

运行 test1/test1.sql 创建表 test1, 然后运行 dumps/test1.sql 恢复数据

mysql> source dumps/test1.sql

Query OK, 0 rows affected (0.00 sec)

Query OK, 45794 rows affected (0.90 sec)

Records: 45794 Deleted: 0  Skipped: 0  Warnings:

检查数据,可以看到数据已经正常恢复了。

测试场景2:Drop Database (innodb_file_per_table=OFF)

创建数据库和测试表

首先确认下 innodb_file_per_table的参数.

mysql> showvariables like 'inno%per%tab%';

+-----------------------+-------+

|Variable_name         | Value |

+-----------------------+-------+

|innodb_file_per_table | ON    |

+-----------------------+-------+

1 row in set(0.00 sec)

创建测试用的数据库表和数据

mysql>create database test6;

Query OK, 1row affected (0.00 sec)

mysql> usetest6

Databasechanged

mysql>create table a(id int);

Query OK, 0rows affected (0.08 sec)

mysql>create table b(id2 int);

Query OK, 0rows affected (0.06 sec)

mysql>insert into a values(1);

Query OK, 1row affected (0.07 sec)

mysql>insert into b values(1);

Query OK, 1row affected (0.04 sec)

mysql>commit;

Query OK, 0rows affected (0.00 sec)

查看下数据表的目录,可以看到只有 frm文件

[root@centostest6]# pwd

/var/lib/mysql/test6

[root@centostest6]# ls

a.frm  b.frm db.opt

反复执行 Insert into aselect * from a; 直到有足够大的数据。

[root@centosmysql]# du -sh ibdata1

76M     ibdata1

Ibdata1增长到了76M

删除数据库 test6

mysql> dropdatabase test6;

Query OK, 2rows affected (0.26 sec)

开始恢复数据

因为数据在ibdata1文件中,所以我们分析ibdata1文件

[root@centosundrop-for-innodb]# ./stream_parser -f /var/lib/mysql/ibdata1

Opening file:/var/lib/mysql/ibdata1

Fileinformation:

ID of devicecontaining file:        64768

inodenumber:                      2621728

protection:                         100660 (regular file)

number of hardlinks:                    1

user ID ofowner:                      498

group ID ofowner:                     497

device ID (ifspecial file):             0

blocksize forfilesystem I/O:         4096

number ofblocks allocated:         155648

time of lastaccess:            1449385451 SunDec  6 15:04:11 2015

time of lastmodification:      1449385922 SunDec  6 15:12:02 2015

time of laststatus change:     1449385922 SunDec  6 15:12:02 2015

total size, inbytes:             79691776 (76.000 MiB)

Size toprocess:                  79691776(76.000 MiB)

All workersfinished in 0 sec

剩下的步骤和之前的一样,首先获取到 我们删除掉的test6的数据库里面的表,从结果里面可以看到是 a 和b 。ID 分别是 24 和 25。

[root@centosundrop-for-innodb]# ./c_parser -4Df./pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page  -t ./dictionary/SYS_TABLES.sql  -o ./dumps/SYS_TABLES.dmp  -l ./dumps/SYS_TABLES.sql

[root@centosundrop-for-innodb]# cat ./dumps/SYS_TABLES.dmp

-- Page id: 8,Format: REDUNDANT, Records list: Invalid, Expected records: (0 10)

000000000F6A    55000008010182  SYS_TABLES      "test6/a"       24     1       1       0      64      ""      0

000000000F64    52000008060182  SYS_TABLES      "test6/b"       25     1       1       0      64      ""      0

获取表中的索引信息

[root@centosundrop-for-innodb]# ./c_parser -4Df./pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page  -t ./dictionary/SYS_INDEXES.sql

-- Page id:11, Format: REDUNDANT, Records list: Invalid, Expected records: (0 12)

000000000F6A    55000008010110  SYS_INDEXES     24     26      "GEN\_CLUST\_INDEX"     0      1       0       4294967295

000000000F64    52000008060110  SYS_INDEXES     25     27      "GEN\_CLUST\_INDEX"     0      1       0       4294967295

-- Page id:11, Found records: 2, Lost records: YES, Leaf page: YES

-- Page id:11, Format: REDUNDANT, Records list: Invalid, Expected records: (0 12)

000000000F6A    55000008010110  SYS_INDEXES     24     26      "GEN\_CLUST\_INDEX"     0      1       0       4294967295

000000000F64    52000008060110  SYS_INDEXES     25     27      "GEN\_CLUST\_INDEX"     0      1       0       4294967295

SETFOREIGN_KEY_CHECKS=0;

LOAD DATALOCAL INFILE '/root/undrop-for-innodb/dumps/default/SYS_INDEXES' REPLACE INTOTABLE `SYS_INDEXES` FIELDS TERMINATED BY '\t' OPTIONALLY ENCLOSED BY '"'LINES STARTING BY 'SYS_INDEXES\t' (`TABLE_ID`, `ID`, `NAME`, `N_FIELDS`,`TYPE`, `SPACE`, `PAGE_NO`);

-- Page id:11, Found records: 2, Lost records: YES, Leaf page: YES

可以看到索引ID分别是 26 和 27

创建建表的文件  test6/a.sql 和 test6/b.sql

开始恢复数据。

./c_parser -6fpages-ibdata1/FIL_PAGE_INDEX/0000000000000027.page -t test6/b.sql -odumps/b.dmmp -l dumps/b.sql

./c_parser -6fpages-ibdata1/FIL_PAGE_INDEX/0000000000000027.page -t test6/b.sql -odumps/b.dmmp -l dumps/b.sql

导入数据到数据库中

mysql>create database test6;

Query OK, 1row affected (0.00 sec)

mysql> usetest6;

Databasechanged

mysql>source test6/a.sql

Query OK, 0rows affected (0.07 sec)

mysql>source test6/b.sql

Query OK, 0rows affected (0.06 sec)

mysql>source dumps/a.sql

Query OK, 0rows affected (0.00 sec)

Query OK,1081922 rows affected (6.18 sec)

Records:1081922  Deleted: 0  Skipped: 0 Warnings: 0

mysql>source dumps/b.sql

Query OK, 0rows affected (0.00 sec)

Query OK, 2rows affected (0.07 sec)

Records:2  Deleted: 0  Skipped: 0 Warnings: 0

数据恢复成功

测试场景3: Drop Database (innodb_file_per_table=ON Windows平台)

我考虑到了另外一种情况,如果是windows平台下删除了数据库,是否有办法通过这个软件来读取呢,我们可以试一下

创建数据库和测试表

查看下innodb_file_per_table的值:

mysql> show variables like 'inno%per%tab%';

+-----------------------+-------+

| Variable_name         |Value |

+-----------------------+-------+

| innodb_file_per_table | ON   |

+-----------------------+-------+

1 row in set (0.00 sec)

创建测试用的数据库 test_recover和表a1。

mysql> use test_recover;

Database changed

mysql> create table a1(a1 int,a2 int);

Query OK, 0 rows affected (0.40 sec)

mysql> insert into a1 values(1,2)

-> ;

Query OK, 1 row affected (0.11 sec)

mysql> insert into a1 values(3,4)

-> ;

Query OK, 1 row affected (0.08 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from a1;

+------+------+

| a1   | a2   |

+------+------+

|    1 |    2 |

|    3 |    4 |

+------+------+

2 rows in set (0.00 sec)

查看下我们的数据在哪个盘:

mysql> show variables like 'datadir';

+---------------+-----------------------------+

| Variable_name | Value                       |

+---------------+-----------------------------+

| datadir       |D:\MyTool\xampp\mysql\data\ |

+---------------+-----------------------------+

1 row in set (0.00 sec)

删除数据库

spacer.gif

开始恢复数据

首先安装 Samba。

yum install samba

因为我默认的administrator帐号没有密码,所以在windows上创建了一个用户 admin密码是 admin.

测试下帐号:

[root@centos~]# smbclient -L 10.0.0.4 -U admin

Enter admin'spassword:

Domain=[ACTION-PC]OS=[Windows 7 Ultimate 7601 Service Pack 1] Server=[Windows 7 Ultimate 6.1]

Sharename       Type     Comment

---------       ----     -------

ADMIN$          Disk      远程管理

C$              Disk      默认共享

D$              Disk      默认共享

E$              Disk      默认共享

F$              Disk      默认共享

IPC$            IPC       远程 IPC

sessionrequest to 10.0.0.4 failed (Called name not present)

sessionrequest to 10 failed (Called name not present)

sessionrequest to *SMBSERVER failed (Called name not present)

NetBIOS overTCP disabled -- no workgroup available

创建 /d 目录,然后 将D盘挂载到本地的 /d 目录下

[root@centos~]# mount -t cifs -o username=admin,password=admin   //10.0.0.4/d$ /d/

[root@centos~]# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/vg_centos-lv_root

50G  4.2G  43G   9% /

tmpfs                 499M     0 499M   0% /dev/shm

/dev/sda1             477M   36M 416M   8% /boot

/dev/mapper/vg_centos-lv_home

47G   52M  45G   1% /home

//10.0.0.4/d$         101G  89G   12G  89% /d

尝试去恢复数据:

[root@centosundrop-for-innodb]#  ./stream_parser -f//10.0.0.4/d$ -t 101g

Opening file://10.0.0.4/d$

Fileinformation:

Errno = 2,Error = No such file or directory

All workersfinished in 0 sec

换个参数:

[root@centosundrop-for-innodb]#  ./stream_parser -f/d/ -t 101g

Opening file:/d

Fileinformation:

ID of devicecontaining file:           28

inodenumber:                 1407374883553285

protection:                          40755 (directory)

number of hardlinks:                    1

user ID ofowner:                        0

group ID ofowner:                       0

device ID (ifspecial file):             0

blocksize forfilesystem I/O:        16384

number ofblocks allocated:             80

time of lastaccess:            1449495079 MonDec  7 21:31:19 2015

time of lastmodification:      1449495079 MonDec  7 21:31:19 2015

time of laststatus change:     1449495079 MonDec  7 21:31:19 2015

total size, inbytes:                40960 (40.000 kiB)

Size toprocess:              108447924224(101.000 GiB)

Worker(0):Failed to read from disk: Is a directory

All workersfinished in 0 sec

最终都失败了。看来没有办法读取windows下的分区来恢复数据,不知道如果把物理磁盘挂载到Linux下会不会有效果。

测试场景4:Drop Database (innodb_file_per_table=OFFWindows平台)

分区是无法读取了,但是文件或许可以,让我们再次测试下。

创建数据库和测试表

查看下innodb_file_per_table的值:

mysql> showvariables like 'inno%per%tab%';

+-----------------------+-------+

|Variable_name         | Value |

+-----------------------+-------+

| innodb_file_per_table| OFF    |

+-----------------------+-------+

1 row in set(0.00 sec)

创建测试用的数据库 test_recover2和表 a2。

mysql>create database test_recover2;

Query OK, 1row affected (0.00 sec)

mysql> use test_recover2;

Databasechanged

mysql>create table a2(a1 int,a2 int);

Query OK, 0rows affected (0.40 sec)

mysql>insert into a2 values(1,2)

-> ;

Query OK, 1row affected (0.06 sec)

mysql>insert into a2 values(3,4)

-> ;

Query OK, 1row affected (0.04 sec)

mysql>insert into a2 values(5,6);

Query OK, 1row affected (0.06 sec)

mysql>commit;

Query OK, 0rows affected (0.00 sec)

mysql>select * from a2;

+------+------+

| a1   | a2  |

+------+------+

|    1 |   2 |

|    3 |   4 |

|    5 |   6 |

+------+------+

3 rows in set(0.00 sec)

查看下我们的数据在哪个盘:

mysql> showvariables like 'datadir';

+---------------+-----------------------------+

|Variable_name | Value                      |

+---------------+-----------------------------+

| datadir       | D:\MyTool\xampp\mysql\data\|

+---------------+-----------------------------+

1 row in set(0.00 sec)

删除数据库

spacer.gif

开始恢复数据

将 D:\MyTool\xampp\mysql\data目录下的 ibdata1 文件上传到Linux服务器的/tmp目录下

开始恢复数据

[root@centosundrop-for-innodb]#  ./stream_parser -f/tmp/ibdata1

Opening file:/tmp/ibdata1

Fileinformation:

ID of devicecontaining file:        64768

inodenumber:                      2753060

protection:                         100644 (regular file)

number of hardlinks:                    1

user ID ofowner:                        0

group ID ofowner:                       0

device ID (ifspecial file):             0

blocksize forfilesystem I/O:         4096

number ofblocks allocated:         155648

time of lastaccess:            1436277889 TueJul  7 22:04:49 2015

time of lastmodification:      1449498101 MonDec  7 22:21:41 2015

time of laststatus change:     1449498181 MonDec  7 22:23:01 2015

total size, inbytes:             79691776 (76.000 MiB)

Size toprocess:                  79691776(76.000 MiB)

All workersfinished in 0 sec

然后解析文件,获取表的信息:

[root@centosundrop-for-innodb]# ./c_parser -4Df./pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page  -t ./dictionary/SYS_TABLES.sql  -o ./dumps/SYS_TABLES.dmp  -l ./dumps/SYS_TABLES.sql

[root@centosundrop-for-innodb]# cat ./dumps/SYS_TABLES.dmp | grep recover

000000055C05    05000002181423  SYS_TABLES      "test\_recover/a1"      1289   2       1       0      80      ""      1275

000000055C19    14000002042D29  SYS_TABLES      "test\_recover2/a2"     1290   2       1       0      64      ""      0

000000055C05    05000002181423  SYS_TABLES      "test\_recover/a1"      1289   2       1       0      80      ""      1275

000000055C19    14000002042D29  SYS_TABLES      "test\_recover2/a2"     1290   2       1       0      64      ""      0

这里我们发现了上一次测试场景里面的 test_recover.a1表的信息。我们这里可以一起尝试恢复下

test_recover.a1  1289

test_recover2.a21290

分别获取这2个表的索引信息:

[root@centosundrop-for-innodb]# ./c_parser -4Df ./pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page  -t ./dictionary/SYS_INDEXES.sql | grep 1289

00000000CCD1    58000001FA2FC1  SYS_INDEXES     841    1289    "PRIMARY"       1      3       827     3

SETFOREIGN_KEY_CHECKS=0;

[root@centosundrop-for-innodb]# ./c_parser -4Df./pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page  -t ./dictionary/SYS_INDEXES.sql | grep 1290

000000055C19    14000002042C82  SYS_INDEXES     1290    1575    "GEN\_CLUST\_INDEX"     0      1       0       4294967295

00000000CCD8    5C0000025C1EBB  SYS_INDEXES     842    1290    "PRIMARY"       2      3       828     3

000000055C19    14000002042C82  SYS_INDEXES     1290   1575    "GEN\_CLUST\_INDEX"     0      1       0       4294967295

SETFOREIGN_KEY_CHECKS=0;

LOAD DATALOCAL INFILE '/root/undrop-for-innodb/dumps/default/SYS_INDEXES' REPLACE INTOTABLE `SYS_INDEXES` FIELDS TERMINATED BY '\t' OPTIONALLY ENCLOSED BY '"'LINES STARTING BY 'SYS_INDEXES\t' (`TABLE_ID`, `ID`, `NAME`, `N_FIELDS`,`TYPE`, `SPACE`, `PAGE_NO`);

可以看到,只有1290找到了索引的ID是 1575 。test_recover.a1确实无法恢复了。

创建建表的文件  test_recover2/a2.sql

开始恢复数据。

[root@centosundrop-for-innodb]# ./c_parser -6fpages-ibdata1/FIL_PAGE_INDEX/0000000000001575.page -t test_recover2/a2.sql -odumps/a2.dmmp -l dumps/a2.sql

[root@centosundrop-for-innodb]# cat dumps/a2.dmmp

-- Page id:336, Format: COMPACT, Records list: Valid, Expected records: (3 3)

000000003500    000000055C11    8E000001410110  a2     1       2

000000003501    000000055C12    8F000002750110  a2     3       4

000000003502    000000055C17    92000002760110  a2     5       6

-- Page id:336, Found records: 3, Lost records: NO, Leaf page: YES

-- Page id:336, Format: COMPACT, Records list: Valid, Expected records: (3 3)

000000003500    000000055C11    8E000001410110  a2     1       2

000000003501    000000055C12    8F000002750110  a2     3       4

000000003502    000000055C17    92000002760110  a2     5       6

-- Page id:336, Found records: 3, Lost records: NO, Leaf page: YES

[root@centosundrop-for-innodb]#

可以看到数据可以恢复。

剩下的步骤就都一样了,创建表,然后加载数据。

恢复数据总结

Linux 平台:  都可以恢复。

Windows平台: 如果 innodb_file_per_table=OFF,则可以恢复,否则无法恢复。

恢复步骤:用stream_parser 工具恢复数据。

如果 innodb_file_per_table=OFF, 所有数据在 ibdata1中,用下面的命令:

./stream_parser-f /var/lib/mysql/ibdata1

如果innodb_file_per_table=ON, 所有数据在数据目录下,用下面的命令:

./stream_parser -f /dev/mapper/vg_centos-lv_root -t 50g

需要用df查看到的逻辑卷的地址,并用-t 指定逻辑卷的大小。

运行完毕后,会在当前目录下生成一个pages-xxxxx 的目录。所有恢复出来的数据都在这个目录下。

用c_parser 来解析恢复出来的文件

0000000000000001.page 文件中是恢复出来的SYS_TABLES 的内容。

./c_parser -4Df ./pages-vg_centos-lv_root/FIL_PAGE_INDEX/0000000000000001.page -t ./dictionary/SYS_TABLES.sql  -o ./dumps/SYS_TABLES.dmp  -l ./dumps/SYS_TABLES.sql

查看SYS_TABLES.dmp ,找到需要恢复的表的ID。page 文件中是恢复出来的 SYS_INDEXS的内容。

./c_parser -4Df./pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page  -t ./dictionary/SYS_INDEXES.sql

查看结果,筛选出所需要恢复表所对应的索引ID

恢复数据

找到000000[索引ID].page 文件,解析,前提是我们必须要有该表的建表语句

./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000027.page -ttest6/b.sql -o dumps/b.dump -l dumps/b.sql

恢复出来的数据在.dump 文件中,运行 test6/b.sql 创建表(如果没有建表语句的话,可以通过其他方式获取,在别的文章里面会提到),然后运行dumps/b.sql 加载数据。

命令手册

C_Parser

[root@centos undrop-for-innodb]# ./c_parser -h

Error: Usage: ./c_parser -4|-5|-6 [-dDV] -f -t table.sql [-T N:M] [-b ]

Where

-f -- InnoDB page or directory with pages(all pages shouldhave same index_id)

-t

--将创建表的语句输出到table.sql文件中

-o -- Save dump in this file. Otherwise print to stdout

-l -- Save SQL statements in this file. Otherwise print to stderr

-h  -- Print this help

-d  -- Process only those pages which potentiallycould have deleted records (default = NO)

-D  --只恢复删除的数据(默认是No) (default = NO)

-U  --只恢复没有删除的数据(默认是Yes) (default = YES)

-V  -- Verbose mode (lots of debug information)

-4  -- innodb_datafile is in REDUNDANT format

-5  -- innodb_datafile is in COMPACT format

-6  -- innodb_datafile is in MySQL 5.6 format

-T  -- retrieves only pages with index id = NM (N- high word, M - low word of id)

-b

-i -- Read external pages at their offsets from .

-p prefix -- Use prefix for a directoryname in LOAD DATA INFILE command

遇到的错误

Could not create directory

[root@centosundrop-for-innodb]# ./stream_parser -f /dev/mapper/vg_centos-lv_root -t 50g

Could notcreate directory pages-vg_centos-lv_root

mkdir(): File exists

如果看到这个错误,是因为已经存在 pages-vg_centos-lv_root这个目录了,只要删除这个目录就可以了。

Failed to parse tablestructure

[root@centos undrop-for-innodb]# ./c_parser -6fpages-ibdata1/FIL_PAGE_INDEX/0000000000000026.page -t test6/a.sql -odumps/a.dmmp -l dumps/a.sql

Line 2: syntax error at ''

1: create tablea(id int)

2:

Failed to parse table structure

这个错误是因为最后少了一个分号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值