磁碟空間不足、IO 隔離、備份掛載等場景需將 MySQL 資料目錄遷移至新分區/掛載點。核心原則:服務停止 → 資料同步 (保留屬性/權限/SELinux) → 修改配置 → 更新 Socket/啟動腳本 → 驗證啟動。
systemctl stop mysqld
# 或 service mysqld stop
# 掛載新分區至 /home/mysql_data (假設已完成)
# 使用 rsync 保留權限、擁有者、時間戳、SELinux 標籤
rsync -avXS /var/lib/mysql/ /home/mysql_data/mysql/
# 驗證
ls -ld /var/lib/mysql /home/mysql_data/mysql
# 應同屬 mysql:mysql,目錄 700,檔案 660
| 檔案 | 修改項目 | 備註 |
|---|---|---|
| /etc/my.cnf | datadir=/home/mysql_data/mysql socket=/home/mysql_data/mysql/mysql.sock | 主配置,[mysqld] 區段 |
| /etc/init.d/mysqld | datadir=/home/mysql_data/mysql | SysV 啟動腳本變量 |
| /usr/bin/mysqld_safe | DATADIR=/home/mysql_data/mysql | mysqld_safe 腳本內變量 |
建議:修改前備份 cp file file.bak。
mkdir -p /var/lib/mysql # 確保目錄存在
ln -sf /home/mysql_data/mysql/mysql.sock /var/lib/mysql/mysql.sock
# 安裝工具
yum install -y policycoreutils-python-utils
# 為新目錄套用 mysqld_db_t 標籤
semanage fcontext -a -t mysqld_db_t "/home/mysql_data/mysql(/.*)?"
restorecon -Rv /home/mysql_data/mysql
# 或者暫時設為 Permissive 驗證 (生產不可取)
# setenforce 0
systemctl start mysqld
systemctl status mysqld
# 連線測試
mysql -uroot -p -e "SHOW VARIABLES LIKE 'datadir'; SELECT @@datadir;"
# 應顯示 /home/mysql_data/mysql/
| 現象 | 原因 | 解決 |
|---|---|---|
| 啟動失敗,日誌 Permission denied | 目錄/檔案擁有者非 mysql:mysql 或權限錯誤 | chown -R mysql:mysql /home/mysql_data/mysql; chmod 700 /home/mysql_data/mysql; find /home/mysql_data/mysql -type f -exec chmod 660 {} \; |
| 啟動失敗,SELinux 拒絕 | 新目錄缺少 mysqld_db_t 標籤 | 執行步驟 5 restorecon |
| 客戶端連線失敗 Can't connect to socket | Socket 路徑不一致 | 檢查 my.cnf socket 路徑與軟連結;客戶端指定 --socket=/home/mysql_data/mysql/mysql.sock 或 --protocol=tcp |
| AppArmor 拒絕 | Ubuntu/Debian AppArmor 設定檔限制 | 修改 /etc/apparmor.d/usr.sbin.mysqld 加入新路徑,重載 apparmor |
SHOW VARIABLES LIKE 'datadir' 指向新路徑。df -h /var 確認空間釋放。