介绍
数据库随着时间的推移而增长,有时会超过文件系统上的空间。 当它们与操作系统的其余部分位于同一分区时,您也可能会遇到 I/O 争用。 RAID、网络块存储和其他设备可以提供冗余和其他理想的功能。 无论您是要添加更多空间、评估优化性能的方法,还是希望利用其他存储功能,本教程都将指导您重新定位 MySQL 的数据目录。
先决条件
要完成本指南,您需要:
- 具有非 root 用户且具有 sudo 权限的 Ubuntu 16.04 服务器。 您可以在我们的 Initial Server Setup with Ubuntu 16.04 指南中了解有关如何设置具有这些权限的用户的更多信息。
- MySQL 服务器。 如果您还没有安装 MySQL,如何在 Ubuntu 16.04 上安装 MySQL 指南可以为您提供帮助。
在此示例中,我们将数据移动到安装在 /mnt/volume-nyc1-01
上的块存储设备。 您可以在 如何在 DigitalOcean 上使用块存储指南中了解如何设置。
无论您使用什么底层存储,本指南都可以帮助您将数据目录移动到新位置。
第 1 步 — 移动 MySQL 数据目录
为了准备移动 MySQL 的数据目录,让我们通过使用管理凭据启动交互式 MySQL 会话来验证当前位置。
mysql -u root -p
出现提示时,提供 MySQL root 密码。 然后从 MySQL 提示符中,选择数据目录:
select @@datadir;
Output+-----------------+ | @@datadir | +-----------------+ | /var/lib/mysql/ | +-----------------+ 1 row in set (0.00 sec)
此输出确认 MySQL 已配置为使用默认数据目录 /var/lib/mysql/,
,因此这是我们需要移动的目录。 确认后,输入 exit
离开显示器。
为了确保数据的完整性,我们将在实际更改数据目录之前关闭 MySQL:
sudo systemctl stop mysql
systemctl
不会显示所有服务管理命令的结果,所以如果你想确保你已经成功,使用以下命令:
sudo systemctl status mysql
如果输出的最后一行告诉您服务器已停止,您可以确定它已关闭:
Output. . . Jul 18 11:24:20 ubuntu-512mb-nyc1-01 systemd[1]: Stopped MySQL Community Server.
现在服务器已关闭,我们将使用 rsync
将现有数据库目录复制到新位置。 使用 -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
。 编辑此文件以反映新的数据目录:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
找到以 datadir=
开头的行并更改后面的路径以反映新位置。
在我们的例子中,更新后的文件如下所示:
/etc/mysql/mysql.conf.d/mysqld.cnf
. . . datadir=/mnt/volume-nyc1-01/mysql . . .
这似乎是再次启动 MySQL 的合适时机,但在我们成功完成之前还需要配置一件事。
第 3 步 — 配置 AppArmor 访问控制规则
我们需要通过在默认目录和新位置之间创建别名来告诉 AppArmor 让 MySQL 写入新目录。 为此,请编辑 AppArmor alias
文件:
sudo nano /etc/apparmor.d/tunables/alias
在文件的底部,添加以下别名规则:
. . . [label /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.
systemctl
和 journalctl
的输出都以:
OutputJul 18 11:03:24 ubuntu-512mb-nyc1-01 systemd[1]: mysql.service: Main process exited, code=exited, status=1/FAILURE
由于这些消息没有在 AppArmor 和数据目录之间建立明确的联系,因此可能需要一些时间才能弄清楚这个错误。
第四步——重启 MySQL
下一步是启动 MySQL,但如果这样做,您将遇到另一个错误。 这一次,错误不是 AppArmor 问题,而是因为脚本 mysql-systemd-start
检查是否存在目录 -d
或符号链接 -L
,即匹配两个默认路径。 如果找不到它们,它将失败:
/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 sudo systemctl status mysql
要确保新数据目录确实在使用中,请启动 MySQL 监视器。
mysql -u root -p
再次查看数据目录的值:
Output+----------------------------+ | @@datadir | +----------------------------+ | /mnt/volume-nyc1-01/mysql/ | +----------------------------+ 1 row in set (0.01 sec)
现在您已重新启动 MySQL 并确认它正在使用新位置,请借此机会确保您的数据库功能齐全。 验证任何现有数据的完整性后,您可以删除备份数据目录:
sudo rm -Rf /var/lib/mysql.bak
最后一次重新启动 MySQL 以确保它按预期工作:
sudo systemctl restart mysql sudo systemctl status mysql
结论
在本教程中,我们将 MySQL 的数据目录移至新位置并更新了 Ubuntu 的 AppArmor ACL 以适应调整。 尽管我们使用的是块存储设备,但此处的说明应该适用于重新定义数据目录的位置,而不管底层技术如何。
有关管理 MySQL 数据目录的更多信息,请参阅 MySQL 官方文档中的以下部分: