1. 为什么需要迁移MariaDB数据目录?
作为一名长期与数据库打交道的运维工程师,我经常遇到系统盘空间不足导致数据库服务异常的情况。默认情况下,MariaDB会将数据文件存储在/var/lib/mysql目录下,而这个目录通常位于系统盘。随着业务数据增长,系统盘空间很快就会被占满,这时将数据目录迁移到更大的数据盘就成为必要操作。
迁移数据库文件目录看似简单,但实际上涉及多个关键环节:服务停止、数据迁移、权限设置、配置调整、SELinux上下文修复以及连接验证等。每个环节都可能隐藏着"坑",我在实际工作中就曾因为忽略SELinux配置导致数据库无法启动,也遇到过PHP应用无法连接新位置数据库socket的问题。
2. 迁移前的准备工作
2.1 环境检查与备份策略
在执行迁移前,有几项关键检查必须完成:
- 磁盘空间验证:使用
df -h命令确认目标数据盘有足够空间容纳当前数据库。建议空间至少是当前数据库大小的1.5倍。
bash复制du -sh /var/lib/mysql # 查看当前数据库大小
df -h /data # 查看目标磁盘空间
- 服务备份:虽然迁移过程不会删除原数据,但为防万一,建议完整备份:
bash复制sudo mysqldump --all-databases > full_backup.sql
sudo systemctl stop mariadb
sudo cp -a /var/lib/mysql /var/lib/mysql_backup
- 业务影响评估:迁移期间数据库服务不可用,需安排在业务低峰期进行,并提前通知相关人员。
2.2 目录结构与权限设置
创建新数据目录时,权限设置至关重要。MariaDB服务默认以mysql用户运行,因此新目录必须确保:
bash复制sudo mkdir -p /data/mysql
sudo chown mysql:mysql /data/mysql
sudo chmod 750 /data/mysql # mysql用户需有读写执行权限
注意:如果/data是单独挂载的分区,需确认挂载选项包含正确的SELinux上下文传递设置。可在/etc/fstab中添加
context="system_u:object_r:mysqld_db_t:s0"选项。
3. 数据迁移与配置调整
3.1 使用rsync进行可靠数据迁移
相比简单的cp命令,rsync更适合数据库文件迁移:
bash复制sudo rsync -av /var/lib/mysql/ /data/mysql/
参数说明:
-a:归档模式,保留所有文件属性-v:显示详细过程- 尾部斜杠/:确保复制目录内容而非目录本身
迁移完成后,务必验证文件完整性和数量:
bash复制sudo ls -l /data/mysql | wc -l
sudo ls -l /var/lib/mysql | wc -l
3.2 关键配置文件修改
MariaDB的主要配置文件通常位于/etc/my.cnf.d/mariadb-server.cnf,需要修改以下关键参数:
ini复制[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mariadb.log
pid-file=/data/mysql/mariadb.pid
修改后建议测试配置文件语法:
bash复制sudo mysqld --validate-config
3.3 SELinux上下文修复详解
SELinux是迁移过程中最常见的"拦路虎"。正确的上下文修复步骤:
- 安装必要工具(如未安装):
bash复制sudo yum install policycoreutils-python-utils
- 设置默认上下文规则:
bash复制sudo semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?"
- 如果遇到Python包错误(如pkg_resources问题),临时解决方案:
bash复制sudo vim /usr/lib64/python3.6/site-packages/setools/__init__.py
# 注释掉原版本检查行,添加:
__version__ = "4.3.0"
- 应用上下文规则:
bash复制sudo restorecon -Rv /data/mysql
验证上下文是否正确:
bash复制ls -Z /data/mysql
应显示system_u:object_r:mysqld_db_t:s0类似的上下文。
4. 服务恢复与连接测试
4.1 启动服务及问题排查
启动服务并检查状态:
bash复制sudo systemctl start mariadb
sudo systemctl status mariadb
常见启动问题及解决方案:
-
权限不足:
bash复制sudo chown -R mysql:mysql /data/mysql sudo chmod -R 750 /data/mysql -
SELinux阻止访问:
bash复制sudo ausearch -m avc -ts recent # 查看SELinux拒绝日志 sudo setenforce 0 # 临时禁用SELinux(仅用于测试) -
配置文件错误:
bash复制sudo journalctl -xe # 查看详细错误日志
4.2 PHP应用连接调整
当PHP应用出现"HY000/2002: No such file or directory"错误时,说明socket路径不匹配。解决方法:
-
确定PHP配置文件位置:
bash复制php --ini # CLI模式 php -i | grep "Configuration File" # Web模式 -
修改php.ini中的socket路径:
ini复制mysqli.default_socket = /data/mysql/mysql.sock pdo_mysql.default_socket = /data/mysql/mysql.sock mysql.default_socket = /data/mysql/mysql.sock -
重启Web服务:
bash复制sudo systemctl restart php-fpm # 或 sudo systemctl restart httpd -
验证连接:
php复制<?php phpinfo(); ?>在phpinfo输出中检查mysql.default_socket的值。
5. 迁移后的验证与优化
5.1 全面功能测试清单
为确保迁移成功,建议执行以下测试:
-
基本功能测试:
bash复制mysql -u root -p -e "SHOW DATABASES;" mysql -u root -p -e "CREATE DATABASE test_migration; DROP DATABASE test_migration;" -
性能测试:
bash复制
mysqlslap --concurrency=50 --iterations=10 --auto-generate-sql -
应用端测试:
- 执行关键业务查询
- 验证数据写入功能
- 检查报表生成等耗时操作
5.2 原数据清理策略
确认新位置数据库运行稳定后(建议观察至少24小时),可以清理原数据:
-
重命名原目录而非直接删除:
bash复制sudo mv /var/lib/mysql /var/lib/mysql_old -
创建符号链接(可选):
bash复制sudo ln -s /data/mysql /var/lib/mysql -
一周后确认无问题再删除备份:
bash复制sudo rm -rf /var/lib/mysql_old
5.3 长期维护建议
-
监控新位置磁盘空间:
bash复制df -h /data -
调整日志轮转配置(/etc/logrotate.d/mariadb):
bash复制
/data/mysql/mariadb.log { weekly rotate 4 compress missingok notifempty } -
更新备份脚本中的路径引用。
6. 高级技巧与故障处理
6.1 在线迁移方案(最小停机时间)
对于不能接受长时间停机的生产环境,可以考虑使用以下方案:
- 设置主从复制,先将从库迁移到新位置
- 主从切换后,再迁移原主库
- 或者使用LVM快照进行快速迁移
6.2 常见故障处理手册
| 故障现象 | 可能原因 | 解决方案 |
|---|---|---|
| 启动失败,日志显示"Permission denied" | SELinux或文件权限问题 | 检查ls -Z输出,修复上下文或权限 |
| PHP连接失败,但命令行可以连接 | socket路径不一致 | 检查所有php.ini文件中的socket设置 |
| 数据库表无法识别 | 文件复制不完整 | 重新执行rsync,确保使用-a参数 |
| 性能显著下降 | 数据盘IO性能差 | 检查磁盘性能:fio --filename=/data/test --rw=randrw --ioengine=libaio --direct=1 --name=test |
6.3 性能优化建议
-
如果/data是独立磁盘,考虑调整I/O调度器:
bash复制echo deadline > /sys/block/sdb/queue/scheduler -
在my.cnf中根据新硬件调整参数:
ini复制innodb_io_capacity = 2000 # 对于SSD innodb_flush_neighbors = 0 # SSD不需要此优化 -
考虑使用更高效的文件系统如XFS:
bash复制sudo mkfs.xfs /dev/sdb
迁移数据库文件目录是DBA和系统管理员的常见任务,看似简单却暗藏诸多细节。我在实际工作中总结的经验是:永远要有备份计划,逐步验证每个步骤,遇到问题时先查日志再动手。特别是在生产环境操作时,建议先在测试环境完整演练整个流程。