返回列表 发帖

MySQL利用ext3grep恢复Myisam表

MySQL没有类型Oracle的闪回机制,当你执行了drop table xxx 之后,这个表就永久删除了,你只能从备份里进行恢复,如果你没有备份,那你就只能哭了。本文提供一种思路,让类似情况能有挽回的机会。

我们知道,Mysql的MYISAM引擎表在当前Database目录下,有3个对应的文件,frm结构文件,MYI索引文件,MYD数据文件。当你在Mysql中,drop了MYISAM引擎表后,其实就是在文件系统里将其对应的3个文件rm了。所以当你执行drop后,如果能将上面3个文件恢复,那么表也将恢复。

如果你使用的是EXT3文件系统,那么可以使用ext3grep来完成上面的操作,举例说明:

1.安装ext3grep
首先需要安装e2fsprogs-libs,可以到http://e2fsprogs.sourceforge.net/下载源码包

tar -xzvf e2fsprogs-1.41.5.tar.gz
cd e2fsprogs-1.41.5
mkdir build; cd build
../configure
make
make install
make install-libs(e2fsprogs-libs)

在安装ext3grep,可以到http://code.google.com/p/ext3grep/downloads/list下载

tar xfvz ext3grep-0.10.1.tar.gz
cd ext3grep-0.10.1
./configure
make
make install

ext3grep -V
Running ext3grep version 0.10.1
ext3grep v0.10.1, Copyright (C) 2008 Carlo Wood.
ext3grep comes with ABSOLUTELY NO WARRANTY;
This program is free software; your freedom to use, change
and distribute this program is protected by the GPL.

2.删除测试表

mysql> use test
mysql> desc t;
+——-+———+——+—–+———+——-+
| Field | Type    | Null | Key | Default | Extra |
+——-+———+——+—–+———+——-+
| id    | int(10) | YES  |     | NULL    |       |
+——-+———+——+—–+———+——-+
1 row in set (0.01 sec)

mysql> select * from t;
+——+
| id   |
+——+
|    1 |
|    2 |
|    3 |
+——+
3 rows in set (0.00 sec)

mysql>drop table t;

mysql> quit

3.停止mysql,并将数据文件所在分区umount。

# /etc/init.d/mysqld stop
Shutting down MySQL..                                      [  OK  ]
cd
# umount /dev/sda6

4.利用ext3grep工具进行恢复

# ext3grep /dev/sda6 –ls –inode 2
Running ext3grep version 0.10.1
WARNING: I don’t know what EXT3_FEATURE_COMPAT_EXT_ATTR is.
Number of groups: 1778
Loading group metadata… done
Minimum / maximum journal block: 29065730 / 29099045
Loading journal descriptors… sorting… done
The oldest inode block that is still in the journal, appears to be from 1243924942 = Tue Jun  2 14:42:22 2009
Number of descriptors in journal: 418; min / max sequence numbers: 13 / 36
Inode is Allocated
Loading sda6.ext3grep.stage2… done
The first block of the directory is 1539.
Inode 2 is directory “”.
Directory block 1539:
.– File type in dir_entry (r=regular file, d=directory, l=symlink)
|          .– D: Deleted ; R: Reallocated
Indx Next |  Inode   | Deletion time                        Mode        File name
==========+==========+—————-data-from-inode——+———–+=========
0    1 d       2                                         drwxr-xr-x  .
1    2 d       2                                         drwxr-xr-x  ..
2    3 d      11                                         drwx——  lost+found
3    4 r      12                                         rrw-r–r–  1
4    5 r      13                                         rrw-r–r–  5
5  end d  237569                                         drwxr-xr-x  data
6  end r      15  D 1243919862 Tue Jun  2 13:17:42 2009  rrw-r–r–  3.txt

可以看到Mysql数据文件的目录data对应的Inode是237569,然后在查看改Inode对应的block。

# ext3grep /dev/sda6 –inode 237569
Running ext3grep version 0.10.1
No –ls used; implying –print.

Inode is Allocated
Group: 29
Generation Id: 3010341297
uid / gid: 500 / 500
mode: drwxr-xr-x
size: 4096
num of links: 4
sectors: 8 (–> 0 indirect blocks).

Inode Times:
Accessed:       1243930169 = Tue Jun  2 16:09:29 2009
File Modified:  1243930170 = Tue Jun  2 16:09:30 2009
Inode Modified: 1243930170 = Tue Jun  2 16:09:30 2009
Deletion time:  0

Direct Blocks: 968704
Loading sda6.ext3grep.stage2… done
There is no directory block associated with inode 237569.

看到Direct Blocks: 968704,在查看这个block。

# ext3grep /dev/sda6 –ls –block 968704
Running ext3grep version 0.10.1
WARNING: I don’t know what EXT3_FEATURE_COMPAT_EXT_ATTR is.
Number of groups: 1778
Minimum / maximum journal block: 29065730 / 29099045
Loading journal descriptors… sorting… done
The oldest inode block that is still in the journal, appears to be from 1243925348 = Tue Jun  2 14:49:08 2009
Number of descriptors in journal: 236; min / max sequence numbers: 15 / 45
Group: 29

