如何在Ubuntu20.04上将MySQL数据目录移动到新位置

来自菜鸟教程
跳转至:导航、​搜索

介绍

数据库随着时间的推移而增长,有时会超过文件系统上的空间。 当它们与操作系统的其余部分位于同一分区时,您还可能遇到输入/输出 (I/O) 争用。 独立磁盘冗余阵列 (RAID)、网络块存储和其他设备可以提供冗余和其他所需功能。 无论您是要添加更多空间、评估优化性能的方法,还是想利用其他存储功能,本教程都将指导您重新定位 MySQL 的数据目录。

先决条件

要完成本指南,您需要:

  • 具有非 root 用户且具有 sudo 权限并启用防火墙的 Ubuntu 20.04 服务器。 您可以在我们的 Initial Server Setup with Ubuntu 20.04 指南中了解有关如何设置具有这些权限的用户的更多信息。
  • 一个 MySQL 服务器。 如果您尚未安装 MySQL,请查看我们关于 如何在 Ubuntu 20.04 上安装 MySQL 的指南。

在本教程中,我们将数据移动到安装在 /mnt/volume-nyc1-01 的块存储设备。 您可以在以下有关 DigitalOcean 上的 Block Storage Volumes 的文档中了解如何设置。

无论您使用什么底层存储,本指南都可以帮助您将数据目录移动到新位置。

第 1 步 — 移动 MySQL 数据目录

为了准备移动 MySQL 的数据目录,让我们通过使用管理凭据启动交互式 MySQL 会话来验证当前位置。 运行以下命令打开 MySQL 服务器提示符:

sudo mysql

注意:如果您将 root MySQL 用户配置为使用密码进行身份验证,则可以使用以下命令以该用户身份连接到 MySQL:

mysql -u root -p

出现提示时,提供 MySQL 用户密码。 然后在 MySQL 提示符下,运行以下 SELECT 语句。 这将返回此 MySQL 实例的活动数据目录,该目录始终记录在 MySQL 的 datadir 变量中:

SELECT @@datadir;
Output+-----------------+
| @@datadir       |
+-----------------+
| /var/lib/mysql/ |
+-----------------+
1 row in set (0.00 sec)

此输出确认 MySQL 已配置为使用默认数据目录 /var/lib/mysql/,因此这是您需要移动的目录。 一旦你确认了这一点,写 exit 离开监视器并返回到你的命令提示符:

exit
OutputBye

为确保数据的完整性,请在更改数据目录之前关闭 MySQL:

sudo systemctl stop mysql

请注意,systemctl 不会显示所有服务管理命令的结果,因此如果要检查是否成功,请使用以下命令:

sudo systemctl status mysql

如果输出中的 Active 行显示为 inactive (dead),您可以确认它已关闭,如以下示例中突出显示的:

Output● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset:>
     Active: inactive (dead) since Wed 2022-03-23 19:03:49 UTC; 5s ago
    Process: 3415 ExecStart=/usr/sbin/mysqld (code=exited, status=0/SUCCESS)
   Main PID: 3415 (code=exited, status=0/SUCCESS)
     Status: "Server shutdown complete"

现在服务器已关闭,您可以使用 rsync 将现有数据库目录 /var/lib/mysql 复制到新位置 /mnt/volume-nyc1-01。 使用 -a 标志保留权限和其他目录属性,而 -v 提供详细输出,以便您可以跟踪进度:

注意: 确保目录后面没有斜杠,如果使用制表符补全,可能会添加斜杠。 当尾部有斜杠时,rsync 会将目录的内容转储到挂载点,而不是将其传输到包含 mysql 的目录中。


sudo rsync -av /var/lib/mysql /mnt/volume-nyc1-01

rsync 命令完成后,使用 .bak 扩展名重命名当前文件夹并保留它,直到您确认移动成功。 通过重命名它,您将避免新旧位置的文件可能引起的混淆:

sudo mv /var/lib/mysql /var/lib/mysql.bak

现在您已准备好继续下一步并开始配置。

第 2 步 — 指向新的数据位置

MySQL 有几种方法可以覆盖配置值。 默认情况下,/etc/mysql/mysql.conf.d/mysqld.cnf 文件中的 datadir 设置为 /var/lib/mysql。 在您喜欢的文本编辑器中编辑此文件以反映新的数据目录。 这里我们将使用 nano

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

