从.frm和.ibd文件还原表?


36

我以前已经保存了/ var / lib / mysql / ddms目录的副本(“ ddms”是架构名称)。现在,我通过运行在新安装的Ubuntu 10.04.3 LTS上安装了新的MySQL apt-get install mysql-server,我相信已经安装了5.1版。在/ var / lib / mysql下复制ddms目录后,它的某些表可以正常工作,这些表具有三个文件的关联集:.frm文件,.MYD文件和.MYI文件。

但是,有两个表具有不同的文件集:.frm文件和.ibd文件。这两个表未显示在phpMyAdmin的表列表中。当我查看错误日志时,它说:

[ERROR] Cannot find or open table ddms/dictionary_item from
the internal data dictionary of InnoDB though the .frm file for the
table exists. Maybe you have deleted and recreated InnoDB data
files but have forgotten to delete the corresponding .frm files
of InnoDB tables, or you have moved .frm files to another database?
or, the table contains indexes that this version of the engine
doesn't support.

请帮助恢复这两个表。谢谢。


Rolando在12月4月23日的报价今天仍然有效。“只是将.frm和.ibd文件从一个位置复制到另一个位置就很麻烦。” 使用mysqldump这样的替代方法,可以将旧数据转换成可以按计划在几年前加载的表格。也称为备份。
威尔逊·豪克

Answers:


37

不能像MyISAM表一样复制InnoDB表。

只是将.frm和.ibd文件从一个位置复制到另一个位置会带来麻烦。仅当且仅当您可以保证.ibd文件的表空间ID与ibdata1文件的metdata中的表空间ID项完全匹配时,才可以复制InnoDB表的.frm和.ibd 文件

我在DBA StackExchange中写了两篇有关此表空间ID概念的文章

这是有关在表空间ID不匹配的情况下如何将任何.ibd文件重新附加到ibdata1的绝佳链接:http : //www.chriscalender.com/ ? tag=innodb-error-tablespace-id-in-file 。读完这篇文章后,您应该立即意识到复制.ibd文件简直是疯狂。

您可以应用Chris Calendar链接中的建议,也可以返回mysql的旧版本,启动mysql,然后mysqldump ddms数据库。然后,将该mysqldump导入新的mysql实例。相信我,这会容易得多。


因此,单个表可能不是一个好主意,但是那时整个数据库又如何呢?我的用户表崩溃严重,我必须在mysqld上执行--initialize。我可以从data_backup文件夹复制整个InoDB数据库文件夹吗?
FMaz008

罗兰多,万一你能帮助我:serverfault.com/q/908988/224334
尼卡比曹

您的帖子从How to Recover an InnoDB table whose files were moved around 字面上救了我一命。非常感谢你。
Paulo Griiettner

20

我最近遇到了同样的问题。这是我用来解决此问题的步骤,而不必像上面的RolandoMySQLDBA所提到的那样弄乱表空间ID。我在Mac上,因此我使用MAMP来将数据库还原到可以在MySQL转储中导出的位置。

您可以在此处阅读有关此内容的完整博客文章:http : //www.quora.com/Jordan-Ryan/Web-Dev/How-to-Recover-innoDB-MySQL-files-using-MAMP-on-a-Mac

你必须有:

-ibdata1

-ib_logfile0

-ib_logfile1

mysql_database文件夹中的-.FRM文件

-您愿意销毁的MAMP / MAMP Pro的最新安装(如果需要)

  1. SSH进入您的Web服务器(开发,生产,没有区别)并浏览到mysql文件夹(我的文件位于/ var / lib / mysql上,用于Linux上的Plesk安装)
  2. 压缩mysql文件夹
  3. 下载mysql文件夹的归档文件,其中应包含所有mySQL数据库,无论是MyISAM还是innoDB(如果需要,您可以将其保存为scp,或将其移动到可下载的目录中)
  4. 安装MAMP(Mac,Apache,MySQL,PHP)
  5. 浏览到/ Applications / MAMP / db / mysql /
  6. 将/ Applications / MAMP / db / mysql备份到zip存档中(以防万一)
  7. 从生产服务器(在我的情况下为mt Plesk环境)中复制mysql文件夹的归档中包含的所有文件夹和文件,但请不要覆盖:

    -/应用程序/ MAMP / db / mysql / mysql /

    -/应用程序/ MAMP / db / mysql / mysql_upgrade_info

    -/应用程序/ MAMP / db / mysql / performance_schema

  8. 瞧,您现在应该可以从phpMyAdmin访问数据库了,真是太好了!

