如何在 CentOS 和 Ubuntu 上将 MySQL 数据目录移动到新位置

举报
Tiamo_T 发表于 2021/11/25 20:01:00 2021/11/25
【摘要】 默认情况下,MySQL 数据库将创建在 /var/lib/mysql 目录下。 如果您正在运行一个不占用太多空间的小型数据库,这可能没问题。但是在生产中,对于较大的数据库,根分区下可能没有足够的空间。 在这种情况下,您可能希望将 MySQL 数据库从根分区移动到不同的分区。

默认情况下,MySQL 数据库将创建在 /var/lib/mysql 目录下。

如果您正在运行一个不占用太多空间的小型数据库,这可能没问题。但是在生产中,对于较大的数据库,根分区下可能没有足够的空间。

在这种情况下,您可能希望将 MySQL 数据库从根分区移动到不同的分区。

要更改 MySQL 目录,在较高级别上,您必须执行以下三个步骤:

  1. 将 MySQL 数据库文件从 /var/lib/mysql 移动到不同的分区
  2. 使用新的目录位置修改 my.cnf 文件
  3. 更新安全设置以反映目录更改:在 CentOS 或 RedHat 上,修改 SELinux 设置。在 Ubuntu 或 Debian 上,修改 AppArmor 设置。

本教程详细介绍了如何执行上述三个步骤将 MySQL 数据移动到不同的目录。

备份当前的 MySQL

在您执行任何操作之前,请停止 MySQL 数据库并对您的数据库进行冷备份。

默认情况下,MySQL 将数据库放在 /var/lib/mysql 目录下。将此 mysql 目录复制到其他位置进行备份。

service mysqld stop

cp -r /var/lib/mysql /backup/mysql

或者,如果您愿意,可以使用mysqldump 进行 MySQL 数据库备份

将 MySQL 数据目录移动到不同的分区

在这个例子中,我的根分区是 /dev/sda1,它没有太多空间用于默认的 /var/lib/mysql 目录。但是,我在 /dev/sdb1 磁盘上有 /data 分区,它有很多空间。

因此,我会将 MySQL 数据库从 / 分区移动到 /data 分区。

创建以下目录并将mysql数据从/var/lib移动到/data/var/lib,如下所示。

mkdir -p /data/var/lib

cd / var / lib

mv mysql/data/var/lib/

需要考虑的几点:

  • 您还可以将 mysql 目录移动到 /data/var/lib/ 目录,并从 /var/lib 创建一个指向 /data/var/lib 的符号链接。但是,在这种特殊情况下,我更喜欢上述简单的移动目录而不使用符号链接以避免混淆。
  • 如果可能,尝试使用 move 命令移动目录(而不是复制)。当您执行复制时,SELinux 上下文将丢失,您必须稍后手动设置(如下所述)。但是,当您移动时,适用于 MySQL 的 SELinux 上下文会保持原样,您不必担心更改它。

此外,如果您复制了目录(而不是移动),请确保适当更改所有权。如果没有,您可能会收到此错误消息:MySQL 错误:1017Can't find file: (errno: 13)

chown -R mysql:mysql /data

修改 my.cnf 并启动 MySQL

在 /etc/my.cnf 文件中,需要修改 datadir 和 socket 参数,并将它们指向新目录,如下所示。

# vi /etc/my.cnf
datadir=/data/var/lib/mysql
socket=/data/var/lib/mysql/mysql.sock

最后,重启 MySQL 数据库。

# service mysqld start
Starting mysqld:  [  OK  ]

如果您的 my.cnf 文件中已经定义了 tmpdir 参数,请同时更改该参数的目录:

tmpdir = /data/var/lib/mysql

更改 my.cnf 文件中的 datadir 和 socket 后,如果 MySQL 没有启动,或者失败并显示权限被拒绝的错误消息,那么您需要按照以下部分的说明设置 SELinux(或 AppArmor)。

MySQL 的 SELinux 上下文类型

使用 ls -Z 命令查看 SELinux 上下文。在移动目录之前,以下是我的 MySQL 数据库上的 SELinux 上下文。在本例中,“thegeekstuff”是/var/lib/mysql 目录下的MySQL 数据库。

正如您在此处看到的,mysqld_db_t 是 SELinux 上下文类型。

# ls -Z /var/lib/mysql
drwx------. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 thegeekstuff
-rw-rw----。mysql mysql unconfined_u:object_r:mysqld_db_t:s0 ibdata1
-rw-rw----。mysql mysql unconfined_u:object_r:mysqld_db_t:s0 ib_logfile0
..

将目录移动到新位置后,您应该会看到确切的 SELinux 作为移动前的内容。

ls -Z /data/var/lib/mysql

