概述
undrop-for-innodb是一款针对mysql innodb引擎数据的数据恢复工具。在数据库没有备份,binlog没有开启的情况下,可以通过读取磁盘页数据进行数据恢复,支持以下情况数据恢复:
- 删除了表或数据库。
- InnoDB 表空间损坏。
- 硬盘故障。
- 文件系统损坏。
- 从表中删除记录。
- 表被truncated。
- InnoDB文件被意外删除。
- 删除了一个表并创建了空表。
说明
在数据库没有开启binlog的情况下,该工具能够最大程度的恢复被删除的数据,前提是数据页未被覆盖。出现故障后应尽量保证数据库文件不会被覆盖写入。
原理delete数据的时候实际并没有从磁盘中删除(delete数据后表空间实际并不会变化),标记数据已经删除,后续写数据可覆盖该数据区域。
本文只记录了通过ibd文件恢复delete数据,若要恢复表结构需要其他操作,未曾尝试不做记录。
准备
- 下载 git clone https://github.com/twindb/undrop-for-innodb.git
- 运行环境 linux系统
- 依赖 make, gcc, flex, bison
- 编译 make
恢复过程
本次记录的是delete数据后的数据恢复过程,即已知数据结构(建表语句)
本次修复基于ibd文件,使用的配置为一个表对应一个ibd文件。
在误删数据后第一时间对被误删表的ibd文件进行备份。如果确定备份的文件没有被覆盖可以在其他服务器进行数据恢复。
- 解析ibd文件内容
./stream_parser -f cattle_base_info
参数:-f 指定要解析的文件地址
ID of device containing file: 64769
inode number: 660748
protection: 100644 (regular file)
number of hard links: 1
user ID of owner: 0
group ID of owner: 0
device ID (if special file): 0
blocksize for filesystem I/O: 4096
number of blocks allocated: 448
time of last access: 1657785448 Thu Jul 14 15:57:28 2022
time of last modification: 1657785433 Thu Jul 14 15:57:13 2022
time of last status change: 1657785433 Thu Jul 14 15:57:13 2022
total size, in bytes: 229376 (224.000 kiB)
Size to process: 229376 (224.000 kiB)
All workers finished in 0 sec
解析完成后会再当前目录下生产解析结果目录
pages-cattle_base_info.ibd/
├── FIL_PAGE_INDEX
│ └── 0000000000000615.page
└── FIL_PAGE_TYPE_BLOB
- 解析page获取数据内容
./c_parser -4Df pages-cattle_base_info.ibd/FIL_PAGE_INDEX/0000000000000615.page -t cattle_base_info.sql > /tmp/cattle_base_info.txt
参数
- 4 表示文件格式是 REDUNDANT,系统表的格式默认值。另外可以取值 5 表示 COMPACT 格式,6 表示 MySQL 5.6 格式。
- D 表示只恢复被删除的记录。
- f 要解析的page文件。
- t 后面跟着 CREATE TABLE 语句sql文件
执行结果
SET FOREIGN_KEY_CHECKS=0;
LOAD DATA LOCAL INFILE '/usr/local/undrop-for-innodb-develop/dumps/default/cattle_base_info' REPLACE INTO TABLE `cattle_base_info` CHARACTER SET UTF8 FIELDS TERMINATED BY '\t' OPTIONALLY ENCLOSED BY '"' LINES STARTING BY 'cattle_base_info\t' (`id`, `ear_no`, `num_no`, `neck_no`, `nick_name`, `father_id`, `mother_id`, `owner`, `owner_id`, `house_id`, `breeder`, `sex`, `come_in_date`, `birth_date`, `cattle_type`, `input_type`, `reproduction_class`, `breed_type`, `come_from`, `price`, `price_min`, `price_max`, `weight`, `health_status`, `sell_status`, `status`, `remark`, `create_user`, `create_time`, `update_user`, `update_time`);
-- STATUS {"records_expected": 281, "records_dumped": 1164, "records_lost": true} STATUS END
cattle_base_info.txt 文件部分内容
-- Page id: 3, Format: COMPACT, Records list: Invalid, Expected records: (0 1)
-- Page id: 3, Found records: 0, Lost records: NO, Leaf page: YES
-- Page id: 4, Format: COMPACT, Records list: Invalid, Expected records: (0 159)
000000072A76 1C000001D40EAC cattle_base_info 7142 "12345" 1 "12354" NULL 0 0 "2" -3 NULL NULL "1" NULL "2021-05-28" "2" NULL NULL NULL NULL NULL NULL NULL "25.00" "0 " "0 " "0 " NULL "162" "2021-05-28 15:37:37.0" NULL NULL
000000072A76 1C000001D40ED7 cattle_base_info 7144 "2021053001" 2 "2021053001" NULL 7142 0 "2" 24 NULL NULL "2" NULL "2019-01-29" "2" NULL NULL NULL NULL NULL NULL NULL "100.00" "0 " "0 " "0 " NULL "162" "2021-05-30 11:38:35.0" NULL NULL
000000072A76 1C000001D40F02 cattle_base_info 7145 "1000" 3 "1000" NULL 0 0 "2" -3 NULL NULL "2" NULL "2020-03-02" "2" NULL NULL NULL NULL NULL NULL NULL "200.00" "0 " "0 " "0 " NULL "162" "2021-05-31 12:29:43.0" NULL NULL
000000072A76 1C000001D40F2D cattle_base_info 7150 "7667" 4 "7767" NULL 0 0 "2" -3 NULL NULL "1" NULL "2021-05-31" "2" NULL NULL NULL NULL NULL NULL NULL "25.00" "0 " "0 " "0 " NULL "162" "2021-05-31 16:38:39.0" NULL NULL
000000072A76 1C000001D40F58 cattle_base_info 7152 "0111" 5 "0111" NULL 0 0 "2" 25 NULL NULL "2" NULL "2016-02-15" "2" NULL NULL NULL NULL NULL NULL NULL NULL "0 " "0 " "0 " NULL "162" "2021-05-31 17:11:35.0" NULL NULL
000000072A76 1C000001D40F83 cattle_base_info 7153 "0021" 6 "" NULL 0 0 "2" 25 NULL NULL "1" NULL "2016-05-31" "2" NULL NULL NULL NULL NULL NULL NULL NULL "0 " "0 " "0 " NULL "162" "2021-05-31 17:16:11.0" NULL NULL
- 整理数据导入mysql数据库