但是我们还没有完成,现在您需要执行mysqldump才能将这些文件还原到生产环境中,并且大型数据库的phpmyadmin接口超时。请按照以下步骤操作:

http://nickhardeman.com/308/export-import-large-database-using-mamp-with-terminal/

复制以下,以供参考。请注意,在默认的MAMP安装中,密码为“ root”。

如何使用终端为MAMP运行mysqldump

从MAMP导出数据库[1]

第一步: 打开一个新的终端窗口

第二步: 在终端cd / applications / MAMP / library / bin中输入以下行,导航到MAMP安装按下回车键

第三步: 编写转储命令./mysqldump -u [USERNAME] -p [DATA_BASENAME]> [PATH_TO_FILE]按下回车键

例:

./mysqldump -u root -p wp_database > /Applications/MAMP/htdocs/symposium10_wp/wp_db_onezero.sql

快速提示:要快速导航到文件夹,您可以将文件夹拖到终端窗口中,它将写入文件夹的位置。那天是很高兴有人向我展示的。

第四步: 在您按回车键后应显示以下文本行输入密码:因此,请猜测,输入密码,请记住,字母不会出现,但它们仍然存在。按Enter键

第五步: 检查文件的存储位置(如果存在)SUCCESS现在,您可以导入数据库,接下来将对其进行概述。

现在,您已经导出了mysql数据库,您可以在生产环境中将其导入。


1
截至2018年仍在工作。答案是金。对我来说重要的部分是#7,这些文件是您绝对必须保留的文件(类似解决方案在其他任何地方均未提及,感谢@jordan)。
Bigood

@Bigood很高兴它仍然在帮助您!
jordan8037310

转储时不存在错误1146表
Robert Sinclair

15

我已经使用MySQL Utilites和MariaDB 10恢复了MySQL 5.5 * .ibd和* .frm文件。

1)生成创建SQL。
您可以从frm文件中获取创建sql。您必须使用: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

您可能以其他方式创建sql。

2)创建
表在数据库上创建表。

3)alter table xxx丢弃表空间
丢弃要替换* .ibd文件的表。

4)将您的* .ibd文件(MySQL或MariaDB)复制到MariaDB的数据路径中。
首先,我尝试使用MySQL 5.5和5.6进行还原,但是数据库崩溃并立即因表空间ID损坏错误而停止。(错误1030(HY000):从存储引擎收到错误-1
在使用MariaDB 10.1.8之后,我成功恢复了数据。

5)alter table xxx import tablespace
运行此语句时,MariaDB警告文件,但它并不重要于恢复数据:)数据库仍在继续,您可以看到您的数据。

希望这些信息对您有所帮助。


1
这对我有用。尽管mysqlfrmCREATE使用MySQL 5.6和5.7的1.3.5和1.6.5版本)没有给出正确的定义,即使使用MySQL 5.7(MySQL 5.7.9中的默认ROW_FORMAT更改)也导致了Schema mismatch (Expected FSP_SPACE_FLAGS=0x21, .ibd file contains 0x0.)导入表空间时的错误。ROW_FORMAT=compactCREATE语句末尾手动添加即可达到目的。
贾尼斯·埃默里斯(JānisElmeris)'17年

@JānisElmeris> Manually adding ROW_FORMAT=compact at the end of the CREATE statement did the trick.这对我也有用。谢谢!👍
Synetech

3

我有完全相同的问题,只有文件作为备份。

我要做的是将数据库文件复制到/ var / lib / mysql / yourdb中,并将ibdata1复制到/ var / lib / mysql中。

然后,我能够验证是否可以访问表 mysql -u root -p dbname并查询先前已损坏的某些表。

之后,我使用mysqldump -u root -p [root_password] [database_name]> dumpfilename.sql对数据库进行了转储


2

如果您使用的是MAMP,则在复制完文件后无法启动MySQL,我将其innodb_force_recovery = 2放进去my.ini,然后便能够使mysql启动并导出数据库。


1