注意:如果您复制了目录(而不是移动),您会注意到它已更改。在这种情况下,请按照以下说明更改 SELinux 上下文。

当 SELinux 上下文错误时,您将在审核日志(或 /var/log/messages)中看到以下错误消息(或类似的内容)

# cat /var/log/audit/audit.log:
type=AVC msg=audit(1447281394.928:20831): avc: denied { read } for pid=21346 comm="mysqld" name="mysql" dev=sda1 ino=5506027 scontext=unconfined_u:system_r:mysqld_tcontext=uun02 :object_r:var_lib_t:s0 

此外,当 MySQL DB 无法启动时,您将在 mysqld.log 文件中看到以下内容。

# cat /var/log/mysqld.log:
mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
[Warning] Can't create test file /var/lib/mysql/devdb..lower-test
/usr/libexec/mysqld: Can't change dir to '/var/lib/mysql/' (Errcode: 13)
[ERROR] Aborting
[Note] /usr/libexec/mysqld: Shutdown complete

CentOS / RedHat 上 MySQL 的 SELinux 设置(选项 1)

使用 chcon 命令,您可以更改新目录中的 SELinux 上下文类型,如下所示。

chcon -R -t mysqld_db_t /data

在上面的命令中:

  • chcon 是改变 SELinux 上下文的命令
  • -R 选项将递归更改给定目录和所有子目录的上下文。
  • -t 选项用于指定应该设置的 SELinux 上下文类型。在本例中,我们将其设置为 mysqld_db_t 类型。
  • /data 是将在其上执行此命令的目录。

注意:从顶级目录 /data(而不是 mysql 目录)开始更改上下文,这将包括 mysql 目录和所有子目录和文件。

CentOS / RedHat 上 MySQL 的 SELinux 设置(选项 2)

使用 restorecon 命令,您可以将 SELinux 上下文恢复到正确的类型。但是,在这种情况下,您应该通过将 mysqld_db_t 类型添加到 SELinux 上下文映射来通知 SELinux 什么是正确的上下文。

要将 SELinux 类型添加到上下文映射,请使用 semanage 命令。安装包含 semanage 命令的 policycoreutils-python 包。

yum -y install policycoreutils-python

接下来,执行以下命令在新目录上设置 SELinux 上下文映射。

semanage fcontext -a -t mysqld_db_t "/data(/.*)?"

在上面的命令中,我们将 mysqld_db_t 添加到 /data 目录下所有子目录和文件的上下文映射中。

最后,使用 restorecon 命令,它将适当的 SELinux 上下文恢复到新的 /data 目录。

restorecon -Rv /data 

验证移动的新 /data 目录和 mysql 子文件夹是否具有正确的 SELinux 上下文。

# ls -Z /data/var/lib/mysql
drwx------. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 thegeekstuff
-rw-rw----。mysql mysql unconfined_u:object_r:mysqld_db_t:s0 ibdata1
-rw-rw----。mysql mysql unconfined_u:object_r:mysqld_db_t:s0 ib_logfile0
..

注意:您还可以将 -e 选项与 fcontext 一起使用。这将使 /data 及其子目录的上下文标签与 /var/lib/mysql 的上下文标签相同

semanage fcontext -a -e /var/lib/mysql /data

在 Ubuntu / Debian 上为 MySQL 设置 AppArmor

将 MySQL 数据目录移动到新位置后,如果不执行以下操作,在 Ubuntu 上,您将在启动 mysql 数据库时收到此错误:“(errno: 13)”(权限被拒绝)。

修改usr.sbin.mysqld文件如下图,添加如下两行。不要忘记行尾的逗号,这是必需的。

# vi /etc/apparmor.d/usr.sbin.mysqld
/data/var/lib/mysql/ r,
/data/var/lib/mysql/** rwk,

接下来,执行以下命令为 mysql 重新解析这个新的 apparmor 配置文件,并重新启动 apparmor。

sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld

sudo /etc/init.d/apparmor reload

注意:或者,您也可以在 AppArmor 别名文件中添加别名,如下所示。同样,不要忘记此别名行末尾的逗号。

# vi  /etc/apparmor.d/tunables/alias
alias /var/lib/mysql/ -> /newpath/,

MySQL 客户端套接字参数

进行上述更改后,您在从 mysql 客户端连接时可能会收到此错误消息:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

# mysql -u root -pMyPassword
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

如果发生这种情况,请将 –socket 参数传递给 mysql 客户端,并将其指向位于新目录下的 mysql.sock 文件。

mysql -u root -pMyPassword --socket=/data/var/lib/mysql/mysql.sock

如果您在本地调用 mysql 客户端,您还可以使用 -h 选项并传递 127.0.0.1,如下所示。这也将避免 mysql.sock 错误消息。

mysql -u root -pMyPassword -h127.0.0.1
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。