找回密码
 立即注册
首页 业界区 安全 工具分享-从ibd文件中恢复数据的神器ibd2sql ...

工具分享-从ibd文件中恢复数据的神器ibd2sql

裒噎 2025-6-13 09:32:05
工具分享-从ibd文件中恢复数据的神器ibd2sql

1. ibd2sql 的使用场景

在单节点单表表空间损坏的情况下,一般我们想到的方法是从最近的备份中恢复表数据并从Binlog中合并数据。
假如备份和Binlog缺失,那就只能从ibd文件中紧急恢复数据,可以使用 ibd2sql 这个工具去恢复数据。
2. ibd2sql 简介

ibd2sql is tool of transform mysql ibd file to sql(data).
ibd2sql是一个使用纯python3编写的离线解析 MySQL InnoDB 存储引擎的ibd文件的工具。无第三方依赖包,使用GPL-3.0 license。

  • 项目地址:https://github.com/ddcw/ibd2sql
3. 实测

3.1 环境信息

操作系统:ky10.x86_64
数据库版本:GreatSQL-8.0.32-27
3.2数据库安装并初始化数据

GreatSQL安装参考:https://greatsql.cn/docs/8.0.32-27/3-quick-start/3-2-quick-start-with-tarball.html
  1. --创建测试库
  2. CREATE database test;
  3. --创建测试表
  4. CREATE TABLE `test`.`workflow_state` (
  5.   `id` int NOT NULL AUTO_INCREMENT,
  6.   `creator` varchar(64) DEFAULT NULL,
  7.   `create_at` datetime(6) NOT NULL,
  8.   `update_at` datetime(6) NOT NULL,
  9.   `updated_by` varchar(64) DEFAULT NULL,
  10.   `end_at` datetime(6) DEFAULT NULL,
  11.   `is_deleted` tinyint(1) NOT NULL,
  12.   `name` varchar(64) NOT NULL,
  13.   `desc` varchar(64) DEFAULT NULL,
  14.   `type` varchar(32) NOT NULL,
  15.   `processors_type` varchar(32) NOT NULL,
  16.   `processors` varchar(255) DEFAULT NULL,
  17.   `distribute_type` varchar(32) NOT NULL,
  18.   `notify_rule` varchar(32) NOT NULL,
  19.   `notify_freq` int NOT NULL,
  20.   `fields` longtext,
  21.   `extras` varchar(1000) DEFAULT NULL,
  22.   `is_draft` tinyint(1) NOT NULL,
  23.   `is_builtin` tinyint(1) NOT NULL,
  24.   `workflow_id` int NOT NULL,
  25.   `is_terminable` tinyint(1) NOT NULL,
  26.   `followers` varchar(255) DEFAULT NULL,
  27.   `followers_type` varchar(32) NOT NULL,
  28.   `api_instance_id` int DEFAULT NULL,
  29.   `assignors` longtext DEFAULT (_utf8mb3''),
  30.   PRIMARY KEY (`id`),
  31.   KEY `workflow_state_workflow_id_ef53cea4_fk_workflow_workflow_id` (`workflow_id`),
  32.   KEY `workflow_state_is_deleted_37d5c517` (`is_deleted`)
  33. ) ENGINE=InnoDB;
  34. --插入初始化数据
  35. INSERT INTO `test`.`workflow_state` VALUES (1, 'admin', '2025-4-28 10:0:0.0', '2025-4-28 10:0:0.0', NULL, NULL, 0, '审批节点1', '基础审批流程', 'approval', 'user', 'user123', 'round_robin', 'immediate', 1, '{"field1": "value1"}', '{"priority": "high"}', 0, 1, 1, 1, 'user456,user789', 'specific', 1001, '["assignor1"]');
  36. INSERT INTO `test`.`workflow_state` VALUES (10, 'system', '2025-4-28 10:45:0.0', '2025-4-28 10:45:0.0', NULL, NULL, 0, '子流程', '调用子工作流', 'subflow', 'system', NULL, 'direct', 'immediate', 1, '{"subflow_id": 100}', '{"parameters": "{}"}', 0, 1, 10, 1, NULL, 'none', 1006, '[]');
复制代码
3.3ibd2sql下载使用
  1. -- 安装python3
  2. yum -y install python3
  3. -- 下载ibd2sql,没法通过wget下载,可以直接复制网址到浏览器下载
  4. wget https://github.com/ddcw/ibd2sql/archive/refs/heads/main.zip
  5. -- 解压
  6. unzip ibd2sql-main.zip
  7. -- 进入ibd2sql
  8. cd ibd2sql-main