如果您能够将* .ibd文件恢复到原始MySQL服务器,请不要忘记恢复文件访问权限。就我而言(在CentOS7上为MySQL8),我将文件还原到/var/lib/mysql/db/tablename.ibd并运行:

chown mysql tablename.ibd
chgrp mysql tablename.ibd
chmod 0640 tablename.ibd

在修复访问权限之前,访问该表会导致错误“ 2006 MySQL服务器已消失”。修复访问权限后,该表起作用(即使不重新启动mysqld服务)。


0

我从类似的主题中收集了帖子(未在此处发布答案):

解决方案1:https : //dba.stackexchange.com/a/59978

解决方案2:https : //dba.stackexchange.com/a/71785(+其他帖子在那里)

解决方案3:表恢复工具包:https : //twindb.com/how-to-recover-innodb-dictionary/

解决方案4:从没有ibdata1的ibd文件的数据文件夹中恢复MySQL数据库

解决方案5:使用mysqlfrm命令

解决方案6:https : //dba.stackexchange.com/a/159001

解决方案7:https : //dba.stackexchange.com/a/144573


这看起来可疑地像仅链接的答案。
mustaccio

因为所有链接都来自我们自己的站点,所以它们不太可能消失,所以我对@mustaccio没问题
jcolebrand

3
这似乎并没有增加太多价值,因为其中大多数也出现在“相关”列表的右侧,只有几个像素。
mustaccio

@jcolebrand感谢您的开明。许多人甚至看不到这种“非直接”答案的用处。他们只能检测规则的突破。
T.Todua

1
不,但您必须了解他是对的。您没有添加任何值。我以规则判断作为回应,而不是纵容您的回答。这实际上是一个非常糟糕的答案。
jcolebrand

0

我只想为macOS El Capitan用户添加一件事。该版本不支持MySQL实用程序,因此mysqlfrm命令没有帮助。我所做的是使用dbsake恢复表结构,如以下链接所示:https ://www.percona.com/blog/2015/12/16/recovering-table-structure-from-frm-files-using-dbsake/

您需要做的就是安装dbsake:

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

然后使用frmdump命令并提供.frm文件的路径:

# ./dbsake frmdump /var/lib/mysql/sakila/staff.frm

您将获得create语句。完成此操作后,我只需遵循@Ecd已经提到的步骤2至5。希望它可以帮助某人。


0

我非常感谢Ecd。对我有用的是:

1.-几个月前,我对基准进行了备份,这有助于我在Windows 10的xampp中取消此备份,并创建具有以下结构的表 (配置:Windows 10,xampp-windows-x64-7.1.30- 5-VC14)mysql my.ini配置文件结尾

NOTE: Some tables did not have ROW_FORMAT = COMPACT, so I went to operations on each 
    table and changed it manually.
    (If I did not do that, an error appeared and I did not let the import).

NOTE2: I had the backup of months ago but it should also work by first recovering 
    the structure of the .frm files in case of not having a backup at hand.
    (You can try this link:
    https://www.percona.com/blog/2014/01/02/recover-table-structure-frm-files-mysql- 
    utilities/)

2.-建立了旧数据库后,我继续对要恢复的数据库中的每个表执行alter table xxx丢弃表空间,然后在C:/ xampp / mysql / data / system中选择数据文件夹的.ibd文件已被删除(在这种情况下,这是此路径)

3.-我将要恢复的数据库中的.ibd文件复制到旧数据库的xampp文件夹中

4.-复制文件后,运行:alter table xxx import tablespace对于数据库中的每个表,都会出现警告,但是我们将忽略它,数据将被加载到表中,以后可以导出。

5.-将整个数据库导出到一个sql文件中,并在生产和成功中继续进行构建!

# Example MySQL config file for small systems.
#
# This is for a system with little memory (<= 64M) where MySQL is only used
# from time to time and it's important that the mysqld daemon
# doesn't use much resources.
#
# You can copy this file to
# C:/xampp/mysql/bin/my.cnf to set global options,
# mysql-data-dir/my.cnf to set server-specific options (in this
# installation this directory is C:/xampp/mysql/data) or
# ~/.my.cnf to set user-specific options.
#
# In this file, you can use all long options that a program supports.
# If you want to know which options a program supports, run the program
# with the "--help" option.