Block 968704 is a directory. The block is Allocated

.– File type in dir_entry (r=regular file, d=directory, l=symlink)
|          .– D: Deleted ; R: Reallocated
Indx Next |  Inode   | Deletion time                        Mode        File name
==========+==========+—————-data-from-inode——+———–+=========
0    1 d  237569                                         drwxr-xr-x  .
1    3 d       2                                         drwxr-xr-x  ..
2    3 r  237570  D 1243930170 Tue Jun  2 16:09:30 2009  rrw-r—–  mysql.err
3    4 d  237571                                         drwx——  mysql
4    5 r  237641                                         rrw-r—–  ibdata1
5    7 d  237642                                         drwx——  test
6    7 r  237646  D 1243926673 Tue Jun  2 15:11:13 2009  rrw-rw—-  mysql.pid
7    8 r  237647                                         rrw-r—–  ib_logfile0
8  end r  237648                                         rrw-r—–  ib_logfile1

在data目录下面,其文件所对应的Inode,我们是删除的test下的表,所以在查看test目录所对应的Inode.

# ext3grep /dev/sda6 –inode 237642
Running ext3grep version 0.10.1
No –ls used; implying –print.

Inode is Allocated
Group: 29
Generation Id: 3010341370
uid / gid: 500 / 500
mode: drwx——
size: 4096
num of links: 2
sectors: 8 (–> 0 indirect blocks).

Inode Times:
Accessed:       1243928606 = Tue Jun  2 15:43:26 2009
File Modified:  1243928606 = Tue Jun  2 15:43:26 2009
Inode Modified: 1243928606 = Tue Jun  2 15:43:26 2009
Deletion time:  0

Direct Blocks: 971511
Loading sda6.ext3grep.stage2… done
There is no directory block associated with inode 237642.

# ext3grep /dev/sda6 –ls –block 971511
Running ext3grep version 0.10.1
WARNING: I don’t know what EXT3_FEATURE_COMPAT_EXT_ATTR is.
Number of groups: 1778
Minimum / maximum journal block: 29065730 / 29099045
Loading journal descriptors… sorting… done
The oldest inode block that is still in the journal, appears to be from 1243925348 = Tue Jun  2 14:49:08 2009
Number of descriptors in journal: 236; min / max sequence numbers: 15 / 45
Group: 29

Block 971511 is a directory. The block is Allocated

.– File type in dir_entry (r=regular file, d=directory, l=symlink)
|          .– D: Deleted ; R: Reallocated
Indx Next |  Inode   | Deletion time                        Mode        File name
==========+==========+—————-data-from-inode——+———–+=========
0    1 d  237642                                         drwx——  .
1  end d  237569                                         drwxr-xr-x  ..
2    3 r  237643  D 1243928606 Tue Jun  2 15:43:26 2009  rrw-r—–  u.frm
3    4 r  237649  D 1243928606 Tue Jun  2 15:43:26 2009  rrw-r—–  u.MYD
4  end r  237645  D 1243928606 Tue Jun  2 15:43:26 2009  rrw-r—–  u.MYI
5  end r  237644  D 1243926666 Tue Jun  2 15:11:06 2009  rrw-rw—-  t.frm
6    7 r  237650  D 1243926666 Tue Jun  2 15:11:06 2009  rrw-rw—-  t.MYI
7  end r  237651  D 1243926666 Tue Jun  2 15:11:06 2009  rrw-rw—-  t.MYD

ok,到这里我们需要恢复的表t的3个文件已经出来了,然后在执行恢复。

# ext3grep /dev/sda6 –restore-inode 237650
Running ext3grep version 0.10.1
Restoring inode.237650
# ext3grep /dev/sda6 –restore-inode 237651
Running ext3grep version 0.10.1
Restoring inode.237651

# ext3grep /dev/sda6 –restore-inode 237644
Running ext3grep version 0.10.1
Restoring inode.237644

cd RESTORED_FILES/
mv inode.237644 t.frm
mv inode.237650 t.MYI
mv inode.237651 t.MYD
ll
total 20
-rw-r—–  1 root root 8556 Jun  2 16:26 t.frm
-rw-r—–  1 root root   21 Jun  2 16:26 t.MYD
-rw-r—–  1 root root 1024 Jun  2 16:26 t.MYI

将数据文件所在分区mount,并将恢复的表t的文件copy到原目录。设置好权限,启动mysql。

mount /dev/sda6 /u01
cp t.* /u01/data/test
chown -R mysql.mysql test/
/etc/init.d/mysqld start
Starting MySQL.                                            [  OK  ]
mysql> use test
Database changed

mysql> select * from t;
+——+
| id   |
+——+
|    1 |
|    2 |
|    3 |
+——+
3 rows in set (0.01 sec)

OK,表已经被恢复。

返回列表