如何将数据库从一台服务器移到另一台服务器?


136

如何将MySQL表从一台物理服务器移动到另一台物理服务器?

像这样的精确场景: 我有一个使用innodb表的MySQL服务器,大小约为20GB。

我想将其移至新服务器,最有效的方法是什么?


4
我会用xtrabackup percona.com/docs/wiki/...它很像复制过来,但你可以保持服务器上运行,并假设你主要使用InnoDB表(你说你),你可以认为这是一个“热”备份。
乔纳森

我不能从使用此工具的其他人中受益。它是免费的/开源的,即使它是由一家公司制造的,使用起来也很容易,您无需考虑从该公司购买支持。
乔纳森

Answers:


80

我最喜欢的方法是将sqldump命令传递到sql命令。您可以处理所有数据库或特定数据库。因此,例如

mysqldump -uuser -ppassword myDatabase | mysql -hremoteserver -uremoteuser -premoteserverpassword 

您可以使用

mysqldump --all-databases -uuser -ppassword | mysql -hremoteserver -uremoteuser -premoteserver 

唯一的问题是当数据库太大并且管道崩溃时。在这种情况下,您可以逐表或下面提到的任何其他方法进行处理。


4
提示:如果两个数据库都不允许远程连接,请通过管道进行访问netcat
Bart van Heukelom

1
为此,我必须在远程服务器上创建一个具有相同名称的空数据库,然后将该数据库的名称添加到命令末尾。
Zugwalt

1
这很优雅,但是没有压缩对于20GB数据库几乎不够快。
Daddy32

该解决方案仅适用于完全受控的网络(如果且仅当在安全的专用网络上时,请阅读:而不是Internet)!但是快速简便的解决方案!
tdaget

这快如闪电!但是@Zugwalt所说的对我来说也是正确的。在创建数据库(空)之前,该命令不起作用。add将数据库名称添加到命令末尾。
飞碟

65

我最近通过以下策略移动了一个30GB的数据库:

