Linux / mysql:使用 cp 命令将 mysql db 文件从一个数据库复制到另一个数据库是否安全?

gio*_*o79 11 mysql linux shell copy

大多数指南推荐使用 mysqldump 和简单的 SQL 将一个表复制到另一个数据库。linux shell cp怎么样?我可以简单地做吗

cp /db1/mytable.frm /db2/mytable.frm

Rol*_*DBA 21

MyISAM 的复制非常简单,而 InnoDB 则完全有 100% 的风险(接近自杀)。

从你的问题中,你提出了

cp /db1/mytable.frm /db2/mytable.frm
Run Code Online (Sandbox Code Playgroud)

我的ISAM

这样做是可以的。但是,您不能只移动 .frm。您必须移动所有组件。根据您的问题,让我们以一个名为 db1.mytable 的表为例。在正常安装中,该表位于 /var/lib/mysql/db1。将有三个文件组成该表。

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.MYD(表数据库)
  • /var/lib/mysql/db1/mytable.MYI(表索引)

您必须移动所有三个文件才能移动一张表。如果所有表都使用 MyISAM 存储引擎,则可以关闭 mysql 并复制。如果您只是简单地制作该表的副本并将其放入另一个数据库中,则应该使用 SQL 来执行此操作。

例如,如果要将 db1.mytable 复制到数据库 db2,请执行以下操作:

CREATE TABLE db2.mytable LIKE db1.mytable;
ALTER TABLE db2.mytable DISABLE KEYS;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;
ALTER TABLE db2.mytable ENABLE KEYS;
Run Code Online (Sandbox Code Playgroud)

现在,如果您只是将表从 db1 移动到 db2,您可以这样做:

ALTER TABLE db1.mytable RENAME db2.mytable;
Run Code Online (Sandbox Code Playgroud)

数据库

由于 InnoDB 在其下工作的基础架构,复制非常危险。有两个基本的基础设施:1) innodb_file_per_table 禁用和 2) innodb_file_per_table 启用

InnoDB 的致命弱点是系统表空间文件 ibdata1(通常位于 /var/lib/mysql)。该文件中包含什么

  • 表数据页
  • 表索引页
  • Table MetaData(表空间id管理列表)
  • MVCC数据(支持事务隔离和ACID 合规性

InnoDB(禁用 innodb_file_per_table)

禁用 innodb_file_per_table 后,所有这些类型的 InnoDB 信息都位于 ibdata1 中。ibdata1 之外的任何 InnoDB 表的唯一表现形式是 InnoDB 表的 .frm 文件。一次复制所有 InnoDB 数据需要复制所有 /var/lib/mysql。

复制单个 InnoDB 表是完全不可能的。您必须 mysqldump 提取表的转储作为数据及其相应索引定义的逻辑表示。然后,您将该转储加载到同一服务器或另一台服务器上的另一个数据库。

InnoDB(启用 innodb_file_per_table)

启用 innodb_file_per_table 后,表数据及其索引位于 .frm 文件旁边的数据库文件夹中。例如,对于表 db1.mytable,该 InnoDB 表在 ibdata1 之外的表现形式为:

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.ibd

db1.mytable 的所有元数据仍然驻留在 ibdata1 中,绝对没有办法解决这个问题。重做日志和 MVCC 数据也仍然存在于 ibdata1 中。

警告(或机器人在《迷失太空》中所说的危险)

如果您只想复制 .frm 和 .ibd 文件,那么您将面临痛苦的世界。复制 InnoDB 表的 .frm 和 .ibd 文件只有在您可以保证 .ibd 文件的表空间 id 与 ibdata1 文件的元数据中的表空间 id 条目完全匹配的情况下才是好的。

我在 DBA StackExchange 中写了两篇关于这个表空间 ID 概念的文章

这是关于如何在表空间 ID 不匹配的情况下将 .ibd 文件重新附加到 ibdata1 的优秀链接:http : //www.chriscalender.com/ ? tag=innodb-error-tablespace-id-in-file 。读完这篇,你应该能明白我为什么说近乎自杀了。

对于 InnoDB,您只需要这样做

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;
Run Code Online (Sandbox Code Playgroud)

制作 InnoDB 表的副本。如果要将其迁移到另一个数据库服务器,请使用 mysqldump。

  • 其他的回答是这样说的,所以也许它“不言而喻”,但无论如何说得很好:即使数据库空闲,InnoDB 也会继续写入文件,因此在 MySQL 运行时复制其文件几乎肯定会导致损坏!您可以关闭、获取文件系统快照或使用 Percona XtraBackup 来解决此问题。 (4认同)

Coo*_*ops 8

复制整个 MySQL 数据目录是一种实用的技术,假设 MySQL 服务已停止并且您希望复制整个数据库服务器。

这是移动具有大索引的数据库的有用技术,并且 mysql 转储将不包括索引,需要在导入时重新生成索引。我发现这种技术在设置 MySQL 从站时很有用。

复制单个文件取决于使用的表模式,但在大多数情况下不是合适的解决方案。

  • 说明:您不必停止服务本身,如果您的文件系统有能力,您可以执行 LVM 快照并从中备份;或冻结文件系统本身。 (2认同)