一、概述

  • 前面文章讨论了默认配置里的数据目录结构,所有的数据库、状态文件和日志文件都位于其中。不过,在确定数据目录内容的存放位置方面,也有一些回旋的余地。MySQL允许你迁移数据目录本身或者其中的某些元素。
  • 你想这样做的理由可能有以下几种:
    • 包含数据目录的那个文件系统已满,你需要将其移动到某个拥有更大容量的文件系统上。
    • 如果数据目录位于一个很忙的磁盘驱动器上,那么你可以把它放在活动不太频繁的驱动器上,以平衡跨物理设备的磁盘活动。你可以把数据库和日志文件放在不同的驱动器上,或者基于同样的原因把数据库分散在各个驱动器上。同样地,虽然InnoDB系统表空间在概念上是一个巨大的存储块,但是可将其各个组成文件放置在不同的驱动器上,以提高性能。如果你使用了分区表,那么可以在各个分区来做这件事情。
    • 把数据库和日志分别放在不同的磁盘上,这样有助于减少单个磁盘故障造成的破坏。
  • 本文将讨论数据目录的哪一部分可以移动,以及如何进行移动。

二、迁移方法

  • 迁移数据目录或其中各个部分的方法有两种。
  • 第一种,在任何平台上,你都可以在服务器启动时,通过命令行或者选项文件,指定一个选项。例如,想要指定数据目录的位置,可以在服务器启动时,在命令行上使用--datadir=dir_name选项来指定,或者将下面的行放入某个选项文件中来指定:
[mysqld]
datadir = dir_name
  • 一般情况下,服务器选项中的选项文件组名是[mysqld],如上面示例所示。不过,根据具体的情况,其他选项组名可能更为适合。例如,你正在使用mysqld_multi运行多个服务器实例,那么这些组名将变成[mysqldn]这样的形式,其中,n是一个与某个特定的服务器实例相关联的整数。后面"安排MySQL服务器的启动和关闭"文章将讨论适用于不同服务器启动方法的不同选项组,并且将对运行多个服务器提供指导。
  • 第二种,在Unix上,可以先移动要迁移的文件或目录,然后在原来位置生成一个符号链接,指向新位置。
  • 这两种方法都不能完全适用于可迁移的所有内容。下图总结了哪些是可迁移的,可以采用哪种迁移方法。如果使用的是选项文件,则可以在全局选项文件(如Unix里的/etc/my.cnf,或者Windows里的C:\my.cnf)中指定各种选项。

三、迁移注意事项

  • 在迁移之前,一定要记得备份数据,以便在迁移操作搞砸时进行恢复。而且,应该在执行迁移操作之前,停止MySQL服务器,迁移完成之后再重启它。
  • 对于某些类型的迁移,如移动数据库目录,有时可能会保持服务器继续运行,但不推荐这样做。如果真要那样,一定要保证服务器不会访问正移动的那个数据库。在移动数据库之前,还应该执行FLUSH TABLES语句,以保证服务器会关闭所有打开的表文件
  • 如果不遵守这几点,可能会导致表损坏。

四、评估迁移带来的影响

  • 在试图迁移之前,请记得核实一下该操作可能会带来的影响。例如,在Unix上,可以使用du、df和Is-1命令来查看磁盘空间信息。不过,你必须正确理解文件系统的结构对所有这些命令来说意味着什么。
  • 下面这个示例展示了在对数据目录迁移进行评估时,需要特别注意的某些难以捉摸的“陷讲”。假设,数据目录为/usr/local/mysql/data,而你想要把它转移到/var/mysql,因为df命令的输出表明/var文件系统有更多的可用空间:

  • 为弄清数据目录迁移之后,/usr文件系统上能释放多少空间,可以使用du-s命令:

  • 这个结果表明,把数据目录从/usr转移到/var,将可以在/usr上释放出约3GB的空间。真是如此吗?为査明真相,可以对数据目录使用df命令。假设得到了如下所示的输出结果:

  • 奇怪!为什么df命令报告的是/var文件系统上的空间使用情况呢?下面这条ls -l命令给出了答案:

  • 这个输出显示,/usr/local/mysgl/data是一个指向/var/mysql的符号链接。换句话说,数据目录早已被转移到了/var文件系统里,并且被替换为了一个指向该处的符号链接。通过把数据目录转移到/var的方式来在/usr上释放大量空间的相关问题就讲解到这里!
  • 如果想要将某个数据库移动到另一个文件系统,以试图重新分配数据库存储,那么请记住一点:如果你正在使用存储在InnoDB系统表里的InnoDB表,那么这些表的内容并不在数据库目录里。对于主要由像IrmoDB表这样的表组成的数据库,在迁移数据库目录时,只需要迁移它们的.fm文件即可,不用迁移它们的内容。这不会对存储分布产生大的影响。
  • 上面这些示例给我们的启发是,多花费几分钟来评估迁移可能造成的影响,可以避免做出多徒劳无功的事情。

