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


11

大多数指南建议使用mysqldump和简单SQL将一个表复制到注释数据库。linux shell cp怎么样?我可以简单地做

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

Answers:


21

对于MyISAM,复制非常简单,并且使用InnoDB完全具有100%的风险(接近自杀)。

从您的问题中,您长大了

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

我的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;

现在,如果只是将表从db1移动到db2,则可以执行以下操作:

ALTER TABLE db1.mytable RENAME db2.mytable;

创新数据库

由于InnoDB使用的基础架构,因此复制非常危险。有两种基本基础架构:1)禁用innodb_file_per_table和2)启用innodb_file_per_table

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

  • 表格数据页
  • 表索引页
  • 表元数据(表空间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文件,那么您很容易受到伤害。仅当您可以确保.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 。读完这篇文章后,您应该就能明白我为什么要自杀了。

对于InnoDB,您只需要这样做

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

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


4
其他回应是这样说的,所以也许它“不言而喻”,但是无论如何还是要说:InnoDB会继续写入文件,即使数据库处于空闲状态,因此在MySQL运行时复制其文件几乎肯定会导致损坏!您可以关闭文件系统快照或使用Percona XtraBackup解决此问题。
Schwartz男爵

1
一如既往的出色答案,@ Rolando!我唯一的大问题是:为什么有人要这样做而不是直接进行MySQL转储和导入?我假设数据库的大小很大,但是应该提高它的大小。
JakeGould 2014年

1
@JakeGould将mysqldump脚本加载到mysql中需要处理大量SQL,一次插入数千行,使用CPU周期,制定说明计划,重建索引(BTree插入,叶节点拆分,重新平衡键,针对每个非表的表扫描-唯一生成)只是为了产生相同的表。对于MyISAM,为什么要重新发明轮子呢?只是副本.frm.MYD.MYI
RolandoMySQLDBA 2014年

@JakeGould对于InnoDB,我已经复制了一个实时数据库,该数据库使用了所有具有rsync的InnoDB。使用rsync复制后,我关闭了mysql,执行了最终的rsync,然后重新启动mysql,没有出现问题。我写了一篇文章像以前一样:serverfault.com/questions/288140/...
RolandoMySQLDBA

8

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

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

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


2
阐述一下:您不必停止服务本身,如果您的文件系统有能力,则可以执行LVM快照并备份该快照。或冻结文件系统本身。
Thinice 2012年

只要个人可以在停机时间吃饭,这是最简单的方法。+1 !!!
RolandoMySQLDBA 2012年

2

使用带innobackupex包装器的xtrabackup,可以同时使用myisam和innodb数据库。请注意,即使使用xtrabackup,还原innodb数据库也不只是将文件复制回来。告诉您是否需要更多信息


1

不,您应该使用mysqdump进行备份,并使用mysql cli实用程序进行还原,复制frm文件仅复制表结构,而不复制内部数据,如果在innodb上,则不能直接复制该文件。

最好的方法是转储并还原表。

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.