复制代码
3.3.1尝试对workflow_state表进行表结构恢复
  1. -- 恢复表结构,后面带的 --ddl为生成表结构
  2. $ python3.7 main.py /greatsql/dbdata/data3306/data/test/workflow_state.ibd --sql --ddl
  3. CREATE TABLE IF NOT EXISTS `test`.`workflow_state`(
  4.     `id` int NOT NULL AUTO_INCREMENT,
  5.     `creator` varchar(64) NULL,
  6.     `create_at` datetime(6) NOT NULL,
  7.     `update_at` datetime(6) NOT NULL,
  8.     `updated_by` varchar(64) NULL,
  9.     `end_at` datetime(6) NULL,
  10.     `is_deleted` tinyint(1) NOT NULL,
  11.     `name` varchar(64) NOT NULL,
  12.     `desc` varchar(64) NULL,
  13.     `type` varchar(32) NOT NULL,
  14.     `processors_type` varchar(32) NOT NULL,
  15.     `processors` varchar(255) NULL,
  16.     `distribute_type` varchar(32) NOT NULL,
  17.     `notify_rule` varchar(32) NOT NULL,
  18.     `notify_freq` int NOT NULL,
  19.     `fields` longtext NULL,
  20.     `extras` varchar(1000) NULL,
  21.     `is_draft` tinyint(1) NOT NULL,
  22.     `is_builtin` tinyint(1) NOT NULL,
  23.     `workflow_id` int NOT NULL,
  24.     `is_terminable` tinyint(1) NOT NULL,
  25.     `followers` varchar(255) NULL,
  26.     `followers_type` varchar(32) NOT NULL,
  27.     `api_instance_id` int NULL,
  28.     `assignors` longtext NULL DEFAULT (_utf8mb3''),
  29.     PRIMARY KEY  (`id` ),
  30.     KEY `workflow_state_workflow_id_ef53cea4_fk_workflow_workflow_id` (`workflow_id` ),
  31.     KEY `workflow_state_is_deleted_37d5c517` (`is_deleted` )
  32. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ;
复制代码
3.3.2尝试对workflow_state表进行表数据恢复
  1. -- 恢复表数据,后面带的 --sql把数据转换为sql,也可以使用--complete-insert合并insert
  2. $ python3.7 main.py /greatsql/dbdata/data3306/data/test/workflow_state.ibd --sql
  3. INSERT INTO `test`.`workflow_state` VALUES (1, 'admin', '2025-4-28 10:0:0.0', '2025-4-28 10:0:0.0', NULL, NULL, 0, '审批节点1', '基础审批流程', 'approval', 'user', 'user123', 'round_robin', 'immediate', 1, '{"field1": "value1"}', '{"priority": "high"}', 0, 1, 1, 1, 'user456,user789', 'specific', 1001, '["assignor1"]');
  4. INSERT INTO `test`.`workflow_state` VALUES (10, 'system', '2025-4-28 10:45:0.0', '2025-4-28 10:45:0.0', NULL, NULL, 0, '子流程', '调用子工作流', 'subflow', 'system', NULL, 'direct', 'immediate', 1, '{"subflow_id": 100}', '{"parameters": "{}"}', 0, 1, 10, 1, NULL, 'none', 1006, '[]');
复制代码
3.3.3更多使用方法

可以使用--help 查看完整的使用方法,在表空间损坏的情况下可以通过--force, -f 强制调用ibd文件拯救数据
  1. --help详情
  2. $ python3.7 main.py --help
  3. usage: main.py [--help] [--version] [--ddl] [--sql] [--delete]
  4.                [--complete-insert] [--force] [--set] [--multi-value]
  5.                [--replace] [--table TABLE_NAME] [--schema SCHEMA_NAME]
  6.                [--sdi-table SDI_TABLE] [--where-trx WHERE_TRX]
  7.                [--where-rollptr WHERE_ROLLPTR] [--limit LIMIT] [--debug]
  8.                [--debug-file DEBUG_FILE] [--page-min PAGE_MIN]
  9.                [--page-max PAGE_MAX] [--page-start PAGE_START]
  10.                [--page-count PAGE_COUNT] [--page-skip PAGE_SKIP] [--mysql5]
  11.                [--keyring-file KEYRING_FILE]
  12.                [FILENAME]
  13. -- 解析mysql 5.7/8.0的ibd文件 https://github.com/ddcw/ibd2sql
  14. positional arguments:
  15.   FILENAME              ibd filename
  16. optional arguments:
  17.   --help, -h            show help
  18.   --version, -v, -V     show version
  19.   --ddl, -d             print ddl
  20.   --sql                 print data by sql
  21.   --delete              print data only for flag of deleted
  22.   --complete-insert     use complete insert statements for sql
  23.   --force, -f           force pasrser file when Error Page
  24.   --set                 set/enum to fill in actual data instead of strings
  25.   --multi-value         single sql if data belong to one page
  26.   --replace             "REPLACE INTO" replace to "INSERT INTO" (default)
  27.   --table TABLE_NAME    replace table name except ddl
  28.   --schema SCHEMA_NAME  replace table name except ddl
  29.   --sdi-table SDI_TABLE
  30.                         read SDI PAGE from this file(ibd)(partition table)
  31.   --where-trx WHERE_TRX
  32.                         default (0,281474976710656)
  33.   --where-rollptr WHERE_ROLLPTR
  34.                         default (0,72057594037927936)
  35.   --limit LIMIT         limit rows
  36.   --debug, -D           will DEBUG (it's too big)
  37.   --debug-file DEBUG_FILE
  38.                         default sys.stdout if DEBUG
  39.   --page-min PAGE_MIN   if PAGE NO less than it, will break
  40.   --page-max PAGE_MAX   if PAGE NO great than it, will break
  41.   --page-start PAGE_START
  42.                         INDEX PAGE START NO
  43.   --page-count PAGE_COUNT
  44.                         page count NO
  45.   --page-skip PAGE_SKIP
  46.                         skip some pages when start parse index page
  47.   --mysql5              for mysql5.7 flag
  48.   --keyring-file KEYRING_FILE, -k KEYRING_FILE
  49.                         keyring filename
  50. Example:
  51. ibd2sql /data/db1/xxx.ibd --ddl --sql
  52. ibd2sql /data/db1/xxx.ibd --delete --sql
  53. ibd2sql /data/db1/xxx#p#p1.ibd --sdi-table /data/db1/xxx#p#p0.ibd --sql
  54. ibd2sql /mysql57/db1/xxx.ibd --sdi-table /mysql80/db1/xxx.ibd --sql --mysql5
复制代码
3.3.4修改lower_case_table_names

lower_case_table_names 是 MySQL 设置大小写是否敏感的一个参数。
  1. lower_case_table_names = 0 表名存储为给定的大小和比较是区分大小写的
  2. lower_case_table_names = 1 表名存储在磁盘是小写的,但是比较的时候是不区分大小写
  3. lower_case_table_names = 2 表名存储为给定的大小写但是比较的时候是小写的
复制代码
通常我们在数据库初始化的时候就已经确定这个参数,想要修改这个参数只能导出重新初始化再导入。
但是ibd2sql号称可以直接修改lower_case_table_names,请各位看官老爷往下看。
lower_case_table_names 由0改成1,对象中已经有大小写混合,可以启动但是原本大小写混合对象读写会有问题
  1. CREATE TABLE IF NOT EXISTS `test`.`TMst`(
  2.     `id` int NOT NULL AUTO_INCREMENT,
  3.     `creator` varchar(64) NULL,
  4.     `updated_by` varchar(64) NULL,
  5.     `end_at` datetime(6) NULL,
  6.     PRIMARY KEY  (`id` )
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ;
  8. INSERT INTO test.TMst (creator) VALUES ('user2');
  9. INSERT INTO test.TMst (creator) VALUES ('user1');
  10. --查看原来的lower_case_table_names为1还是0
  11. $ python3 modify_lower_case_table_names.py /greatsql/dbdata/data3306/data/mysql.ibd
  12. lower_case_table_names: 0
  13. --停止数据库
  14. $ systemctl stop greatsql
  15. --修改lower_case_table_names为1
  16. $ python3 modify_lower_case_table_names.py /greatsql/dbdata/data3306/data/mysql.ibd ./mysql.ibd 1
  17. set lower_case_table_names=1 into new file(./mysql.ibd) finish.
  18. --对比文件权限属主
  19. $ ls -la ./mysql.ibd
  20. -rw-r--r-- 1 root root 26214400 Apr 29 10:58 ./mysql.ibd
  21. $ ls -la /greatsql/dbdata/data3306/data/mysql.ibd
  22. -rw-r----- 1 greatsql greatsql 26214400 Apr 29 10:56 /greatsql/dbdata/data3306/data/mysql.ibd
  23. --修改文件属主
  24. $  chmod 640 ./mysql.ibd
  25. $  chown greatsql:greatsql ./mysql.ibd  
  26. -- 覆盖原来的mysql.ibd文件
  27. $ mv ./mysql.ibd /greatsql/dbdata/data3306/data
  28. mv: overwrite '/greatsql/dbdata/data3306/data/mysql.ibd'? y
  29. --修改配置文件 lower_case_table_names=1
  30. $ vi /greatsql/conf/greatsql3306.cnf
  31. --启动数据库
  32. $ systemctl start greatsql
  33. --查询表,插入数据报错
  34. greatsql> show tables;
  35. +----------------+
  36. | Tables_in_test |
  37. +----------------+
  38. | TMst           |
  39. +----------------+
  40. 1 row in set (0.01 sec)
  41. greatsql> SELECT * FROM TMst;
  42. ERROR 1146 (42S02): Table 'test.tmst' doesn't exist
  43. greatsql> INSERT INTO test.TMst (creator) VALUES ('user3');
  44. ERROR 1146 (42S02): Table 'test.tmst' doesn't exist
  45. greatsql> DROP database test;
  46. greatsql> CREATE database test;
  47. ERROR 3678 (HY000): Schema directory './test' already exists. This must be resolved manually (e.g. by moving the schema directory to another location).
复制代码
lower_case_table_names 由1改成0,对象读写正常
  1. create database test1;
  2. CREATE TABLE IF NOT EXISTS `test1`.`tmst`(
  3.     `id` int NOT NULL AUTO_INCREMENT,
  4.     `creator` varchar(64) NULL,
  5.     `updated_by` varchar(64) NULL,
  6.     `end_at` datetime(6) NULL,
  7.     PRIMARY KEY  (`id` )
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ;
  9. INSERT INTO test1.tmst (creator) VALUES ('user2');
  10. INSERT INTO test1.tmst (creator) VALUES ('user1');
  11. --查看原来的lower_case_table_names为1还是0
  12. $ python3 modify_lower_case_table_names.py /greatsql/dbdata/data3306/data/mysql.ibd
  13. lower_case_table_names: 1
  14. --停止数据库
  15. $ systemctl stop greatsql
  16. --修改lower_case_table_names为1
  17. $ python3 modify_lower_case_table_names.py /greatsql/dbdata/data3306/data/mysql.ibd ./mysql.ibd 0
  18. set lower_case_table_names=0 into new file(./mysql.ibd) finish.
  19. --对比文件权限属主
  20. $ ls -la ./mysql.ibd
  21. -rw-r--r-- 1 root root 26214400 Apr 29 10:58 ./mysql.ibd
  22. $ ls -la /greatsql/dbdata/data3306/data/mysql.ibd
  23. -rw-r----- 1 greatsql greatsql 26214400 Apr 29 10:56 /greatsql/dbdata/data3306/data/mysql.ibd
  24. --修改文件属主
  25. $  chmod 640 ./mysql.ibd
  26. $  chown greatsql:greatsql ./mysql.ibd  
  27. -- 覆盖原来的mysql.ibd文件
  28. $ mv ./mysql.ibd /greatsql/dbdata/data3306/data
  29. mv: overwrite '/greatsql/dbdata/data3306/data/mysql.ibd'? y
  30. --修改配置文件 lower_case_table_names=1
  31. $ vi /greatsql/conf/greatsql3306.cnf
  32. --启动数据库
  33. $ systemctl start greatsql
  34. --查询表,新建带有大写的表均正常
  35. greatsql> CREATE TABLE IF NOT EXISTS `test1`.`TMst`(
  36.     ->     `id` int NOT NULL AUTO_INCREMENT,
  37.     ->     `creator` varchar(64) NULL,
  38.     ->     `updated_by` varchar(64) NULL,
  39.     ->     `end_at` datetime(6) NULL,
  40.     ->     PRIMARY KEY  (`id` )
  41.     -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ;
  42. Query OK, 0 rows affected (0.01 sec)
  43. greatsql> INSERT INTO test1.TMst (creator) VALUES ('user2');
  44. Query OK, 1 row affected (0.02 sec)
  45. greatsql> INSERT INTO test1.TMst (creator) VALUES ('user1');
  46. Query OK, 1 row affected (0.01 sec)
  47. greatsql> SELECT * FROM `test1`.`TMst`;
  48. +----+---------+------------+--------+
  49. | id | creator | updated_by | end_at |
  50. +----+---------+------------+--------+
  51. |  1 | user2   | NULL       | NULL   |
  52. |  2 | user1   | NULL       | NULL   |
  53. +----+---------+------------+--------+
  54. 2 rows in set (0.00 sec)
  55. greatsql> SELECT * FROM `test1`.`tmst`;
  56. +----+---------+------------+--------+
  57. | id | creator | updated_by | end_at |
  58. +----+---------+------------+--------+
  59. |  1 | user2   | NULL       | NULL   |
  60. |  2 | user1   | NULL       | NULL   |
  61. +----+---------+------------+--------+
  62. 2 rows in set (0.01 sec)
复制代码
结论


  • 修改lower_case_table_names
  • 由0改成1,对象中已经有大小写混合,可以启动但是原本大小写混合对象读写会有问题。
  • 由1改成0,对象读写正常,操作名字大小混合的对象也正常。
参考文章


  • GreatSQL 二进制安装:https://greatsql.cn/docs/8.0.32-27/3-quick-start/3-2-quick-start-with-tarball.html
  • ibd2sql项目README_zh.md https://github.com/ddcw/ibd2sql/blob/main/README_zh.md

Enjoy GreatSQL
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册