旧服务器

  • 停止mysql服务器
  • datadir的内容复制到磁盘上的另一个位置(~/mysqldata/*
  • 再次启动mysql服务器(停机时间为10-15分钟)
  • 压缩数据(tar -czvf mysqldata.tar.gz ~/mysqldata
  • 将压缩文件复制到新服务器

新服务器

  • 安装mysql(不要启动)
  • 解压缩压缩文件(tar -xzvf mysqldata.tar.gz
  • 将mysqldata的内容移动到datadir
  • 确保您的innodb_log_file_size在新服务器上相同,否则,请不要复制旧日志文件mysql会生成这些文件
  • 启动mysql

1
压缩/解压缩后跳过副本。使用ssh在网络上流tar,或者(当且仅当在安全的专用网络上读取:不是 Internet时)使用netcat避免加密开销。另外,如果在本地网络上跳过gziping,则如果您有快速的网络管道,则会发现传输瓶颈在固定压缩的旋转核心上发生
atxdba

这对innodb和myisam都适用吗?另外,mysql用户也在datadir中吗?
giorgio79 2013年

2
@ giorgio79确保只要您也移动ibdata文件。默认情况下,它们在datadir中。MySQL用户存储在用户表空间的mysql文件夹中。
Derek Downey 2013年

2
从Windows迁移到Linux是否可以使用此过程?
ypercubeᵀᴹ

2
@TypoCube很抱歉花了两年以上的时间来回答,但是如果有人明确地说:“是的,它可以在Windows到Linux上运行”,那将对我有帮助。就我而言,我从Windows Server 2012 R2转到Cent OS(Red Hat 4.8.5-11)。特定的mysql版本是Maria DB 10.1。按照规定,我停止了两个mysql服务,重新同步了数据目录,并且在新服务器上启动mysql服务后,所有数据库,数据库表和数据库用户都完好无损。
WEBjuju

30

根据MySQL 5.0认证研究指南,第32章32.3.4节,第456,457页描述了二进制可移植性条件,条件带来了以下内容:

如果要进行在一台计算机上进行的二进制备份并在具有不同体系结构的另一台计算机上使用二进制备份,则二进制可移植性非常重要。例如,使用二进制备份是将数据库从一台MySQL服务器复制到另一台MySQL服务器的一种方法。

对于MyISAM,二进制可移植性意味着您可以将MyISAM表的文件从一台MySQL服务器直接复制到另一台机器上的另一台,而第二台服务器将能够访问该表。

对于InnoDB,二进制可移植性意味着您可以将表空间文件从一台计算机上的MySQL服务器直接复制到另一台计算机上的另一台服务器,而第二台服务器将能够访问该表空间。默认情况下,服务器管理的所有InnoDB表都存储在表空间中,因此表空间的可移植性取决于所有单个InnoDB表是否可移植。如果一个表都不是可移植的,那么表空间也不是。

如果满足两个条件,则可以将MyISAM表和InnoDB表空间从一台主机二进制移植到另一台主机:

  • 两台机器都必须使用二进制补码算术
  • 两台计算机都必须使用IEEE浮点格式,否则表必须不包含浮点列(FLOAT或DOUBLE)

实际上,这两个条件几乎没有限制。二进制补码整数算法和IEEE浮点格式是现代硬件上的标准。InnoDB二进制可移植性的第三个条件是,您应该对表和数据库使用小写名称。这是因为InnoDB在Windows上以小写形式在内部(在其数据字典中)存储这些名称。使用小写名称可以在Windows和Unix之间实现二进制可移植性,以强制使用小写名称,您可以在选项文件中放置以下几行:

[mysqld]
lower_case_table_names=1

如果将InnoDB配置为使用按表的表空间,则二进制可移植性的条件将扩展为也包括InnoDB表的.ibd文件。(共享表空间的条件仍然适用,因为它包含存储有关所有InnoDB表信息的数据字典。)

如果不满足二进制可移植性的条件,则可以通过使用某种文本格式(例如,使用mysqldump)转储MyISAM或InnoDB表将它们从一台服务器复制到另一台服务器,然后将它们重新加载到目标服务器中。

基于存储引擎的两种主要方法可以移动单个表。

对于给定的示例,我们将假设以下内容:

  1. datadir是/ var / lib / mysql
  2. 名为mydb的数据库
  3. mydb数据库中称为mytable的表。

MyISAM表

如果mydb.mytable使用MyISAM存储引擎,则该表实际上将表现为三个单独的文件

  1. /var/lib/mysql/mydb/mytable.frm(.frm文件)
  2. /var/lib/mysql/mydb/mytable.MYD(.MYD文件)
  3. /var/lib/mysql/mydb/mytable.MYI(.MYI文件)

.frm包含表结构
.MYD包含表数据
.MYI包含表索引页

从mysql的逻辑观点来看,这些文件相互依赖地用来表示表。由于这些文件没有附加的逻辑关联,因此将表从一个DB服务器迁移到另一个。您甚至可以从Windows服务器到Linux服务器或MacOS。当然,您可以关闭mysql并复制3个表文件。您可以运行以下命令:

LOCK TABLES mydb.mytable READ;
SELECT SLEEP(86400);
UNLOCK TABLES;

在一个ssh会话中将表保持为只读状态并保持锁24小时。一秒钟后,在另一个ssh会话中执行复制。然后用24小时锁定终止mysql会话。您无需等待24小时。

InnoDB表

根据认证书中的上述引用,有许多因素决定着如何备份特定的InnoDB表。为了简单,清楚和简洁起见,只需使用--single-transaction参数对所需表执行mysqldump,即可获得表的最佳时间点转储。如果您只想要一张表,则无需使用InnoDB语义。您可以将该转储文件重新加载到您选择的任何MySQL服务器上。

由于此处合并了两个问题(jcolebrand):编辑

如果您不愿忍受数据库性能缓慢的问题,那么即使mysql仍在ServerA上运行,也可以执行从旧服务器(ServerA)到新服务器(ServerB)的一系列rsync。

步骤01)在ServerB上安装ServerA具有的相同版本的mysql

步骤02)在ServerA上,SET GLOBAL innodb_max_dirty_pages_pct = 0;从mysql 运行大约10分钟(这将从InnoDB缓冲池中清除脏页。它还有助于更快地关闭mysql)如果您的数据库全部是MyISAM,则可以跳过此步骤。

步骤03) rsync --archive --verbose --stats --partial --progress --human-readable ServerA:/var/lib/mysql ServerB:/var/lib/mysql

步骤04)重复步骤03,直到rsync花费不到1分钟

步骤05)service mysql stop在ServerA上

步骤06)再执行一次rsync

步骤07) scp ServerA:/etc/my.cnf ServerB:/etc/

service mysql startServerB上的步骤08)

service mysql start在ServerA上执行步骤08)(可选)

试试看 !!!

警告

您可以创建一个复制从属。只需记住在主服务器/etc/my.cnf中明确设置了server-id,在从属服务器/etc/my.cnf中明确设置了server-id的编号


29

如果您要移动整个数据库架构,甚至不需要mysqldump,并且愿意停止第一个数据库(因此在传输时保持一致)

  1. 停止数据库(或锁定数据库)
  2. 转到mysql数据文件所在的目录。
  3. 将文件夹(及其内容)转移到新服务器的mysql数据目录中
  4. 开始备份数据库
  5. 在新服务器上,发出“创建数据库”命令。
  6. 重新创建用户并授予权限。

我不记得,如果mysqldump的处理用户和权限,或者仅仅是数据......但即使是这样,这是方式比做转储和运行速度更快。仅当需要转储mysql数据库然后将其重新插入其他RDBMS,需要更改存储选项(innodb与myisam),或者如果要更改mysql的主要版本时,才使用该命令。我认为我已经在4到5之间完成了此操作)


这效率更高,尤其是如果是sysadmin / DBA。使用BTW mysqldump --all-databases转储mysql模式。在下一台机器上启动mysql会弹出权限,前提是您已将数据文件夹转移到具有相同主要MySQL版本的另一台机器上。(MySQL 5.5.x至MySQL 5.5.x,MySQL 5.1.x至MySQL 5.1.x,MySQL 5.0.x至MySQL 5.0.x)
RolandoMySQLDBA 2011年

4
@Joe是的,可以mysqldump处理用户和权限,因为它们存储在mysql架构中。
Shlomi Noach 2012年

此方法对AWS等云托管特别有用。您可以停止mysql,卸载并从当前服务器分离;附加并挂载到新服务器并启动mysql。如果卷保留在同一服务器场中,则没有复制开销。
LateralFractal

12

如果只想移动特定的表,请尝试:

mysqldump -u username -ppassword databasename tablename > databasename.tablename.sql

您可以在同一命令中在上面指定更多表名。命令完成后,将databasename.tablename.sql文件移动到另一台服务器,然后使用以下命令进行还原:

mysql -u username -ppassword databasename < databasename.tablename.sql

请注意,使用mysqldump程序创建了反向.sql文件,并且还原直接在mysql中完成。


7
  1. 如果您具有ssh访问权限,则可以从命令行使用mysqldump
  2. 如果您没有ssh访问权限,但是具有phpMyAdmin访问权限,则可以使用它来导出/导入
  3. 如果您没有phpMyAdmin访问权限,则将有一些方便的php脚本将转储和导入(但是从我自己的经验来看,我从未找到像phpMyAdmin一样可靠的脚本)。

您可能会在其中移动实际的数据库文件(对于我的安装,这些文件位于/ var / lib / mysql),但是我不太确定它将如何执行/解决问题。


5

您将需要停机。这将需要一段时间,具体取决于您的网络速度。我假设您在Linux / Unix上运行MySQL。这是我使用的过程:

  1. 在源主机上停止mysql守护程序。
  2. 在目标主机上创建一个tmp文件夹以接收文件。
  3. 使用screen创建一个shell会话,如果您的ssh断开连接,它将继续存在。
  4. 使用rsync在主机之间传输文件。类似于:rsync -avhP source user @ targethost:/ path / to / folder /
  5. 运行测试用例,以确保您在传输中没有丢失任何东西。

然后照常进行设置本地MySQL。

*注意:您也可以将-c参数与rsync一起使用,以将校验和添加到传输中,但是根据CPU速度的不同,这会很麻烦。


4

我可以确认DTest的方法也可以在ubuntu和osx之间进行复制。

要复制所有数据库而不必进行任何转储或类似操作:

确保您拥有干净的mysql mysql(安装了从mysql http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.63-osx10.6-x86_64.dmg下载的dmg ),该文件(VERY重要)从未运行过。

从Mac上/ usr / local / mysql / data /目录顶部的ubuntu计算机复制/ var / lib / mysql /文件夹目录。要访问ubuntu机器上的get文件夹,我必须使用sudo即:

sudo cp /var/lib/mysql /home/foouser/mysql_data_folder
sudo chown -R foouser /home/foouser/mysql_data_folder

我使用scp复制了该文件夹。

在开始之前,请在Mac上获取mysql文件夹的副本,以确保您不会弄乱任何内容。

复制文件夹后,在mac机上执行以下操作:

sudo chown -R _mysql /usr/local/mysql/data/
sudo chgrp -R wheel /usr/local/mysql/data/
sudo chmod -R g+rx /usr/local/mysql/data/

首次启动mysql服务器(从“系统偏好设置”->“ mysql”下的“偏好设置”窗格中)。现在应该正确设置所有用户和数据库。

这适用于ubuntu 64位11.10上的mysql 5.1.61和osx lion(macbook pro)上的mysql 5.1.63。


4

我认为所有较早的答案都可以正常工作,但是并不能真正解决在传输过程中设置数据库名称的问题。

这就是我刚刚使用bash的方式:

您最好使用而rsync不是scp,如果经常这样做,最好不要压缩文件。

在我的源服务器上:

me@web:~$ d=members
me@web:~$ mysqldump $d | gzip > $d.sql.gz
me@web:~$ scp -i .ssh/yourkeynamehere $d.sql.gz $sbox:$d.sql.gz

在我的目标服务器上:

me@sandbox:~$ d1=members
me@sandbox:~$ d2=members_sb
me@sandbox:~$ mysqladmin create $d2
me@sandbox:~$ cat $d1.sql.gz | gunzip |  mysql $d2

在任一台机器上查看进度:

me@sandbox:~$ ls *.gz 
me@sandbox:~$ cat $d.sql.gz | gunzip |  less

所有这些都假定您在两台计算机的主目录中都有MySQL配置文件,并设置了权限:

$ echo "
[client]
user=drupal6
password=metoknow
host=ord-mysql-001-sn.bananas.com
[mysql]
database=nz_drupal" > .my.cnf
$ chmod 0600 ~/.my.cnf

3

您是否将其移动到另一个mysql服务器数据库?如果使用,请对其进行导出

# mysqldump -u username -ppassword database_name > FILE.sql

Mysqldump的?那是您要处理少量数据的时候?
Oh Chin Boon

2
我认为这些天大/小都是相当主观的。当我看到问题的标题时,我期望数据库比20gb大得多,因此被认为是“大型” ...
Aaron Bertrand

3

通用linux方法:

/etc/init.d/mysqld stop
rsync -avz source_files destination
vi /etc/my.cnf

编辑mysqld和mysqld_safe的数据目录(和套接字)(如果适用)以指向新位置,然后

/etc/init.d/mysql start

我发布此邮件是因为似乎没有人简单地列出最少的步骤来完成此操作,而且我个人认为这是最简单的方法。


2

也许这是一种更好的方法:

版本1:数据文件复制(仅MYISAM)

ssh server1
service mysql stop
cd $mysql-data-dir
rsync -avz dirs-or-files server2:$mysql-data-dir
service mysql start

ssh server2服务重启mysql

  • 如果您的数据库文件是只读的,则可以跳过停止服务器的操作。

版本2:mysqldump

在现代Xeon或Opteron处理器上安装pigz-尤其是当您具有2个或更多CPU时,它比gzip快得多。

ssh server1 
mysqldump ... | pigz > backup-YYMDD.sql.gz
rsync backup-YYMDD.sql.gz server:location

ssh server2
pigz -dc location/backup-YYMDD.sql.gz | mysql ..

版本3:主/从+ mysqldump /文件复制

In HA environment you should use the following trick:
setup slave server & do all backups from it
before backups - do "slave stop"; 
then do version 1 or version 2

脚本:

touch full.start
mysqladmin -h slave-db stop-slave
echo "show slave status \G" | mysql -h slave-db > FULL/comfi-$NOW.master-position
/usr/bin/mysqldump -h slave-db --default-character-set=utf8 -A --opt --skip-lock-tables | pigz > "FULL/XXXX-$NOW.sql.gz"
mysqladmin -h slave-db start-slave
touch full.end

ln -fs "FULL/XXXX-$NOW.sql.gz" FULL.sql.gz

PS:

复制小表使用:

ssh server1 mysqldump模式表 ssh server2 mysql模式


2

我建议通过两个简单步骤将整个数据库从一台服务器转移到另一台服务器。

步骤1:使用mysqldump在源服务器中进行数据库的完整备份。

步骤2:您可以使用rsync命令将整个数据库传输到目标服务器。

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.