yum/rpm 安裝 MySQL 時,`datadir` 預設為 `/var/lib/mysql`。為提升 I/O 效能、隔離系統盤與資料盤、滿足合規要求,常需遷移至獨立掛載點(如 `/data/mysql` 或 `/home/mysql`)。本文提供標準化、可驗證的遷移流程。
# 確認當前 datadir
mysql -u root -p -e "SHOW VARIABLES LIKE 'datadir';"
# 確認目標分區掛載點與剩餘空間
df -h /data
ls -ld /data/mysql 2>/dev/null || echo "目標目錄不存在,將自動建立"
systemctl stop httpd # 或 service httpd stop
systemctl stop mysqld # 或 service mysqld stop
mv /var/lib/mysql /data/mysql
# 若目標父目錄不存在:mkdir -p /data && mv /var/lib/mysql /data/
為何用 mv 而非 cp?
`mv` 在同一檔案系統內僅修改目錄項,瞬間完成,且完整保留 inode、權限、SELinux 標籤(`context`)。`cp -a` 雖也保留屬性,但跨檔案系統時需重新寫入資料,耗時且易遺漏 SELinux 上下文,導致後續啟動被 SELinux 攔截。
[mysqld]
# datadir=/var/lib/mysql # 註釋舊路徑
datadir=/data/mysql # 新路徑
# socket=/var/lib/mysql/mysql.sock
socket=/data/mysql/mysql.sock
[mysqld_safe]
socket=/data/mysql/mysql.sock
[client]
socket=/data/mysql/mysql.sock
[mysql.server]
socket=/data/mysql/mysql.sock
PHP PDO/MySQLi 預設讀取 `mysql.default_socket`,若為空則 fallback 至編譯時預設(通常 `/var/lib/mysql/mysql.sock`),**必須顯式指定新路徑**,否則 PHP 應用無法連線。
[mysql]
mysql.default_socket = /data/mysql/mysql.sock
[mysqli]
mysqli.default_socket = /data/mysql/mysql.sock
[pdo_mysql]
pdo_mysql.default_socket = /data/mysql/mysql.sock
# 檢查目標目錄 SELinux 標籤
ls -Z /data/mysql
# 應為:system_u:object_r:mysqld_db_t:s0
# 若標籤不正確,恢復預設標籤
restorecon -Rv /data/mysql
# 或臨時關閉 SELinux 驗證(不建議生產環境)
# setenforce 0
systemctl start mysqld
systemctl start httpd
# 驗證 datadir 生效
mysql -u root -p -e "SHOW VARIABLES LIKE 'datadir';"
# 驗證 PHP 連線
php -r "$mysqli = new mysqli('localhost', 'root', 'pass'); var_dump($mysqli->connect_errno);"
| 現象 | 原因 | 解決 |
|---|---|---|
| MySQL 啟動失敗,日誌顯示 Permission denied | 目錄擁有者非 mysql:mysql,或 SELinux 封鎖 | `chown -R mysql:mysql /data/mysql` + `restorecon -Rv /data/mysql` |
| PHP 連線報 "Can't connect to local MySQL server through socket" | `php.ini` 未更新 socket 路徑 | 修改 `php.ini` 三處 `default_socket`,重啟 php-fpm/httpd |
| 遷移後資料表損壞/丟失 | 移動前未完全停止寫入,或用 `cp` 遺漏隱藏檔 | 嚴格遵循「停服務 → mv → 改配置 → 啟動」順序 |
| 錯誤日誌報 "Unknown/unsupported storage engine: InnoDB" | `ibdata1`、`ib_logfile*` 路徑錯誤或權限問題 | 確認 `innodb_data_home_dir`、`innodb_log_group_home_dir` 或預設在 `datadir` 下 |
Linux 下 MySQL `datadir` 遷移核心在於:**停服務 → mv 保留屬性 → 改雙端配置 → SELinux 恢復標籤 → 啟動驗證**。嚴格遵循流程可將風險降至最低,避免「服務啟動了但應用連不上」或「SELinux 暗坑」等典型問題。