五、迁移整个数据目录

  • 在迁移数据目录时,要停止MySQL服务器,并把数据目录移至新的位置。在移动之后,要使用能明确指示新位置的--datadir选项来重启服务器。
  • 在Unix上,除了使用--datadir以外,还可以在原来的数据目录里创建一个符号链接,让它指向新位置。

六、迁移单个数据库

  • 服务器总是会在数据目录里查找数据库目录,因此迁移数据库的唯一方法是使用符号链接。这个过程在Unix和Windows上有所不同。
  • 在Unix上,迁移数据库的过程如下:
    • (1)停止正在运行的服务器。
    • (2)把数据库移至新的位置;或者将其复制过去,并删除原来那个。
    • (3)在数据目录中创建一个符号链接,让其具有原来那个数据库的名字,并指向那个新的数据库位置。
    • (4)重启服务器。
  • 下面这个示例展示了如何把bigdb数据库从/usr/local/nysql/data目录迁移至/var/db:

七、迁移单个表

  • 只有在满足以下条件时才能迁移单个表:
    • 必须使用Unix系统,并且要迁移的表必须为MylSAM表
    • 操作系统必须具有一个可工作的realpath()系统调用。如果真有,那么下面这个査询的结果将为YES:
SHOW VARIABLES LIKE 'have_symlink';

  • 如果上述两个条件都满足,那么你便可以把表的.MYD数据文件和.MYI索引文件移动到新的位置;接着在原来的数据文件和索引文件所在的数据库目录里创建符号链接,分别指向它们。(.frm文件仍然需要留在原来的数据库目录里)。
  • 在执行此操作之前,可以在移动文件时停止服务器;也可以锁定表,以防止服务器使用它。

八、迁移InnoDB系统表空间

  • 初次配置InnoDB系统表空间时,可以使用innodb_data_home_dir和innodb_data_file_path系统变量,将InnoDB系统表空间的各个组成文件罗列在某个选项文件里。(更多相关细节请参考后面"存储引擎配置"文章)。
  • 如果你已经创建了表空间,可能就可以迁移组成它的那些常规文件,例如,把它们分散到不同的文件系统里。因为文件的位置是通过系统变量来指定的,所以你必须按以下步骤来迁移部分或者全部的表空间文件。
    • (1)如果服务器在运行,要停止它。
    • (2)移动需要迁移的表空间文件。
    • (3)修改定义InnoDB配置的那个选项文件,反映出文件迁移后的新位置。
    • (4)重启服务器。

九、迁移状态文件和日志文件

  • 如果要迁移PID文件或日志文件,则需要先停止MySQL服务器,然后使用一个可以指定文件新位置的选项来重启它。例如,为把PID文件创建为/tmp/mysql.pid,可以在命令行上使用--pid-file=/tmp/mysql.pid选项,或者在某个选项文件里包含以下内容:
[mysqld]
pid-file = /tmp/mysql.pid
  • 如果是用绝对路径名来指定文件名,那么服务器会使用该路径名来创建文件。如果使用的是相对路径名,那么服务器将在其自己的数据目录中创建该文件。例如,当指定--pid-file=mysqld.pid时,这个PID文件即为数据目录下的mysqld.pid。
  • 有些系统会把各种服务器的PID文件保存在某个特定的目录里,如/var/run。你可能也会想要把MySQL的PID文件保存到那里,从而与系统操作的保持一致。类似地,如果你的系统把日志文件都保存在/var/log目录里,那么你也可以把MySQL的日志文件放置到那里。不过,许多系统都只允许root用户对这些子目录进行写操作。这意味着,你必须以root用户权限来运行服务器——从安全的角度来讲,这可是个不太好的做法。比较可行的做法是:创建两个子目录/var/run/mysql和/var/log/mysql,并把它们的所有者设置成你用于运行服务器的那个账户。例如,这个账户的用户名和用户组名都是mysql,以root用户的身份执行以下命令:

  • 然后,服务器就能毫无问题地在这些目录里写入文件了,并且可以使用指定这些文件所在位置的选项来启动服务器。例如:

更多推荐