CentOS 6.2 環境下,修改 /etc/my.cnf 中 datadir 至新路徑 /mnt/hgfs/mysql_data 後,MySQL 啟動失敗,日誌顯示 Errcode: 13 (Permission denied)。目錄權限 777、擁有者 root、上層目錄有 rx 權限,表面看無問題,實為 SELinux 安全上下文阻擋。
120609 11:35:13 [Warning] Can't create test file /mnt/hgfs/mysql_data/data.lower-test
/usr/libexec/mysqld: Can't change dir to '/mnt/hgfs/mysql_data/' (Errcode: 13)
[ERROR] Aborting
關鍵線索: Errcode: 13 為系統調用 EACCES,權限被拒,但 Linux DAC (Discretionary Access Control) 權限 (rwx) 已全開,必須是 MAC (Mandatory Access Control) —— 即 SELinux 在作祟。
# 查看當前模式
getenforce
# Enforcing (強制模式)
# 臨時設為寬容模式 (不攔截,只記錄日誌)
setenforce 0
getenforce
# Permissive
執行後 MySQL 即可正常啟動,確認為 SELinux 策略阻擋。
vi /etc/selinux/config
# 修改
SELINUX=disabled
# 重啟系統生效
reboot
配置檔完整內容參考:
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
vi /etc/selinux/config
SELINUX=permissive
reboot
優勢: 保留審計日誌,安全審計合規;劣勢: 實際不攔截違規操作。
# 1. 檢查當前上下文
ls -Z /mnt/hgfs/mysql_data
# 可能顯示:unconfined_u:object_r:vmblock_t:s0 (錯誤類型)
# 2. 設定正確的 MySQL 資料目錄上下文
semanage fcontext -a -t mysqld_db_t "/mnt/hgfs/mysql_data(/.*)?"
restorecon -Rv /mnt/hgfs/mysql_data
# 3. 驗證
ls -Z /mnt/hgfs/mysql_data
# 應顯示:system_u:object_r:mysqld_db_t:s0
前置條件: 需安裝 policycoreutils-python (含 semanage)。
| 層面 | 說明 |
|---|---|
| 掛載來源 | VMware 共享資料夾 (Windows 檔案系統掛載至 Linux) |
| 檔案系統 | 宿主機 NTFS,客體機透過 vmhgfs-fuse 掛載 |
| 擁有者 | 掛載點預設為 root:root,無法透過 chown 改變 (NTFS 特性) |
| SELinux 策略 | mysqld_t 進程類型僅允許存取 mysqld_db_t 類型的檔案/目錄 |
| 衝突點 | vmblock_t (VMware 共享預設類型) ≠ mysqld_db_t,被策略拒絕 |
# 重啟 SELinux 為 Enforcing
setenforce 1
# 或重啟系統
# 啟動 MySQL
service mysqld start
# 應顯示 SUCCESS
# 確認資料目錄
mysql -e "SHOW VARIABLES LIKE 'datadir';"
# +---------------+------------------------+
# | Variable_name | Value |
# +---------------+------------------------+
# | datadir | /mnt/hgfs/mysql_data/ |
# +---------------+------------------------+
ls -Z/var/lib/mysql 已預設正確上下文,避免自訂路徑semanage fcontext -a -t mysqld_db_t "/path(/.*)?" && restorecon -Rv /path