在MySQL中,它是按什麼順序或規律去讀取my.cnf配置文件的呢?其實只要你花一點功夫,實驗測試一下就能弄清楚,下麵的實驗環境為5.7.21 MySQL Community Server。其它版本如有不同,請以實際情況為準。 其實,MySQL是按照下麵這個順序來讀取my.cnf: 1: /etc/... ...
在MySQL中,它是按什麼順序或規律去讀取my.cnf配置文件的呢?其實只要你花一點功夫,實驗測試一下就能弄清楚,下麵的實驗環境為5.7.21 MySQL Community Server。其它版本如有不同,請以實際情況為準。
其實,MySQL是按照下麵這個順序來讀取my.cnf:
1: /etc/my.cnf
2: /etc/mysql/my.cnf
3: /usr/etc/my.cnf
4: ~/.my.cnf
也就是說首先它會找/etc/my.cnf 這個文件, 如果這個文件不存在,那麼它接下來去找/etc/mysql/my.cnf這個文件,依此類推(這個實驗很簡單,在此略過,不浪費篇幅),如果最後一個文件~/.my.cnf 也不存在,那麼會怎麼樣呢?
[root@gettestlnx02 ~]# mysql --help | grep my.cnf
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
[root@gettestlnx02 ~]# ls /etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
ls: cannot access /etc/mysql/my.cnf: No such file or directory
ls: cannot access /usr/etc/my.cnf: No such file or directory
ls: cannot access /root/.my.cnf: No such file or directory
/etc/my.cnf
[root@gettestlnx02 ~]#
如上所示,其實MySQL安裝完成後,只生成了/etc/my.cnf這個配置文件。其它路徑的my.cnf文件是不存在的。我們先來測試一下,將配置文件移走。在這之前,我們先查看一下log_error的位置。如下所示:
mysql> show variables like '%log_error%';
+---------------------+---------------------+
| Variable_name | Value |
+---------------------+---------------------+
| binlog_error_action | ABORT_SERVER |
| log_error | /var/log/mysqld.log |
| log_error_verbosity | 3 |
+---------------------+---------------------+
3 rows in set (0.00 sec)
mysql> exit
Bye
[root@gettestlnx02 ~]# mv /etc/my.cnf /tmp/my.cnf
[root@gettestlnx02 ~]# ls -lrt /etc/my.cnf
ls: cannot access /etc/my.cnf: No such file or directory
[root@gettestlnx02 ~]# service mysqld stop
Stopping mysqld: [ OK ]
[root@gettestlnx02 ~]# service mysqld start
Starting mysqld: [ OK ]
[root@gettestlnx02 ~]#
如上所示,即使沒了my.cnf配置文件,MySQL服務依然可以啟動,那麼這個是怎麼回事呢? 我們知道service mysqld start啟動MySQL,其實是運行/etc/init.d/mysqld這個腳本。下麵是腳本獲取給變數datadir、socketfile、errlogifle賦值的部分腳本,如下所示:
# Extract value of a MySQL option from config files
# Usage: get_mysql_option OPTION DEFAULT SECTION1 SECTION2 SECTIONN
# Result is returned in $result
# We use my_print_defaults which prints all options from multiple files,
# with the more specific ones later; hence take the last match.
get_mysql_option () {
option=$1
default=$2
shift 2 #移動到第3個參數,詳情見下麵調試。
result=$(/usr/bin/my_print_defaults "$@" | sed -n "s/^--${option}=//p" | tail -n 1)
if [ -z "$result" ]; then
# not found, use default
result="${default}"
fi
}
get_mysql_option datadir "/var/lib/mysql" mysqld
datadir="$result"
get_mysql_option socket "$datadir/mysql.sock" mysqld
socketfile="$result"
get_mysql_option log-error "/var/log/mysqld.log" mysqld mysqld_safe
errlogfile="$result"
get_mysql_option pid-file "/var/run/mysqld/mysqld.pid" mysqld mysqld_safe
mypidfile="$result"
如果你對shell很熟,那麼可以忽略下麵步驟,如果不熟悉,那麼我們可以手工調試一下(# sh -x mysqld),看看它是如何獲取相關變數的值的呢?
[root@gettestlnx02 ~]# file /usr/bin/my_print_defaults
/usr/bin/my_print_defaults: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
[root@gettestlnx02 ~]# /usr/bin/my_print_defaults mysqld
[root@gettestlnx02 ~]#
如上所示,因為/usr/bin/my_print_defaults mysqld輸出為空,所以result為空值, 所以result被授予${default}的值,而defualt=$2,其實就是第二個變數,如下所示,第二個變數被標記為紅色。
get_mysql_option datadir "/var/lib/mysql" mysqld
datadir="$result"
另外,my.cnf的位置是會影響腳本輸出結果的。如下所示:(不在幾個預設路徑的話,my_print_defaults是沒有輸出結果的)
[root@gettestlnx02 ~]# ls /tmp/my.cnf
/tmp/my.cnf
[root@gettestlnx02 ~]# /usr/bin/my_print_defaults mysqld
[root@gettestlnx02 ~]# mv /tmp/my.cnf /etc/my.cnf
[root@gettestlnx02 ~]# /usr/bin/my_print_defaults mysqld
--datadir=/var/lib/mysql
--socket=/var/lib/mysql/mysql.sock
--symbolic-links=0
--log-error=/var/log/mysqld.log
--pid-file=/var/run/mysqld/mysqld.pid
接下來,我們將配置文件my.cnf挪回原位(/etc/my.cnf),然後更改資料庫數據存儲目錄(從/var/lib/mysql挪動到/data/mysqldata/mysql 步驟從略),然後我們再做下麵測試: