在生產環境中,有時候你會遇到一些看似簡單但實際上很棘手的問題。最近我就碰到了一次典型的服務器磁盤空間告急,最后通過遷移 MySQL 數據目錄成功解決了問題。本文記錄整個過程,包括我的分析思路、遷移步驟、踩坑和經驗總結,希望對你有幫助。
一、問題背景
公司的一臺業務數據庫服務器,運行的是 MySQL 8.0.20,數據目錄默認放在:
/data/mysql-8.0.20/data
隨著業務數據的增長,/data
分區的空間漸漸被吃滿,監控報警開始提示:
Disk space usage on /data exceeds 98%
打開 df -h
一看,果然 /data
分區只剩不到 1GB,而 /home
分區卻很空閑,有幾十 MB 可用。
二、分析思路
-
確認空間問題是否由 MySQL 引起
du -sh /data/mysql-8.0.20/data
結果:
38G /data/mysql-8.0.20/data
→ 明確是 MySQL 數據目錄占了大頭。
-
能否擴容
/data
分區?- 由于這臺是虛擬機,業務部門不方便短期擴容。
- 考慮將數據目錄遷移至磁盤更大的
/home
分區。
-
遷移 MySQL 數據目錄的關鍵點
- 必須 停庫遷移,否則數據會不一致。
- 遷移后需要修改 配置文件 datadir。
- 新路徑權限必須正確(
mysql:mysql
,SELinux 要處理)。 - 遷移過程要有 回退方案(先復制,驗證成功后再刪舊數據)。
三、實現步驟
在正式進行遷移前,我們先看一下整個遷移的流程圖,幫助你對后續的步驟有直觀印象。
1. 停止 MySQL 服務
sudo systemctl stop mysqld
ps -ef | grep mysqld # 確認進程關閉
2. 創建新目錄
sudo mkdir -p /home/mysql/data
3. 遷移數據
建議先復制,確保安全:
sudo cp -av /data/mysql-8.0.20/data/* /home/mysql/data/
(等驗證 OK 再刪除舊目錄)
4. 修改 MySQL 配置
編輯 /etc/my.cnf
(路徑可能不同,根據實際環境調整):
[mysqld]
datadir=/home/mysql/data
socket=/home/mysql/data/mysql.sock[client]
socket=/home/mysql/data/mysql.sock
5. 更新權限
sudo chown -R mysql:mysql /home/mysql/data
sudo chmod 750 /home/mysql/data
6. SELinux 處理(重要)
CentOS / RHEL 默認 /home 屬于 home_t
類型,MySQL 無法直接訪問,需要修改安全上下文:
查看 SELinux 狀態:
getenforce
如果輸出 Enforcing
,執行:
sudo semanage fcontext -a -t mysqld_db_t "/home/mysql/data(/.*)?"
sudo restorecon -Rv /home/mysql/data
(如果只是驗證,可以先用 setenforce 0
暫時關閉 SELinux)
7. 啟動 MySQL
sudo systemctl start mysqld
8. 驗證新目錄生效
SHOW VARIABLES LIKE 'datadir';
結果應為:
/home/mysql/data/
9. 清理舊目錄
確認 MySQL 穩定運行幾天再刪除舊目錄:
sudo rm -rf /data/mysql-8.0.20/data
四、踩坑記錄
在遷移過程中我踩了一些坑,也分享出來避免大家踩同樣的雷:
-
忘記改權限 → 啟動失敗
The server quit without updating PID file
解決:
chown -R mysql:mysql /home/mysql/data
-
SELinux 拒絕訪問新目錄
- 關閉 SELinux 后啟動成功 → 說明是安全上下文問題
- 永久解決:使用
semanage fcontext
和restorecon
修改為mysqld_db_t
-
客戶端連接失敗
- 因為 socket 文件路徑變了,要同步修改
[client]
部分的socket
配置
- 因為 socket 文件路徑變了,要同步修改
五、經驗總結
-
生產環境操作一定要有回退方案
- 先
cp
而不是直接mv
- 保留舊數據目錄,確認沒問題后再刪
- 先
-
權限和 SELinux 是 MySQL 無法啟動的核心原因
- 遷移路徑后務必
chown
+ SELinux 規則調整
- 遷移路徑后務必
-
提前規劃數據目錄的位置
- 盡量放在可擴容的分區,或者掛載點規劃時預留足夠磁盤空間
-
驗證后再清理
- 保留一段時間舊目錄,是救命稻草
六、參考命令速查表
# 停mysql
systemctl stop mysqld# 拷貝數據目錄
cp -av /data/mysql-8.0.20/data/* /home/mysql/data/# 修改配置文件
vim /etc/my.cnf# 權限
chown -R mysql:mysql /home/mysql/data
chmod 750 /home/mysql/data# SELinux規則調整
semanage fcontext -a -t mysqld_db_t "/home/mysql/data(/.*)?"
restorecon -Rv /home/mysql/data# 啟動MySQL
systemctl start mysqld# 驗證數據目錄
SHOW VARIABLES LIKE 'datadir';
💡 寫在最后
這次遷移雖然只是換了個目錄,但背后體現的是處理 🛠 生產問題的三個關鍵能力:
- 快速定位根因
- 制定低風險方案
- 預留回退路徑
實際生產中,看似瑣碎的小問題,通過“按步驟 + 防風險”去執行,才不會把小問題變成大事故。