E-mail:chf.dba@gmail.com
Title: MySQL ibd Recovery
Author: DATABASE SOS©All rights reserved [without my consent, it may not be reproduced in any form, otherwise there is the right to further legal responsibility.]
The ibd file is saved in mysql for some reason, but the table has been deleted or the frm file is damaged or the ibdata file is damaged / lost. This article simulates that in this case, ibd file recovery can be completed through mysql’s own technology.
Test environment mysql version
mysql> select version (); + ----------- + | version () | + ----------- + | 5.6.25 | + ----------- + 1 row in set (0.00 sec)
mysql main parameters
mysql> show variables like 'innodb_file_per_table'; + ----------------------- + ------- + | Variable_name | Value | + ----------------------- + ------- + | innodb_file_per_table | ON | + ----------------------- + ------- + 1 row in set (0.00 sec) mysql> show variables like 'innodb_force_recovery'; + ----------------------- + ------- + | Variable_name | Value | + ----------------------- + ------- + | innodb_force_recovery | 0 | + ----------------------- + ------- + 1 row in set (0.00 sec)
The innodb_file_per_table parameter is on to enable each table to store a separate ibd file.The default range of the innodb_force_recovery parameter is 0
Test table situation
mysql> use xifenfei; Database changed mysql> show tables; + ----------------------------- + | Tables_in_xifenfei | + ----------------------------- + | user_login | + ----------------------------- + 1 rows in set (0.00 sec) mysql> select count (*) from user_login; + ---------- + | count (*) | + ---------- + | 48 | + ---------- + 1 row in set (0.02 sec) mysql> desc user_login; + ------------ + -------------- + ------ + ----- + -------- -+ ------- + Field | Type | Null | Key | Default | Extra | + ------------ + -------------- + ------ + ----- + -------- -+ ------- + | ID | varchar (255) | NO | PRI | NULL | | | ACCOUNT | varchar (255) | YES | | NULL | | | LifeCycle | int (11) | YES | | NULL | | | Name | varchar (255) | YES | | NULL | | | Password | varchar (255) | YES | | NULL | | | Role | varchar (255) | YES | | NULL | | | UTime | varchar (255) | YES | | NULL | | UserID | varchar (255) | YES | | NULL | | | UserName | varchar (255) | YES | | NULL | | UserStatus | int (11) | YES | | NULL | | + ------------ + -------------- + ------ + ----- + -------- -+ ------- + 10 rows in set (0.05 sec) mysql> select * from user_login limit 1; + ---------------------------------- + --------- + ---- ------- + ----------- + ---------- ------------------------ + ------ + ------------------ --- + -------------------------- -------- + ---------- + ------------ + | ID | ACCOUNT | LifeCycle | Name | Password | Role | UTime | UserID | UserName | UserStatus | + ---------------------------------- + --------- + ---- ------- + ----------- + ---------- ------------------------ + ------ + ------------------ --- + -------------------------- -------- + ---------- + ------------ + | 010d6c85a76c44cba80d07cbd8590bb2 | hyh | 0 | Hu Yuanhui | 698d51a19 d8a121ce581499d7b701668 | | 6 | | 2016-08-30 06:04:32 | 0fe3bc4dd9654687a4b85065e d5cfee8 | NULL | 1 | + ---------------------------------- + --------- + ---- ------- + ----------- + ---------- ------------------------ + ------ + ------------------ --- + -------------------------- -------- + ---------- + ------------ + 1 row in set (0.00 sec) mysql> show create table user_login \ G; *************************** 1. row ************* Table: user_login Create Table: CREATE TABLE `user_login` ( `ID` varchar (255) NOT NULL, `ACCOUNT` varchar (255) DEFAULT NULL, `LifeCycle` int (11) DEFAULT NULL, `Name` varchar (255) DEFAULT NULL, `Password` varchar (255) DEFAULT NULL, `Role` varchar (255) DEFAULT NULL, `UTime` varchar (255) DEFAULT NULL, `UserID` varchar (255) DEFAULT NULL, `UserName` varchar (255) DEFAULT NULL, `UserStatus` int (11) DEFAULT NULL, PRIMARY KEY (`ID`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8 1 row in set (0.00 sec) mysql> show variables like 'datadir'; + --------------- + --------------------------------- -------------- + | Variable_name | Value | + --------------- + --------------------------------- -------------- + datadir | D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ | + --------------- + --------------------------------- -------------- + 1 row in set (0.00 sec)
Back up ibd files
C: \ Users \ XIFENFEI> dir D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei \ user_login.ibd The volume in drive D has no labels. The serial number of the volume is 4215-1F18 D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei 2016-12-02 20:07 98,304 user_login.ibd 1 file 98,304 bytes 0 directories 78,789,591,040 available bytes C: \ Users \ XIFENFEI> cp D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei \ user_login.ibd d: / C: \ Users \ XIFENFEI> dir d: \ user_login.ibd The volume in drive D has no labels. The serial number of the volume is 4215-1F18 d: \ directory 2016-12-25 23:15 98,304 user_login.ibd 1 file 98,304 bytes 0 directories 78,789,591,040 available bytes
Simulated delete table (ibd file is also deleted)
mysql> drop table xifenfei.user_login; Query OK, 0 rows affected (0.03 sec) C: \ Users \ XIFENFEI> dir D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei \ user_login.ibd The volume in drive D has no labels. The serial number of the volume is 4215-1F18 D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei File not found
Create a new table
mysql> CREATE TABLE `user_login` ( -> `ID` varchar (255) NOT NULL, -> `ACCOUNT` varchar (255) DEFAULT NULL, -> `LifeCycle` int (11) DEFAULT NULL, -> `Name` varchar (255) DEFAULT NULL, -> `Password` varchar (255) DEFAULT NULL, -> `Role` varchar (255) DEFAULT NULL, -> `UTime` varchar (255) DEFAULT NULL, -> `UserID` varchar (255) DEFAULT NULL, -> `UserName` varchar (255) DEFAULT NULL, -> `UserStatus` int (11) DEFAULT NULL, -> PRIMARY KEY (`ID`) ->) ENGINE = InnoDB DEFAULT CHARSET = utf8; Query OK, 0 rows affected (0.03 sec) C: \ Users \ XIFENFEI> dir D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei \ user_login.ibd The volume in drive D has no labels. The serial number of the volume is 4215-1F18 D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei 2016-12-25 23:19 98,304 user_login.ibd 1 file 98,304 bytes 0 directories 78,789,591,040 available bytes mysql> select count (*) from xifenfei.user_login; + ---------- + | count (*) | + ---------- + | 0 | + ---------- + 1 row in set (0.00 sec)
Stop mysql and replace user_login.ibd
C: \ Users \ XIFENFEI> dir D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei \ user_login.ibd The volume in drive D has no labels. The serial number of the volume is 4215-1F18 D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei 2016-12-25 23:22 98,304 user_login.ibd 1 file 98,304 bytes 0 directories 78,787,141,632 bytes available C: \ Users \ XIFENFEI> cp d: \ user_login.ibd D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei \ user_login.ibd C: \ Users \ XIFENFEI> dir D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei \ user_login.ibd The volume in drive D has no labels. The serial number of the volume is 4215-1F18 D: \ xifenfei \ mysql-5.6.25-winx64 \ data \ xifenfei 2016-12-02 20:07 98,304 user_login.ibd 1 file 98,304 bytes 0 directories 78,787,141,632 bytes available
Start the mysql service and query the database
mysql> select count (*) from xifenfei.user_login; ERROR 2013 (HY000): Lost connection to MySQL server during query mysql> exit Bye C: \ Users \ XIFENFEI> mysql -uroot ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)
mysql log error
2016-12-25 23:31:07 11632 [Note] MySQL: ready for connections. Version: '5.6.25' socket: '' port: 3306 MySQL Community Server (GPL) InnoDB: Error: tablespace id is 56 in the data dictionary InnoDB: but in file. \ Xifenfei \ user_login.ibd it is 47! 2016-12-25 23:31:31 2eb8 InnoDB: Assertion failure in thread 11960 in file fil0fil.cc line 796 InnoDB: We intentionally generate a memory trap. InnoDB: Submit a detailed bug report to http://bugs.mysql.com. InnoDB: If you get repeated assertion failures or crashes, even InnoDB: immediately after the mysqld startup, there may be
Obviously, because the replaced ibd file and the dictionary information of the page of the ibd file recorded in the database do not match, because the database cannot query the data normally, and mysql directly crashed the instance for security.
Resume operation
mysql> show variables like 'innodb_force_recovery'; + ----------------------- + ------- + | Variable_name | Value | + ----------------------- + ------- + | innodb_force_recovery | 1 | + ----------------------- + ------- + 1 row in set (0.00 sec) mysql> alter table xifenfei.user_login discard tablespace; Query OK, 0 rows affected, 2 warnings (0.02 sec) mysql> alter table xifenfei.user_login import tablespace; Query OK, 0 rows affected, 1 warning (0.06 sec) mysql> select count (*) from xifenfei.user_login; + ---------- + | count (*) | + ---------- + | 48 | + ---------- + 1 row in set (0.00 sec) mysql> select * from xifenfei.user_login limit 1; + ---------------------------------- + --------- + ---- ------- + ----------- + ---------- ------------------------ + ------ + ------------------ --- + -------------------------- -------- + ---------- + ------------ + | ID | ACCOUNT | LifeCycle | Name | Password | Role | UTime | UserID | UserName | UserStatus | + ---------------------------------- + --------- + ---- ------- + ----------- + ---------- ------------------------ + ------ + ------------------ --- + -------------------------- -------- + ---------- + ------------ + | 010d6c85a76c44cba80d07cbd8590bb2 | hyh | 0 | Hu Yuanhui | 698d51a19 d8a121ce581499d7b701668 | | 6 | | 2016-08-30 06:04:32 | 0fe3bc4dd9654687a4b85065e d5cfee8 | NULL | 1 | + ---------------------------------- + --------- + ---- ------- + ----------- + ---------- ------------------------ + ------ + ------------------ --- + -------------------------- -------- + ---------- + ------------ + 1 row in set (0.00 sec)
After the discard tablespace and import tablespace operations provided by mysql, the table data can be completed.
mysql log
2016-12-25 23:34:08 10464 [ERROR] InnoDB: Failed to find tablespace for table '"xifenfei". "User_login"' in the cache. Attempting to load the tablespace with space id 56. 2016-12-25 23:34:08 10464 [ERROR] InnoDB: In file '. \ Xifenfei \ user_login.ibd', tablespace id and flags are 47 and 0, but in the InnoDB data dictionary they are 56 and 0. Have you moved InnoDB .ibd files around without using the commands DISCARD TABLESPACE and IMPORT TABLESPACE? Please refer to http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting-datadict.html for how to resolve the issue. 2016-12-25 23:34:08 10464 [ERROR] InnoDB: Could not find a valid tablespace file for 'xifenfei / user_login'. See http://dev.mysql.com/doc/refman/5.6/en/innodb -troubleshooting-datadict.html for how to resolve the issue. 2016-12-25 23:34:08 30e8 InnoDB: cannot calculate statistics for table "xifenfei". "User_login" because the .ibd file is missing. For help, please refer to http://dev.mysql.com/doc /refman/5.6/en/innodb-troubleshooting.html 2016-12-25 23:34:08 10464 [ERROR] InnoDB: Cannot delete tablespace 56 because it is not found in the tablespace memory cache. 2016-12-25 23:34:08 10464 [Warning] InnoDB: Cannot delete tablespace 56 in DISCARD TABLESPACE. Tablespace not found 2016-12-25 23:34:41 10464 [Note] InnoDB: Sync to disk 2016-12-25 23:34:41 10464 [Note] InnoDB: Sync to disk-done! 2016-12-25 23:34:41 10464 [Note] InnoDB: Phase I-Update all pages 2016-12-25 23:34:41 10464 [Note] InnoDB: Sync to disk 2016-12-25 23:34:41 10464 [Note] InnoDB: Sync to disk-done! 2016-12-25 23:34:41 10464 [Warning] InnoDB: Tablespace 'xifenfei / user_login' exists in the cache with id 47! = 56 2016-12-25 23:34:41 10464 [Warning] InnoDB: Freeing existing tablespace 'xifenfei / user_login' entry from the cache with id 56 2016-12-25 23:34:41 10464 [Note] InnoDB: Phase III-Flush changes to disk 2016-12-25 23:34:41 10464 [Note] InnoDB: Phase IV-Flush complete
The mysql log still reports that the page dictionary information does not match. But the data is already accessible, you can re-create the table through mysqldump export. If this method cannot be restored due to ibd damage, please refer to: MySQL drop database recovery (the recovery method is also applicable to MySQL drop table, delete, truncate table)