在MySQL中,my.cnf是參數文件(Option Files),類似於ORACLE資料庫中的spfile、pfile參數文件,照理說,參數文件my.cnf中的都是系統參數(這種稱呼比較符合思維習慣),但是官方又稱呼其為系統變數(system variables),那麼到底這個叫系統參數或系統變數... ...
在MySQL中,my.cnf是參數文件(Option Files),類似於ORACLE資料庫中的spfile、pfile參數文件,照理說,參數文件my.cnf中的都是系統參數(這種稱呼比較符合思維習慣),但是官方又稱呼其為系統變數(system variables),那麼到底這個叫系統參數或系統變數(system variables)呢? 這個曾經是一個讓我很糾結的問題,因為MySQL中有各種類型的變數,有時候語言就是這麼博大精深;相信很多人也對這個問題或多或少有點困惑。其實拋開這些名詞,它們就是同一個事情(東西),不管你叫它系統變數(system variables)或系統參數都可,無需那麼糾結。 就好比王三,有人叫他王三;也有人也叫他王麻子綽號一樣。
另外,MySQL中有很多變數類型,確實有時候讓人有點混淆不清,本文打算總結一下MySQL資料庫的各種變數類型,理清各種變數類型概念。能夠從全局有個清晰思路。MySQL變數類型具體參考下圖:
Server System Variables(系統變數)
MySQL系統變數(system variables)是指MySQL實例的各種系統變數,實際上是一些系統參數,用於初始化或設定資料庫對系統資源的占用,文件存放位置等等,這些變數包含MySQL編譯時的參數預設值,或者my.cnf配置文件里配置的參數值。預設情況下系統變數都是小寫字母。官方文檔介紹如下:
The MySQL server maintains many system variables that indicate how it is configured. Each system variable has a default value. System variables can be set at server startup using options on the command line or in an option file. Most of them can be changed dynamically at runtime using the SET statement, which enables you to modify operation of the server without having to stop and restart it. You can also use system variable values in expressions.
系統變數(system variables)按作用域範圍可以分為會話級別系統變數和全局級別系統變數。如果要確認系統變數是全局級別還是會話級別,可以參考官方文檔,如果Scope其值為GLOBAL或SESSION,表示變數既是全局級別系統變數,又是會話級別系統變數。如果其Scope其值為GLOBAL,表示系統變數為全局級別系統變數。
--查看系統變數的全局值
select * from information_schema.global_variables;
select * from information_schema.global_variables
where variable_name='xxxx';
select * from performance_schema.global_variables;
--查看系統變數的當前會話值
select * from information_schema.session_variables;
select * from information_schema.session_variables
where variable_name='xxxx';
select * from performance_schema.session_variables;
SELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;
mysql> show variables like '%connect_timeout%';
mysql> show local variables like '%connect_timeout%';
mysql> show session variables like '%connect_timeout%';
mysql> show global variables like '%connect_timeout%';
註意:對於SHOW VARIABLES,如果不指定GLOBAL、SESSION或者LOCAL,MySQL返回SESSION值,如果要區分系統變數是全局還是會話級別。不能使用下麵方式,如果某一個系統變數是全局級別的,那麼在當前會話的值也是全局級別的值。例如系統變數AUTOMATIC_SP_PRIVILEGES,它是一個全局級別系統變數,但是 show session variables like '%automatic_sp_privileges%'一樣能查到其值。所以這種方式無法區別系統變數是會話級別還是全局級別。
mysql> show session variables like '%automatic_sp_privileges%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| automatic_sp_privileges | ON |
+-------------------------+-------+
1 row in set (0.00 sec)
mysql> select * from information_schema.global_variables
-> where variable_name='automatic_sp_privileges';
+-------------------------+----------------+
| VARIABLE_NAME | VARIABLE_VALUE |
+-------------------------+----------------+
| AUTOMATIC_SP_PRIVILEGES | ON |
+-------------------------+----------------+
1 row in set, 1 warning (0.00 sec)
mysql>
如果要區分系統變數是全局還是會話級別,可以用下麵方式:
方法1: 查官方文檔中系統變數的Scope屬性。
方法2: 使用SET VARIABLE_NAME=xxx; 如果報ERROR 1229 (HY000),則表示該變數為全局,如果不報錯,那麼證明該系統變數為全局和會話兩個級別。
mysql> SET AUTOMATIC_SP_PRIVILEGES=OFF;
ERROR 1229 (HY000): Variable 'automatic_sp_privileges' is a GLOBAL variable and should be set with SET GLOBAL
可以使用SET命令修改系統變數的值,如下所示:
修改全局級別系統變數:
SET GLOBAL max_connections=300;
SET @@global.max_connections=300;
註意:更改全局變數的值,需要擁有SUPER許可權
修改會話級別系統變數:
SET @@session.max_join_size=DEFAULT;
SET max_join_size=DEFAULT; --預設為會話變數。如果在變數名前沒有級別限定符,表示修改會話級變數。
SET SESSION max_join_size=DEFAULT;
如果修改系統全局變數沒有指定GLOBAL或@@global的話,就會報“Variable 'xxx' is a GLOBAL variable and should be set with SET GLOBAL”這類錯誤。
mysql> set max_connections=300;
ERROR 1229 (HY000): Variable 'max_connections' is a GLOBAL variable and should be set with SET GLOBAL
mysql> set global max_connections=300;
Query OK, 0 rows affected (0.00 sec)
mysql>
系統變數(system variables)按是否可以動態修改,可以分為系統動態變數(Dynamic System Variables)和系統靜態變數。怎麼區分系統變數是動態和靜態的呢? 這個只能查看官方文檔,系統變數的"Dynamic"屬性為Yes,則表示可以動態修改。Dynamic Variable具體可以參考https://dev.mysql.com/doc/refman/5.7/en/dynamic-system-variables.html
另外,有些系統變數是只讀的,不能修改的。如下所示: