1
背景
創建文件及目錄時,我們會對相關的權限有一定的要求,默認的可以通過系統的umask來控制。然而,在我們使用MySQL時,無論是開始使用前的初始化,還是MySQL實例啟動后,創建的相關文件及目錄,并不受umask控制,MySQL 默認創建出來的文件權限是0660,目錄權限是0700,并且,在通過引入MySQL初始化相關的環境變量解決了這一問題后,在以不同的MySQL的啟動方式啟動實例后,創建的文件及目錄的權限也不相同。以下,將從幾個方面分別討論。
2
umask對系統文件及
目錄的影響
以下是linux man-page中對umask的相關描述:
從該描述中,可以看出,umask影響open、mkdir等其他系統調用產生的新的文件或目錄的權限。
2.1 umask對open函數的影響
open函數用到umask的相關形式為:
截取open函數的部分描述:
通過該段描述,當沒有默認的acl時,創建的文件的權限應為mode & ~umask,而一般情況下針對文件來說,系統默認的mode為0666(并不是所有的文件都可以執行),所以實際創建的文件權限應為 0666 & ~umask,當umask為0022時,創建出來的文件的權限應為0644。
2.2 umask對mkdir函數的影響
mkdir函數用的umask的相關形式:
截取相關描述:
在沒有默認acl的情況下,創建的目錄的權限為 mode & ~umask & 0777,一般情況下,目錄的默認的mode為0777,所以實際創建的目錄權限應為 0777 & ~umask & 0777,當umask為0022時,創建的目錄的權限應為0755。
2.3 參考資料
- [umask 參考](http://man7.org/linux/man-pages/man2/umask.2.html)
- [open 參考](http://man7.org/linux/man-pages/man2/open.2.html)
- [mkdir 參考](http://man7.org/linux/man-pages/man2/mkdir.2.html)
3
Umask對MySQL默認的影響
3.1 Umask對MySQL默認的影響
當umask=0022時,初始化后生成的文件及目錄權限:
可以看出創建出來的文件的權限為0660,目錄權限為0700,與系統umask并無關系。
實例啟動后,通過mysql連接數據庫,創建新的數據庫及表,查看權限:
新創建的文件及目錄權限為0660、0700,同樣與umask無關。
3.2 源碼層面分析
通過這段源碼可以看出,當沒有設置UMASK、UMASK_DIR環境變量時,MySQL默認創建文件及目錄的權限分別為0660、0700。
4
自定義MySQL相關文件及
目錄權限
4.1 初始化過程中文件及目錄的權限
4.1.1 方法
MySQL 提供另外一種方法,設置UMASK和UMASK_DIR環境變量,可以影響創建文件和目錄的權限:
The default UMASK and UMASK_DIR values are 0660 and 0700, respectively. MySQL assumes that the value forUMASK or UMASK_DIR is in octal if it starts with a zero. For example,setting UMASK=0600 is equivalent toUMASK=384 because 0600 octal is 384 decimal.
The UMASK and UMASK_DIR variables, despite their names, are used as modes, not masks:
If UMASK is set, mysqld uses ($UMASK | 0600) as the mode for file creation, so that newly created files have a mode in the range from 0600 to 0666 (all values octal).
If UMASK_DIR is set, mysqld uses ($UMASK_DIR | 0700) as the base mode for directory creation, which then is AND-ed with ~(~$UMASK & 0666), so that newly created directories have a mode in the range from 0700 to 0777 (all values octal). The AND operation may remove read and write permissions from the directory mode, but not execute permissions.
簡單的把核心內容翻譯一下,設置了UMASK及UMASK_DIR之后,生成的文件及目錄的權限應分別為:
如設置了UMASK=0664,UMASK_DIR=0774,在經過以上運算之后,生成的文件及目錄的權限應為0664,0774。
4.1.2 設置方式
設置這兩個環境變量的建議做法是,在用戶的/etc/skel/{bashrc, bash_profile} 文件和root用戶的.bashrc .bash_profile中加入:
4.1.3 驗證
驗證所用版本:mysql 5.6.31
系統umask:
UMASK、UMASK_DIR環境變量:
初始化后生成的文件及目錄權限為:
4.1.4 特殊的目錄權限
在初始化完成后,mysql、test文件夾的權限和預期不符,出現此種情況的原因為mysql、test文件夾的創建是通過scripts/mysql_install_db這個perl腳本實現的,找到相關的代碼如下,可以看出,這兩個文件夾的創建時的權限是固定的。
4.2 啟動及MySQL實例運行中創建文件及目錄的權限
啟動mysql 有兩種方式,/etc/init.d/mysql start 或 service mysql start,這兩種方式都能夠正確的啟動MySQL,但實際情況是有差別的,尤其是在設置了上述環境變量的情況下。
查看了service 命令的 manual,描述是這樣的:
DESCRIPTION
service runs a System V init script in as predictable environment as possible, removing most environment variables and with current working directory set to /.
通過驗證后確實如此,用service 命令啟動 會去掉UMASK環境變量:
4.2.1 驗證
啟動后,生成的mysql.err文件權限為0640,通過mysql連接數據庫,創建的新的database及table,查看權限:
實例運行后創建的文件及目錄權限為0660、0700,UMASK、UMASK_DIR環境變量未起作用。
4.2.1.1 源碼層面分析
使用service mysql start 啟動:
使用service mysql start 啟動不會產生 atoi_octal 函數調用,所以UMASK、UMASK_DIR環境變量沒有生效。
4.2.2 解決辦法
- 啟動腳本中加入 export UMASK等環境變量;
- 不使用service命令啟動。
驗證
驗證所用版本:mysql 5.6.31
以下,通過在每次啟動MySQL服務之前,刪除MySQL的錯誤日志,啟動之后查看生成的錯誤日志的權限來具體說明這個問題(本例中,錯誤日志為mysql.err),最初初始化生成的錯誤日志的權限為0664,即 rw-rw-r–。
啟動腳本中加入 export UMASK等環境變量:
啟動后mysql.err權限為0664,通過mysql連接數據庫,創建新的數據庫及表,查看權限:
新創建的文件及數據庫目錄的權限為0664、0774。
4.2.2.1 源碼層面分析
使用service啟動:
產生atoi_octal調用,UMASK、UMASK_DIR環境變量生效。
1. 不使用service命令啟動
啟動后生成的mysql.err權限仍為0664,通過mysql連接數據庫,創建新的數據庫及表,查看權限:
新創建的文件及數據庫目錄的權限為0664、0774。
4.2.2.2 源碼層面分析
使用/etc/init.d/mysql 啟動:
使用/etc/init.d/mysql start 啟動,產生atoi_octal函數調用,UMASK、UMASK_DIR環境變量生效。
4.2.3 特殊文件的權限
socket文件權限:
每次MySQL啟動之后產生的socket文件(本例中的mysql.sock)的權限與預期不符,通過查看相關源碼,以及相關socket文件生成的源碼,可以解釋該現象。
4.2.3.1 源碼層面分析
MySQL socket文件生成源碼:
socket文件生成的相關源碼:
4.3 總結
- 代碼中單獨定義了my_umask變量,并通過判斷環境變量來調整my_umask的值;
- 如果日志文件存在, 重啟時打開日志時并不會對文件權限變更;如果文件不存在,打開日志時會創建并設定文件權限。