找到以 datadir= 开头的行。 通过删除井号 (#) 取消注释该行并更改路径以反映新位置。 在这种情况下,更新后的文件内容如下:

/etc/mysql/mysql.conf.d/mysqld.cnf

. . .
datadir=/mnt/volume-nyc1-01/mysql
. . .

完成此更新后,保存并退出文件。 如果您使用的是 nano,您可以按 CTRL + X,然后按 YENTER 来执行此操作。 现在几乎是再次启动 MySQL 的时候了,但在此之前,还有一件事需要配置才能成功。

第 3 步 — 配置 AppArmor 访问控制规则

在这一步中,您需要通过在默认目录和新位置之间创建别名来告诉 AppArmor 让 MySQL 写入新目录。 AppArmor 是 Linux 内核中的一个安全模块,它允许系统管理员通过程序配置文件而不是用户自己来限制程序功能。 首先打开并编辑 AppArmor alias 文件:

sudo nano /etc/apparmor.d/tunables/alias

在文件底部,取消注释以下行并添加别名规则:

/etc/apparmor.d/tunables/alias

. . .
alias /var/lib/mysql/ -> /mnt/volume-nyc1-01/mysql/,
. . .

完成后,保存并退出文件。

要使更改生效,请重新启动 AppArmor:

sudo systemctl restart apparmor

注意: 如果您跳过 AppArmor 配置步骤,您将收到以下错误消息:

OutputJob for mysql.service failed because the control process 
exited with error code. See "systemctl status mysql.service" 
and "journalctl -xe" for details.

由于此消息未在 AppArmor 和数据目录之间建立显式连接,因此此错误可能需要一些时间才能弄清楚。


正确配置 AppArmor 后,您可以继续下一步。

第四步——重启 MySQL

现在是时候启动 MySQL 了。 但是,如果这样做,您将遇到另一个错误。 此错误不是 AppArmor 问题,而是由 mysql-systemd-start 引起的,该脚本支持通过 systemd 管理 MySQL。 您可以使用以下命令检查此脚本:

nano /usr/share/mysql/mysql-systemd-start

此脚本检查是否存在与默认数据目录路径匹配的目录 -d 或符号链接 -L。 如果它没有找到其中任何一个,脚本将触发错误并阻止 MySQL 启动:

/usr/share/mysql/mysql-systemd-start

. . .
if [ ! -d /var/lib/mysql ] && [ ! -L /var/lib/mysql ]; then
 echo "MySQL data dir not found at /var/lib/mysql. Please create one."
 exit 1
fi

if [ ! -d /var/lib/mysql/mysql ] && [ ! -L /var/lib/mysql/mysql ]; then
 echo "MySQL system database not found. Please run mysql_install_db tool."
 exit 1
fi

. . .

检查此文件后,关闭它而不做任何更改。

由于您需要适当的目录或符号链接来启动服务器,因此您必须创建最小目录结构以通过脚本的环境检查:

sudo mkdir /var/lib/mysql/mysql -p

现在您已准备好启动 MySQL:

sudo systemctl start mysql

通过检查状态确认 MySQL 正在运行:

sudo systemctl status mysql
Output● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset:>
     Active: active (running) since Wed 2022-03-23 20:51:18 UTC; 4s ago
    Process: 17145 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=>
   Main PID: 17162 (mysqld)
     Status: "Server is operational"
      Tasks: 38 (limit: 1132)
     Memory: 376.7M
     CGroup: /system.slice/mysql.service
             └─17162 /usr/sbin/mysqld

要确保新数据目录确实在使用中,请启动 MySQL 监视器:

mysql -u sammy -p

现在再次查询数据目录的值:

SELECT @@datadir;
Output+----------------------------+
| @@datadir                  |
+----------------------------+
| /mnt/volume-nyc1-01/mysql/ |
+----------------------------+
1 row in set (0.01 sec)

在您重新启动 MySQL 并确认它正在使用新位置后,请借此机会确保您的数据库功能齐全。 完成后,按如下方式退出数据库并返回命令提示符:

exit
OutputBye

现在您已经验证了任何现有数据的完整性,您可以删除备份数据目录:

sudo rm -Rf /var/lib/mysql.bak

然后最后一次重新启动 MySQL:

sudo systemctl restart mysql

最后,通过检查状态确认它是否按预期工作:

sudo systemctl status mysql
Output● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset:>
     Active: active (running) since Wed 2022-03-23 20:53:03 UTC; 4s ago
    Process: 17215 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=>
   Main PID: 17234 (mysqld)
     Status: "Server is operational"
      Tasks: 38 (limit: 1132)
     Memory: 368.9M
     CGroup: /system.slice/mysql.service
             └─17234 /usr/sbin/mysqld

如果 Active 行声明 active(running) 这确认 MySQL 正在工作。

结论

在本教程中,您学习了如何将 MySQL 的数据目录移动到新位置并更新 Ubuntu 的 AppArmor 访问控制列表以适应调整。 尽管我们使用的是块存储设备,但此处的说明应该适用于重新定义数据目录的位置,而不管底层技术如何。

有关管理 MySQL 数据目录的更多信息,请查看官方 MySQL 文档中的以下部分: