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

MySQL ERROR 1017 (HY000): Can't find file: './"DatabaseName/Table.frm' (errno: 13)

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

假设我的数据库名称是 mydb,它有一个 table 叫做 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.

那我错过了什么?您复制哪些文件来备份数据库? 我知道 table 可以被几个 sql 语句复制但是我想学习一些已知的东西所以我正在试验。谢谢! :)

您必须复制 3 个文件:copy.frm copy.MYD copy.MYI
为文件、所有者和组设置权限
chown mysql.mysql 复制。*
chmod 660 副本。*
并刷新 mysql 中的表格:
mysql 数据库
mysql> 刷新表格;

瞧!

只是把这个作为答案:

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

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

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

create table new_table as select * from old_table

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

TL;DR

Copying/moving MySQL tables 在某些情况下可以通过改变底层文件来实现,但是不推荐.

总是使用MySQL命令来完成。


.frm 文件仅包含 table 定义。数据和索引存储在其他文件中,它们取决于 table.

的存储引擎

部分官方文档摘录:

MyISAM

15.2 The MyISAM Storage Engine

Each MyISAM table is stored on disk in three files. The files have names that begin with the table name and have an extension to indicate the file type. An .frm file stores the table format. The data file has an .MYD (MYData) extension. The index file has an .MYI (MYIndex) extension.

InnoDB

14.1 Introduction to InnoDB

By default, with the innodb_file_per_table setting enabled, each new InnoDB table and its associated indexes are stored in a separate file. When the innodb_file_per_table option is disabled, InnoDB stores all its tables and indexes in the single system tablespace, which may consist of several files (or raw disk partitions).

14.2.15.1 Role of the .frm File for InnoDB Tables

MySQL stores its data dictionary information for tables in .frm files in database directories. Unlike other MySQL storage engines, InnoDB also encodes information about the table in its own internal data dictionary inside the tablespace. When MySQL drops a table or a database, it deletes one or more .frm files as well as the corresponding entries inside the InnoDB data dictionary. You cannot move InnoDB tables between databases simply by moving the .frm files.

14.12 InnoDB Startup Options and System Variables

innodb_file_per_table

When innodb_file_per_table is enabled (the default in 5.6.6 and higher), InnoDB stores the data and indexes for each newly created table in a separate .ibd file, rather than in the system tablespace.

MySQL Glossary

system tablespace

One or more data files (ibdata files) containing the metadata for InnoDB-related objects (the data dictionary), and the storage areas for the undo log, the change buffer, and the doublewrite buffer. Depending on the setting of the innodb_file_per_table, when tables are created, it might also contain table and index data for some or all InnoDB tables. The data and metadata in the system tablespace apply to all the databases in a MySQL instance.

Prior to MySQL 5.6.7, the default was to keep all InnoDB tables and indexes inside the system tablespace, (...) In MySQL 5.6.7 and higher, the default is file-per-table mode, where each table and its associated indexes are stored in a separate .ibd file.

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

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

如果您要复制的 table 使用 MyISAM 引擎,那么您需要 copy/rename .frm.MYD.MYI 与 table.

同名的文件

如果 table 在创建时使用 InnoDB 引擎 innodb_file_per_table 设置为 ON 那么您需要 copy/rename 与 table.

同名的 .frm.ibd 文件

如果 table 使用 InnoDB 引擎并且它是在 innodb_file_per_table 设置为 OFF 时创建的,那么您 不能 从 MySQL.

外部复制或移动 table 数据

如果 table 使用 MEMORY table 那么复制 .frm 文件并重新启动服务器就足够了。 table 数据和索引存储在内存中,没有它们的文件并且服务器重启后源 table 将是空的,所以你得到空 table 的精确副本;-)

但是等等,还有更多!

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

还有更多

如果你想以这种方式破解的服务器是 replication cluster 的一部分,你所做的更改要么被忽略(如果你更改从属服务器,则不会传播到集群中的其他服务器)或中断复制(从属服务器需要查询和更新一个 table 它们没有,如果你改变主服务器)。

结论

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

复制 table 的正确(而且很多时候是唯一的)方法是使用 MySQL 提供的命令。

13.1.14 CREATE TABLE Syntax

Use LIKE to create an empty table based on the definition of another table, including any column attributes and indexes defined in the original table:

CREATE TABLE new_tbl LIKE orig_tbl;

The copy is created using the same version of the table storage format as the original table. The SELECT privilege is required on the original table.

然后您可以使用:

INSERT INTO `new_tbl` SELECT * FROM `orig_tbl`

复制数据。

另一种方式

另一种复制 table 而无需编写 SQL 命令的方法是使用 mysqldump, open the export file in a text editor, change the table name in all the places where it appears, save the file and import it into the database using the mysql command line tool(或其他 MySQL 导出 table 定义和数据客户)。