如何仅使用ibdata和* .ibd文件为MySQL InnoDB表重新创建FRM文件?

时间:2011-07-24 01:22:01

标签: mysql database innodb restore database-restore

这与我在stackoverflow上看到的相关InnoDB修复问题略有不同。

假设我已经使用innodb_file_per_table = 1恢复了MySQL 5.1数据库中的以下内容:

db/tablename.ibd
innodb/ibdata1
innodb/ib_logfile0
innodb/ib_logfile1

我丢失了db/tablename.frm文件。我可以启动数据库服务器,但InnoDB抱怨:

110723 13:26:33  InnoDB: Error: table 'db/tablename'
InnoDB: in InnoDB data dictionary has tablespace id 5943,
InnoDB: but tablespace with that id or name does not exist. Have
InnoDB: you deleted or moved .ibd files?

如何重建FRM文件?

2 个答案:

答案 0 :(得分:3)

我自己想出了一个解决方案。

简单的解决方案是找到保存的CREATE TABLE SQL副本,在开发实例上运行它,然后将生成的FRM文件复制到已恢复的实例。

但是,在我的情况下,我没有CREATE TABLE命令的副本。

您可以使用ibdata,ib_logfiles和* .ibd文件运行MySQL服务器。但是,如果没有FRM,数据库中似乎没有表格。

  1. 在已还原的数据库中,运行create table innodb_table_monitor (a int) ENGINE=InnoDB
  2. 观察MySQL服务器错误文件,直到表监视器数据被转储(通常大约一分钟)
  3. 运行drop table innodb_table_monitor
  4. 停止已恢复的数据库

  5. 编写SQL以匹配表监视器输出,例如:

    TABLE: name db/mylosttable, id 0 7872, flags 1, columns 5, indexes 1, appr.rows 1828
    COLUMNS: id: DATA_MYSQL DATA_NOT_NULL len 12; name: type 12 DATA_NOT_NULL len 45;     
    DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; 
    DB_ROLL_PTR: DATA_SYS prtype 258 len 7;
    INDEX: name GEN_CLUST_INDEX, id 0 17508, fields 0/5, uniq 1, type 1
    root page 3, appr.key vals 1828, leaf pages 9, size pages 10
    FIELDS:  DB_ROW_ID DB_TRX_ID DB_ROLL_PTR id name
    

    可表示为:

    drop table if exists mylosttable;
    create table mylosttable (
        id char(12) NOT NULL,
        name varchar(45) NOT NULL
    );
    

    如果您对表监视器输出感到困惑,请查看具有已知模式的表的输出。

  6. 在MySQL的开发实例

  7. 上运行上述SQL
  8. 将在开发服务器中创建的FRM文件复制到已还原的数据库。您可以在相应数据库的子目录中的MySQL数据目录中找到它们。

  9. 重新启动已恢复的数据库

    注意您可以将FRM文件复制到实时数据库实例中。上面停止服务器的原因是,如果在创建innodb_table_monitor表之后使数据库崩溃,它将使ibdata文件处于不一致状态,并且你必须从备份开始。

  10. 使用select *语句测试表是否有效。如果你错了,你会看到:

    ERROR 2013 (HY000): Lost connection to MySQL server during query
    
  11. 表示数据库已崩溃。

    如果发生这种情况,请在dev实例上执行create table innodb_table_monitor...,并将输出与已还原实例的原始输出进行比较。你可能会看到你错过了一个NOT NULL或类似的东西。

答案 1 :(得分:3)

编辑:我创建了一个简单的脚本,执行下面描述的所有步骤:https://ourstickys.com/recover.sh

旧问题,但我发现这种更简单的方法:https://dba.stackexchange.com/questions/16875/restore-table-from-frm-and-ibd-file

I have recovered my MySQL 5.5 *.ibd and *.frm files with using MySQL Utilites and MariaDB 10.

1) Generating Create SQLs.
You can get your create sql's from frm file. You must use : https://dev.mysql.com/doc/mysql-utilities/1.5/en/mysqlfrm.html

shell> mysqlfrm --server=root:pass@localhost:3306 c:\MY\t1.frm --port=3310

Other way you may have your create sql's.

2) Create Your Tables
Create your tables on the database.

3) alter table xxx discard tablespace
Discard your tables which do you want to replace your *.ibd files.

4) Copy your *.ibd files (MySQL Or MariaDB) to MariaDB's data path
First i try to use MySQL 5.5 and 5.6 to restrore, but database crashes and immediately stops about tablespace id broken error. (ERROR 1030 (HY000): Got error -1 from storage engine) 
After i have used MariaDB 10.1.8, and i have succesfully recovered my data.

5) alter table xxx import tablespace
When you run this statement, MariaDB warns about file but its not important than to recover your data :) Database still continues and you can see your data.

I hope this information will helpful for you.

让我补充一点,你可以在这里下载mysqlfrm:https://dev.mysql.com/downloads/utilities/

我还发现了使用CREATE TABLE获得dbsake的更快捷方式:

curl -s http://get.dbsake.net > dbsake
chmod u+x dbsake

然后:

#only one table
./dbsake frmdump /path/to/table.frm > recover.sql

#multiple tables
./dbsake frmdump /path/to/*.frm > recover.sql

接下来是:

mysql -uUSER -p recover_db < recover.sql

如果您愿意,也可以在单行中执行:

./dbsake frmdump /path/to/*.frm | mysql -uUSER -p recover_db

此时您可以按照上述第3点的说明进行操作。

相关问题