Mysql利用ext3grep恢复Myisam表
2009年06月20日 作者: 大头刚
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,表已经被恢复。




- Comments (0)
- Trackbacks (0)
Leave a comment TrackbackNo comments yet.
No trackback yet.