# The following options will be passed to all MySQL clients
[client] 
# password       = your_password 
port            = 3306 
socket          = "C:/xampp/mysql/mysql.sock"


# Here follows entries for some specific programs 

# The MySQL server
[mysqld]
port= 3306
socket = "C:/xampp/mysql/mysql.sock"
basedir = "C:/xampp/mysql" 
tmpdir = "C:/xampp/tmp" 
datadir = "C:/xampp/mysql/data"
pid_file = "mysql.pid"
# enable-named-pipe
key_buffer = 160M
max_allowed_packet = 300M
sort_buffer_size = 1204K
net_buffer_length = 80K
read_buffer_size = 512K
read_rnd_buffer_size = 1024K
myisam_sort_buffer_size = 8M
log_error = "mysql_error.log"

# Change here for bind listening
# bind-address="127.0.0.1" 
# bind-address = ::1          # for ipv6

# Where do all the plugins live
plugin_dir = "C:/xampp/mysql/lib/plugin/" 

# Don't listen on a TCP/IP port at all. This can be a security enhancement,
# if all processes that need to connect to mysqld run on the same host.
# All interaction with mysqld must be made via Unix sockets or named pipes.
# Note that using this option without enabling named pipes on Windows
# (via the "enable-named-pipe" option) will render mysqld useless!
# 
# commented in by lampp security
#skip-networking
#skip-federated

# Replication Master Server (default)
# binary logging is required for replication
# log-bin deactivated by default since XAMPP 1.4.11
#log-bin=mysql-bin

# required unique id between 1 and 2^32 - 1
# defaults to 1 if master-host is not set
# but will not function as a master if omitted
server-id   = 1

# Replication Slave (comment out master section to use this)
#
# To configure this host as a replication slave, you can choose between
# two methods :
#
# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
#    the syntax is:
#
#    CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
#    MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
#
#    where you replace <host>, <user>, <password> by quoted strings and
#    <port> by the master's port number (3306 by default).
#
#    Example:
#
#    CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
#    MASTER_USER='joe', MASTER_PASSWORD='secret';
#
# OR
#
# 2) Set the variables below. However, in case you choose this method, then
#    start replication for the first time (even unsuccessfully, for example
#    if you mistyped the password in master-password and the slave fails to
#    connect), the slave will create a master.info file, and any later
#    change in this file to the variables' values below will be ignored and
#    overridden by the content of the master.info file, unless you shutdown
#    the slave server, delete master.info and restart the slaver server.
#    For that reason, you may want to leave the lines below untouched
#    (commented) and instead use CHANGE MASTER TO (see above)
#
# required unique id between 2 and 2^32 - 1
# (and different from the master)
# defaults to 2 if master-host is set
# but will not function as a slave if omitted
#server-id       = 2
#
# The replication master for this slave - required
#master-host     =   <hostname>
#
# The username the slave will use for authentication when connecting
# to the master - required
#master-user     =   <username>
#
# The password the slave will authenticate with when connecting to
# the master - required
#master-password =   <password>
#
# The port the master is listening on.
# optional - defaults to 3306
#master-port     =  <port>
#
# binary logging - not required for slaves, but recommended
#log-bin=mysql-bin


# Point the following paths to different dedicated disks
#tmpdir = "C:/xampp/tmp"
#log-update = /path-to-dedicated-directory/hostname

# Uncomment the following if you are using BDB tables
#bdb_cache_size = 40M
#bdb_max_lock = 10000

# Comment the following if you are using InnoDB tables
#skip-innodb
innodb_data_home_dir = "C:/xampp/mysql/data"
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = "C:/xampp/mysql/data"
#innodb_log_arch_dir = "C:/xampp/mysql/data"
## You can set .._buffer_pool_size up to 50 - 80 %
## of RAM but beware of setting memory usage too high
innodb_buffer_pool_size = 16M
## Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 50M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 600

## UTF 8 Settings
#init-connect=\'SET NAMES utf8\'
#collation_server=utf8_unicode_ci
#character_set_server=utf8
#skip-character-set-client-handshake
#character_sets-dir="C:/xampp/mysql/share/charsets"
sql_mode=NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION
log_bin_trust_function_creators = 1

[mysqldump]
quick
max_allowed_packet = 160M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[isamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M

[myisamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

希望对有这种情况的人有所帮助。

Google提供的英语


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.