MySQL ERROR 1017(HY000):找不到文件:'./"DatabaseName/Table.frm'(错误号码:13)

时间:2015-04-11 06:58:41

标签: mysql database database-backups

您是否可以通过简单地复制.frm文件来创建表的副本? 我打算做这样的事情:

假设我的数据库名称是mydb,它有一个名为mytab的表。 浏览到文件系统中名为mydb的文件夹,它有一个mytab.frm文件。 然后将mytab.frm的内容复制到名为copy.frm的文件中 然后我登录到mysql并运行以下命令:

use mydb;  //Selects the database mydb
show tables; //To see the list of tables. I can see the table named copy.
select * from copy; //This throws the error mentioned in the title.

那我错过了什么?您复制哪些文件来备份数据库? 我知道这个表可以通过几个sql语句复制但是我想知道一些事情,所以我正在试验。谢谢! :)

3 个答案:

答案 0 :(得分:3)

把它扔掉作为答案:

你不能做你为InnoDB表所做的尝试。 InnoDB将所有表数据存储在一个文件中 - ibdata。您可以使用my.cnf中的innodb_file_per_table设置对其进行修改,但它不具有追溯力,只适用于新表。即使你有每个表设置文件,你仍然不应该尝试只复制数据文件,因为innodb可能没有刷新从ib_logfile到ibdata / .ibd文件的所有更改,所以你最终可能会损坏数据。

您可以为MyISAM表执行此操作但不应该(并且还有其他文件也要复制,因为.FRM只是表定义。.MYD文件包含数据和.MYI文件包含索引)。为什么?因为您将数据委托给数据库,所以您应该使用数据库工具来复制它。您应该直接触摸数据文件的唯一时间是在数据恢复期间,并且仅在服务器未运行时 - 您不希望在写入文件时复制这些文件。

要复制表格,只需执行以下操作:

create table new_table as select * from old_table

要备份整个数据库,请使用mysqldump或其他可用备份工具之一。

答案 1 :(得分:3)

TL; DR

在某些情况下,可以通过更改基础文件来复制/移动MySQL表,但它非常未经推荐

始终使用MySQL命令来执行此操作。


.frm文件仅包含表定义。数据和索引存储在其他文件中,它们依赖于表的存储引擎。

官方文件摘录:

MyISAM

  

15.2 The MyISAM Storage Engine

     

每个MyISAM表都存储在三个文件的磁盘上。这些文件的名称以表名开头,并具有指示文件类型的扩展名。 .frm文件存储表格格式。数据文件具有.MYD(MYData)扩展名。索引文件的扩展名为.MYI(MYIndex)。

InnoDB

  

14.1 Introduction to InnoDB

     

默认情况下,启用innodb_file_per_table设置后,每个新InnoDB表及其关联的索引都存储在单独的文件中。禁用innodb_file_per_table选项后,InnoDB将其所有表和索引存储在单个系统表空间中,该表空间可能包含多个文件(或原始磁盘分区)。

     

14.2.15.1 Role of the .frm File for InnoDB Tables

     

MySQL将数据字典信息存储在数据库目录中的.frm文件中。与其他MySQL存储引擎不同,InnoDB还在表空间内的自己的内部数据字典中对表的信息进行编码。当MySQL删除表或数据库时,它会删除一个或多个.frm文件以及InnoDB数据字典中的相应条目。只需移动InnoDB文件,就无法在数据库之间移动 .frm表。

  

14.12 InnoDB Startup Options and System Variables

     

innodb_file_per_table

     

启用innodb_file_per_table时(5.6.6及更高版本中的默认值),InnoDB将每个新创建的表的数据和索引存储在单独的.ibd文件中,而不是system tablespace

  

MySQL Glossary

     

system tablespace

     

一个或多个数据文件(ibdata文件),包含与InnoDB相关的对象(数据字典)的元数据,以及撤消日志,更改缓冲区和双写缓冲区的存储区域。根据{{​​1}}的设置,在创建表时,它还可能包含部分或全部innodb_file_per_table表的表和索引数据。系统表空间中的数据和元数据适用于MySQL实例中的所有数据库。

     

在MySQL 5.6.7之前,默认是将所有InnoDB表和索引保留在系统表空间内,(...)在MySQL 5.6.7及更高版本中,默认为InnoDB模式,其中每个表及其关联的索引存储在单独的file-per-table文件中。

让我们得出一些(部分)结论

在其他任何事情之前你必须停止MySQL服务器(以确保所有数据都安全地存储到文件中)。

如果要复制的表使用.ibd引擎,则需要复制/重命名与MyISAM.frm.MYD文件同名的文件。表

如果该表在创建时使用.MYI引擎,则InnoDB设置为innodb_file_per_table,那么您需要复制/重命名ON.frm个文件与表格名称相同。

如果该表使用了.ibd引擎并且在InnoDB设置为innodb_file_per_table时创建了该表,那么您无法从外部复制或移动表格数据的MySQL。

如果表使用OFF表,则它足以复制MEMORY文件并重新启动服务器。表数据和索引存储在内存中,没有文件,服务器重启后源表将为空,因此您可以获得空表的精确副本; - )

但等等,还有更多!

MySQL实现的几个other storage engines可能比上面提到的少用replication cluster。他们每个人都有自己的数据存储规则。

还有更多

如果要以这种方式破解的服务器是13.1.14 CREATE TABLE Syntax的一部分,您所做的更改将被忽略(如果更改从属服务器,则不会传播到群集中的其他服务器)或中断复制(如果更改主服务器,则从属服务器需要查询和更新他们不具备的表。)

结论

即使在某些情况下,可以通过更改下划线文件来复制或移动表格,但强烈不推荐

复制表的正确方法(也是唯一的方法)是使用MySQL提供的命令。

  

SELECT privilege

     

使用.frm根据另一个表的定义创建一个空表,包括原始表中定义的所有列属性和索引:

     

LIKE

     

使用与原始表相同版本的表存储格式创建副本。原始表格中需要mysqldump

然后您可以使用:

CREATE TABLE new_tbl LIKE orig_tbl;

复制数据。

另一种方式

在不编写SQL命令的情况下复制表的另一种方法是使用mysql command line tool导出表定义和数据,在文本编辑器中打开导出文件,在出现的所有位置更改表名,使用{{3}}(或其他INSERT INTO `new_tbl` SELECT * FROM `orig_tbl` 客户端)保存文件并将其导入数据库。

答案 2 :(得分:-1)

您必须复制3个文件:copy.frm copy.MYD copy.MYI
为文件,所有者和组创建权限  chown mysql.mysql copy。*
 chmod 660 copy。*
并在mysql中刷新表:
 mysql数据库
MySQL的>冲洗表;

瞧!