MySQL Drop Database之后的恢复测试

工具介绍

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

代码地址: https://github.com/twindb/undrop-for-innodb

官方文档: https://recovery.twindb.com/

介绍工具的一篇ppt  http://www.slideshare.net/akuzminsky/undrop-for-innodb

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

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

安装恢复软件

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

[[email protected]~]# yum install make  gcc  flex bison git

  1. 下载代码

[[email protected]~]# 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.

[[email protected]~]# 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.编译代码

[[email protected]~]# cd undrop-for-innodb/

[[email protected]]# 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

[[email protected]]# 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)

创建数据库和测试表

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

[[email protected] 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)

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

[[email protected]]# 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的目录。进入目录看下

[[email protected]]# cd test1

[[email protected]]# 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中。

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

[[email protected]]# du -sh *

4.0K    db.opt

12K     test1.frm

72M     test1.ibd

[[email protected]]# 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 是这个磁盘的大小。

[[email protected]~]# df -h /var/lib/mysql

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/vg_centos-lv_root

50G  4.1G  43G   9% /

[[email protected]]#./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

这里说明一下:

0000000000000001.page:  恢复出来的 SYS_TABLES 表

0000000000000003.page:  恢复出来的 SYS_INDEXES 表

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

[[email protected]]#mkdir -p dictionary dumps/default

[[email protected]]# ./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,可以看到我们删除掉的数据

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

可以看到 table_id 是 20。

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

可以看到,索引的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文件

[[email protected]]# pwd

/var/lib/mysql/test6

[[email protected]]# ls

a.frm  b.frm db.opt

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

[[email protected]]# du -sh ibdata1

76M     ibdata1

Ibdata1增长到了76M

删除数据库 test6

mysql> dropdatabase test6;

Query OK, 2rows affected (0.26 sec)

开始恢复数据

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

[[email protected]]# ./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。

[[email protected]]# ./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

[[email protected]]# 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

获取表中的索引信息

[[email protected]]# ./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)

删除数据库

开始恢复数据

首先安装 Samba。

yum install samba

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

测试下帐号:

[[email protected]~]# 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 目录下

[[email protected]~]# mount -t cifs -o username=admin,password=admin   //10.0.0.4/d$ /d/

[[email protected]~]# 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

尝试去恢复数据:

[[email protected]]#  ./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

换个参数:

[[email protected]]#  ./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=OFF Windows平台)

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

创建数据库和测试表

查看下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)

删除数据库

开始恢复数据

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

开始恢复数据

[[email protected]]#  ./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

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

[[email protected]]# ./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

[[email protected]]# 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个表的索引信息:

[[email protected]]# ./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;

[[email protected]]# ./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

开始恢复数据。

[[email protected]]# ./c_parser -6fpages-ibdata1/FIL_PAGE_INDEX/0000000000001575.page -t test_recover2/a2.sql -odumps/a2.dmmp -l dumps/a2.sql

[[email protected]]# 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

[[email protected]]#

可以看到数据可以恢复。

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

恢复数据总结

Linux 平台:  都可以恢复。

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

恢复步骤:

  1. 用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 的目录。所有恢复出来的数据都在这个目录下。

  1. 用c_parser 来解析恢复出来的文件
  2. 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。

  1. page 文件中是恢复出来的 SYS_INDEXS的内容。

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

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

  1. 恢复数据

找到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

[[email protected] undrop-for-innodb]# ./c_parser -h

Error: Usage: ./c_parser -4|-5|-6 [-dDV] -f <InnoDBpage or dir> -t table.sql [-T N:M] [-b <external pages directory>]

Where

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

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

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

-l<file> -- 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<dir> -- Directory where external pages can be found. Usually it ispages-XXX/FIL_PAGE_TYPE_BLOB/

-i<file> -- Read external pages at their offsets from <file>.

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

遇到的错误

Could not create directory

[[email protected]]# ./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

