首先说一下,我们在操作数据库的时候,请切记一定要备份!备份!!备份!!!
这篇文档我是真的不想写的,但是遇到这样的问题了,而且处理起来比较麻烦的,在网上找了很多的文档,看了很多的方法,最后慢慢理解了数据回复的不步骤,才一点一点完成整个数据的恢复。
配置工具
- 下载undrop-for-innodb:
git clone https://github.com/twindb/undrop-for-innodb.git
- 安装并配置工具:
- 安装:
sudo apt install -y make gcc flex bison
- 配置
cd undrop-for-innodb
- `make
- $basedir 是 MySQL的安装路径:/usr/bin/mysql_config
sudo apt-get install libmariadb-client-lgpl-dev
- 或者:
sudo apt install libmysqld-dev
sudo ln -s /usr/bin/mariadb_config /usr/bin/mysql_config
- 安装:
gcc "$basedir/usr/bin/mysql_config --cflags" "$basedir/usr/bin/mysql_config --libs" -o sys_parser sys_parser.c
本地配置
数据恢复之前,我们首先最好先看一下本地配置:
- 系统:
uname -a
- 数据库的版本:
- 终端:
MySQL -V
- MySQL:
show variables like ‘%version%
- 终端:
- 数据库的存储:
show global variables like 'innodb_file_per_table';
- 数据库的登录状态:无密码登录(方便后续修改)
表结构
- 解析表结构:
./stream_parser -f /var/lib/mysql/ibdata1
- 创建存放sql文件的文件夹:
mkdir -p dumps/default
- 获取系统表,存入dumps文件夹:
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql > dumps/default/SYS_TABLES 2> dumps/default/SYS_TABLES.sql
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql > dumps/default/SYS_INDEXES 2> dumps/default/SYS_INDEXES.sql
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000002.page -t dictionary/SYS_COLUMNS.sql > dumps/default/SYS_COLUMNS 2> dumps/default/SYS_COLUMNS.sql
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000004.page -t dictionary/SYS_FIELDS.sql > dumps/default/SYS_FIELDS 2> dumps/default/SYS_FIELDS.sql
- 参数:
- 4 表示文件格式是 REDUNDANT,系统表的格式默认值。5–COMPACT 格式,6–MySQL 5.6 格式。
- D 表示只恢复被删除的记录。
- f 后面跟着文件。
- t 后面跟着 CREATE TABLE 语句,需要根据表的格式来解析文件
- 创建恢复数据库 recover,用来存放恢复的系统表:
create database recover
- 导入系统表:dictionary目录下是建表SQL,dumps/default/是刚才解析 page 得到的sql
mysql recover < dictionary/SYS_TABLES.sql
mysql recover < dictionary/SYS_INDEXES.sql
mysql recover < dictionary/SYS_FIELDS.sql
mysql recover < dictionary/SYS_COLUMNS.sql
mysql recover < dumps/default/SYS_TABLES.sql
mysql recover < dumps/default/SYS_INDEXES.sql
mysql recover < dumps/default/SYS_FIELDS.sql
mysql recover < dumps/default/SYS_COLUMNS.sql
- 解析表结构,把数据表的创建语句写入
tmp/direction.sql
中:
./sys_parser -d recover Test/tb_direction > tmp/tb_direction.sql
CREATE TABLE `tb_direction`(
`id` INT NOT NULL,
`name` VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL,
`parent_id` INT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
获取数据文件id
- 查看table_id:
grep direction dumps/default/SYS_TABLES
- 查看table_id的index_id:
grep 480 dumps/default/SYS_INDEXES
表数据
当innodb_file_per_table=ON时,我们的数据在磁盘中是分开存储的,我们只是使用mysql/ibdata1,没法获取所有的数据文件,我们可以使用stream_parser扫描磁盘,解析磁盘中的page文件。
- 查看磁盘使用情况:
df -h
- 解析磁盘文件(注意扫描大小):
./stream_parser -f /dev/sda2 -t 50G
- 我们在解析
pages-sda2
中的文件:
-- 会在`dumps/defaul`中生成:direction、direction_load.sql两个文件
./c_parser -6f pages-sda2/FIL_PAGE_INDEX/0000000000000999.page -t tmp/direction.sql > dumps/default/direction 2> dumps/default/direction.sql
- 恢复数据
mysql Test < tm/direction.sql
mysql Test < dumps/default/direction_load.sql
数据恢复完成了,记得验证数据哦!
评论区