如何在 CentOS 和 Ubuntu 上将 MySQL 数据目录移动到新位置
默认情况下,MySQL 数据库将创建在 /var/lib/mysql 目录下。
如果您正在运行一个不占用太多空间的小型数据库,这可能没问题。但是在生产中,对于较大的数据库,根分区下可能没有足够的空间。
在这种情况下,您可能希望将 MySQL 数据库从根分区移动到不同的分区。
要更改 MySQL 目录,在较高级别上,您必须执行以下三个步骤:
- 将 MySQL 数据库文件从 /var/lib/mysql 移动到不同的分区
- 使用新的目录位置修改 my.cnf 文件
- 更新安全设置以反映目录更改:在 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
- 点赞
- 收藏
- 关注作者
评论(0)