[[email protected] 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

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

时间: 2024-10-05 23:06:59

MySQL Drop Database之后的恢复测试的相关文章

mysql使用mysqldump备份、恢复

  mysqldump是mysql用于转存储数据库的实用程序.它主要产生一个SQL脚本,其中包含从头重新创建数据库所必需的命令CREATE TABLE INSERT等 mysqldump 语法 :      默认配置读取路径:  /etc/mysql/my.cnf     /etc/my.cnf    ~/.my.cnf            Usage: mysqldump [OPTIONS] database [tables]           OR     mysqldump [OPTI

mysql5.7基础 drop database if exists... 删除数据库前判断它是否存在

礼悟:    公恒学思合行悟,尊师重道存感恩.叶见寻根三返一,江河湖海同一体.          虚怀若谷良心主,愿行无悔给最苦.读书锻炼养身心,诚劝且行且珍惜. 数据.数据,命根就在数据.操作数据库一定要谨慎小心.给最苦 这里的代码,看看就好,要有自己的判断.遇到抉择,要不耻上下问. mysql:5.7                     os:Windows7 x64 代码及效果 mysql> show databases; +--------------------+ | Databa

xtrabackup 备份mysql数据库三: innobackupex 测试一个全量和两个增量的备份恢复测试

## 查看当前库中表的数据 ([email protected]) [test]>select count(*) from t_innodb; +----------+ | count(*) | +----------+ |        0 | +----------+ 1 row in set (0.00 sec) ## 执行插入数据操作,该操作在全备之后执行完成 ([email protected]) [test]>call addTest(100000,0); ## 执行全库备份 #

一个简单的binlog恢复测试

日常的数据备份及恢复测试,是DBA工作重中之重的事情,所以要做好备份及测试,日常的备份常见有mysqldump+binlog备份.xtrabackup+binlog备份,无论那一种,几乎都少不了对binlog的备份,说明了binlog在数据恢复中的重要性,下面做个小测试,是工作中不少运维或者新人DBA容易犯的错. 创建一个测试表tb1: <test>([email protected]) [xuanzhi]> show create table tb1\G ***************

Linux自学笔记——mysql基础、备份和恢复、主从复制、MHA

RDBMS:关系型数据库管理系统 C/S:通过专有协议 关系模型:表(行,列),二维关系: 范式:第一范式.第二范式.第三范式(在之前的博客中已经做过说明) 关系运算: 选择      投影 数据库:表,索引,视图(虚表) SQL:Structure Query Language DDL,DML 编程接口: 存储过程 存储函数 触发器 事件调度器 过程式编程:选择.循坏 三层模型: 物理层  逻辑层  视图层 解决方案: Oracle, Sybase, Infomix, DB2 MySQL, M

Mysql 基于innobackupex 的备份&amp;恢复

备份,对于任何数据库,任何系统都是重中之重.针对Mysql,我选择percona xtrabackup软件.我更喜欢物理层面的热备份.而不是逻辑层面的备份(mysqldump),当然很多情况,也要定期做mysqldump备份.增加一个安全的备份选择. 关于如何下载安装percona xtrabackup,请参考: http://blog.51cto.com/hsbxxl/2107388 先看看innobackupex常用参数 --compact        创建一个不包含第二索引(除了主键之外

【windows】环境下mysql的数据备份以及恢复

[windows]环境下mysql的数据备份以及恢复 无论是刚刚入行的'猿友'还是入行很久的'老猿',我相信都会遇到过因为各种原因(很多情况下是自己误删了数据库)的操作.drop databases xxxxx 而误删了线上项目的数据库是一件很恐怖的事情,那么如果大家遇到这种情况怎么办呢?首先不要着急(我感觉说了也白说-,-),先看一看自己的mysql是否开启了binlog日志功能,如果没有???game over !!! 关于查看binlog日志有没有开启,请到自己的Mysql文件下找my.i

MySQL数据库-完全备份及恢复

MySQL数据库-完全备份及恢复 数据库备份的分类 物理角度: 冷备份:也称脱机备份,特点:关掉数据库再备份 热备份:也称联机备份,特点:开启数据库再备份 温备份:数据库只有可读权限的状态下备份 逻辑角度: 对数据库的对象的备份,例如数据表,及数据表中的一些sql语句等 备份策略角度: 完全备份:每次对数据进行整体的备份 差异备份:在第一次完整备份a数据后,以后的每次的备份是a+b,b就是针对于a数据发生变化的数据,称之为'差异数据'.缺点:b的数据内存会越来越大b+=b,导致数据恢复缓慢.恢复

【mysql】使用tpcc-mysql进行压力测试

Tpcc-mysql是percona基于tpcc衍生出来专用于mysql基准测试的产品 ,可以参见 <高性能MySQL第三版> 一.安装 rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm yum install bzr bzr branch lp:~percona-dev/perconatools/tpcc-mysql 查看 README [[email protected] tpc