搞懂這三個命令的區別,核心是 變量作用域(全局 / 會話),你的部分理解需要修正 ——
show VARIABLES 並非 “疊加”,而是默認顯示「當前會話生效的變量」;session 和 global 變量也並非數量一致,而是有 “僅全局”“僅會話”“兩者都有” 三類情況。下面分步驟講清楚:
一、核心區別:作用域與顯示邏輯
三者的本質差異是 查詢的變量作用域不同,且
show VARIABLES 有默認行為,具體對比如下:
| 命令 | 作用域 | 含義(顯示什麼) | 生效範圍 | 修改方式(示例) |
|---|---|---|---|---|
show GLOBAL VARIABLES |
全局(實例級) | MySQL 實例的全局配置,對 所有新連接 生效(已存在的會話不受影響) | 整個數據庫實例 | SET GLOBAL sql_mode = 'XXX';(需 SUPER 權限) |
show SESSION VARIABLES |
會話(連接級) | 當前數據庫連接的專屬配置,僅對 當前連接 生效(斷開連接後失效) | 僅當前連接 | SET SESSION sql_mode = 'XXX';(普通權限即可) |
show VARIABLES |
默認 = 會話級(可省略 SESSION) | 等價於 show SESSION VARIABLES,顯示 當前會話正在使用的變量值 |
僅當前連接 | 同 show SESSION VARIABLES |
關鍵糾正你的誤解:
- 不是 “疊加”:
show VARIABLES只顯示「當前會話生效的變量」,而非同時顯示 global 和 session。其值的來源是:如果當前會話修改過某個變量,就顯示修改後的 session 值;如果沒修改過,就顯示繼承自 global 的默認值。例:global 的sql_mode是'',當前會話執行SET SESSION sql_mode = 'STRICT_TRANS_TABLES'後,show VARIABLES like 'sql_mode'會顯示修改後的 session 值,而非同時顯示兩個值。
二、直觀例子:看懂 session 與 global 的優先級
假設場景:
- 全局變量
sql_mode為''(寬鬆模式); - 你當前會話執行
SET SESSION sql_mode = 'STRICT_TRANS_TABLES'(嚴格模式);
此時查詢結果:
sql
-- 顯示全局配置(未變)
show GLOBAL VARIABLES like 'sql_mode'; -- 結果:''
-- 顯示當前會話配置(已修改)
show SESSION VARIABLES like 'sql_mode'; -- 結果:'STRICT_TRANS_TABLES'
-- 等價於上面的 SESSION,顯示當前生效的配置
show VARIABLES like 'sql_mode'; -- 結果:'STRICT_TRANS_TABLES'
結論:同一變量,session 優先級 > global(當前會話優先用自己的配置,沒有則繼承 global)。
三、session 變量 vs global 變量:數量與範圍
你的第二個問題:“session 變量允許有哪些?是不是和 global 一樣多?”
答案:不一樣多。MySQL 的變量分為三類,決定了兩者的範圍差異:
1. 僅全局變量(無對應 session 變量)
這類變量是數據庫實例的 “基礎配置”,無法在會話級別修改,只能全局設置。
- 例子:
datadir(數據存儲目錄)、port(監聽端口)、max_connections(最大連接數)、innodb_buffer_pool_size(InnoDB 緩衝池大小)。 - 特點:
show SESSION VARIABLES查不到這些變量,只能通過show GLOBAL VARIABLES查看。
2. 僅會話變量(無對應 global 變量)
這類變量和 “當前連接的操作狀態” 相關,僅存在於會話中,不影響全局。
- 例子:
insert_id(手動指定的下一個自增 ID)、last_insert_id(當前會話最後插入的自增 ID)、sql_safe_updates(當前會話的安全更新模式)。 - 特點:
show GLOBAL VARIABLES查不到這些變量,只能通過show SESSION VARIABLES查看。
3. 既全局又會話的變量(最常見)
這類變量有全局默認值,每個會話會繼承初始值,但可以在會話中單獨修改(不影響全局)。
- 例子:
sql_mode(SQL 模式)、wait_timeout(連接超時時間)、character_set_client(客户端字符集)、max_join_size(關聯查詢的最大行數限制)。 - 特點:
show GLOBAL和show SESSION都能查到,但值可能不同(會話修改後)。
總結數量關係:
session 變量總數 ≠ global 變量總數,兩者有重疊(第三類),但各有獨有的變量(第一、二類)。
四、補充注意點
- 全局變量修改後,已存在的會話不生效,只有新連接會繼承新的全局值;
- 有些變量即使是 “既全局又會話”,修改 session 級也可能無效(比如
innodb_buffer_pool_size,雖然能查 session 值,但修改後不生效,因為是共享資源,只能全局配置); - 權限要求:修改 global 變量需要
SUPER權限(或 MySQL 8.0+ 的SYSTEM_VARIABLES_ADMIN權限),修改 session 變量一般不需要特殊權限; - 簡寫:
show LOCAL VARIABLES等價於show SESSION VARIABLES(LOCAL 是 SESSION 的別名)。
最終總結
show GLOBAL VARIABLES:查實例級全局配置,影響所有新連接;show SESSION VARIABLES:查當前連接的專屬配置,僅影響當前連接;show VARIABLES:默認查 SESSION 變量,即當前會話正在使用的配置(優先用自己的,沒有則繼承 global);- session 和 global 變量數量不同,有 “僅全局”“僅會話”“兩者都有” 三類,同名變量的會話值會覆蓋全局值(僅當前連接)。
如何得知 當前session 有修改過哪些變量? 難道只能一個個的比對嗎
不需要一個個手動比對!MySQL 提供了 系統表查詢 + 變量來源追蹤 的高效方法,能直接篩選出當前會話中被修改過的變量(即「會話值≠全局默認值」的變量)。以下是兩種最實用的方案,適配不同 MySQL 版本:
核心邏輯
會話變量的初始值默認繼承自全局變量,只有「手動修改過」或「連接時自動適配」的變量,才會和全局值不一致。因此,找出「會話值≠全局值」且「變量同時存在於全局和會話」的記錄,就是當前會話修改過的變量(排除會話獨有變量)。
方案一:通用方案(MySQL 5.7+ 兼容)
利用
information_schema 中的 GLOBAL_VARIABLES 和 SESSION_VARIABLES 兩張系統表,直接關聯比對同名變量的值,差異結果就是修改過的變量。
直接可用的 SQL 語句
sql
-- 找出當前會話中,與全局值不同的變量(即修改過的變量)
SELECT
s.VARIABLE_NAME, -- 變量名
g.VALUE AS GLOBAL_VALUE, -- 全局默認值
s.VALUE AS SESSION_VALUE -- 會話修改後的值
FROM
information_schema.GLOBAL_VARIABLES g
INNER JOIN
information_schema.SESSION_VARIABLES s
ON
g.VARIABLE_NAME = s.VARIABLE_NAME -- 只比對「既有全局又有會話」的變量(排除獨有變量)
WHERE
-- 注意:用 CAST 統一類型,避免因變量類型不同導致的比對失敗(比如數字 vs 字符串)
CAST(g.VALUE AS CHAR) != CAST(s.VALUE AS CHAR)
ORDER BY
s.VARIABLE_NAME;
效果説明
- 結果會列出所有「會話值≠全局值」的變量,這些變量要麼是你手動
SET SESSION修改的,要麼是連接時 MySQL 自動適配的(比如字符集相關變量,若客户端和全局默認字符集不同)。 - 排除了「僅全局變量」(如
datadir)和「僅會話變量」(如last_insert_id),只聚焦於「可修改且有全局默認值」的變量(正是你關心的 “可能被修改” 的變量)。
方案二:精準方案(MySQL 8.0.11+ 推薦)
MySQL 8.0.11 及以上版本,新增了
performance_schema.variables_info 表,其中 VARIABLE_SOURCE 字段直接記錄了「會話變量值的來源」,無需比對,直接篩選來源為 SESSION 的變量即可,更精準高效。
直接可用的 SQL 語句
sql
-- 精準找出當前會話中「手動修改過」的變量(來源為 SESSION)
SELECT
VARIABLE_NAME, -- 變量名
VARIABLE_VALUE AS SESSION_VALUE, -- 會話修改後的值
VARIABLE_SOURCE AS 來源 -- 來源:SESSION=手動修改;GLOBAL=繼承全局;COMMAND_LINE=命令行啓動參數等
FROM
performance_schema.variables_info
WHERE
-- VARIABLE_SOURCE 取值説明:
-- SESSION:會話中手動修改過(核心目標)
-- GLOBAL:繼承全局默認值(未修改)
-- COMMAND_LINE:MySQL 啓動時指定的參數
-- CONFIG_FILE:my.cnf/my.ini 配置文件
VARIABLE_SOURCE = 'SESSION'
ORDER BY
VARIABLE_NAME;
優勢
- 無需關聯兩張表,查詢速度更快;
- 能精準區分「手動修改」(來源
SESSION)和「自動適配 / 繼承」(來源GLOBAL),避免誤判(比如字符集變量可能因客户端配置自動變化,並非手動修改,方案一會列出,方案二可排除)。
補充説明(避坑)
-
變量類型比對問題:部分變量的全局值和會話值類型可能不同(比如
max_connections是數字,sql_mode是字符串),方案一中用CAST(xxx AS CHAR)統一轉成字符串比對,避免因類型差異導致的 “假陽性”(比如123和'123'本應相等,卻因類型不同被判為不同)。 -
會話獨有變量的處理:方案一用
INNER JOIN只保留「既有全局又有會話」的變量,自動排除了last_insert_id這類「僅會話變量」(它們不存在全局值,自然不屬於 “修改自全局” 的範疇),無需額外過濾。 -
權限要求:兩種方案都需要
SELECT權限(對information_schema或performance_schema),普通用户默認擁有(除非管理員特意限制),無需SUPER權限。 -
修改後不生效的變量:有些變量(比如
innodb_buffer_pool_size)雖然能SET SESSION修改,但實際不生效(因為是全局共享資源),但這兩個方案依然會列出它們(只要會話值≠全局值或來源為SESSION),需注意這類變量的 “修改” 僅為表面值,未實際生效。
總結
- 若使用 MySQL 8.0.11+,優先用 方案二(精準、高效,直接定位手動修改的變量);
- 若使用 MySQL 5.7 及以下,用 方案一(兼容所有版本,能找出所有與全局值不同的變量);
- 兩種方案都無需手動比對,直接運行 SQL 即可得到結果,高效解決你的問題。
我是否可以理解為,當啓動一個mysql 會話即session的時候, 會創建MySQL的一個session實例,然後 會自動從global實例中繼承一些變量(是繼承全部嗎),然後按需對其中某些變量進行修改,(哪些是可以修改、哪些不能修改的呢?)如不修改, 那麼直接去global的變量?
你的理解大體方向正確,但有幾個關鍵細節需要修正和補充,核心結論先明確:
- 會話(session)啓動時不會繼承全部 global 變量,只繼承「既全局又會話的變量」的初始值;
- 不修改會話變量時,用的是「啓動時繼承的全局初始值」(而非實時讀取 global 變量);
- 變量能否修改,取決於它的「類型」和「MySQL 的設計規則」(不是所有變量都能改會話級)。
下面分步驟把邏輯講透,貼合你的 MySQL 5.7.11 版本:
一、先明確:會話啓動時的變量 “初始化邏輯”(不是 “繼承全部”)
你説的 “session 實例啓動時繼承 global 變量”,本質是 會話變量的初始化過程,但繼承範圍有限,具體分 3 類(沿用之前的變量分類,保持一致):
| 變量類型 | 會話啓動時的初始化邏輯 | 舉例 |
|---|---|---|
| 1. 僅全局變量(無 session 版) | 會話中不存在該變量,既不能繼承,也不能修改(會話根本查不到) | datadir(數據目錄)、port(端口)、max_connections(最大連接數) |
| 2. 僅會話變量(無 global 版) | 會話啓動時自動創建,值來自 MySQL 的 “會話默認規則”(和 global 無關),只能改會話級 | last_insert_id(當前會話最後插入的自增 ID)、insert_id(手動指定的自增 ID) |
| 3. 既全局又會話的變量(最常見) | 會話啓動時,複製當前 global 變量的 “實時值” 作為初始值(相當於 “快照”),之後可獨立修改 | sql_mode(SQL 模式)、wait_timeout(連接超時)、character_set_client(客户端字符集) |
關鍵修正你的誤解:
- 不是 “繼承全部 global 變量”:僅第 3 類變量會被會話 “複製初始值”,第 1 類僅全局變量會話根本沒有,談不到繼承;
- 不是 “實時讀取 global 變量”:會話啓動後,第 3 類變量的初始值就和 global 變量 “脱鈎” 了 —— 之後哪怕修改了 global 變量,已存在的會話也不會同步(新會話才會用新的 global 值當初始值)。
舉個直觀例子:
- 全局變量
wait_timeout= 86400(默認 24 小時); - 你啓動一個新會話(session A),會話的
wait_timeout初始值 = 86400(複製當時的 global 值); - 之後管理員修改全局變量
SET GLOBAL wait_timeout = 3600(1 小時); - 會話 A 的
wait_timeout依然是 86400(不受 global 修改影響),只有新啓動的會話 B,才會以 3600 作為初始值。
二、哪些變量能修改?哪些不能?(分場景説清楚)
變量能否修改,核心看「變量類型」和「MySQL 的設計限制」,按 “修改範圍”(會話級 / 全局級)分類如下:
1. 僅能修改全局級(會話級不能改,也不存在會話值)
- 對應變量類型:第 1 類(僅全局變量);
- 特點:和數據庫實例的 “基礎配置 / 共享資源” 相關,必須全局統一,不能按會話自定義;
- 例子:
datadir(數據目錄)、port(端口)、max_connections(最大連接數)、innodb_buffer_pool_size(InnoDB 緩衝池); - 説明:
show SESSION VARIABLES查不到這些變量,只能用SET GLOBAL xxx修改(需 SUPER 權限),且新會話才生效。
2. 僅能修改會話級(全局級不存在,或不能改)
- 對應變量類型:第 2 類(僅會話變量)+ 部分第 3 類(既全局又會話,但全局級不允許改);
- 特點:和當前會話的 “操作狀態” 相關,僅影響當前連接,不涉及全局資源;
- 例子:
- 僅會話變量:
last_insert_id(只能通過插入數據或SET SESSION last_insert_id = xxx修改)、sql_safe_updates(僅會話級生效,控制是否允許無 WHERE 的 UPDATE/DELETE); - 第 3 類但僅能改會話級:
character_set_results(客户端字符集返回格式,全局改意義不大,通常改會話級);
- 僅會話變量:
- 説明:修改無需特殊權限,
SET SESSION xxx即可,斷開連接後失效。
3. 既能改全局級,也能改會話級(最常見)
- 對應變量類型:大部分第 3 類(既全局又會話的變量);
- 特點:有全局默認值,也支持會話自定義,滿足 “全局統一 + 局部靈活” 的需求;
- 例子:
sql_mode(SQL 模式,全局寬鬆 + 會話嚴格)、wait_timeout(連接超時,全局 24 小時 + 會話 1 小時)、max_join_size(關聯查詢最大行數限制)、sort_buffer_size(排序緩衝區大小); - 説明:
- 改全局:
SET GLOBAL xxx(需 SUPER 權限),新會話生效; - 改會話:
SET SESSION xxx(普通權限),僅當前會話生效,不影響全局。
- 改全局:
4. 特殊情況:能改但不生效(坑點)
有些第 3 類變量(既全局又會話),雖然能執行
SET SESSION xxx,但修改後實際不生效 —— 因為它們是 “全局共享資源”,會話級修改被 MySQL 忽略;
- 例子:
innodb_buffer_pool_size(緩衝池大小)、key_buffer_size(MyISAM 索引緩衝區); - 説明:這些變量的會話值只是 “顯示用”,實際生效的還是全局值,改會話級沒用。
三、補充:不修改會話變量時,取值邏輯是什麼?
你問 “如不修改,那麼直接去 global 的變量?”—— 這個理解不準確,正確邏輯是:
- 對於第 3 類變量(既全局又會話):不修改的話,用的是「會話啓動時複製的 global 初始值」(不是實時去讀 global);
- 對於第 2 類變量(僅會話變量):不修改的話,用的是「MySQL 的會話默認值」(和 global 無關);
- 對於第 1 類變量(僅全局變量):會話中根本查不到,不存在 “取值” 一説。
再舉個例子驗證:
- 全局
sql_mode=''(寬鬆模式); - 啓動會話 A,會話 A 的
sql_mode初始值 =''(複製當時的 global 值); - 管理員修改全局
sql_mode=STRICT_TRANS_TABLES(嚴格模式); - 會話 A 不修改自己的
sql_mode,此時查詢show VARIABLES like 'sql_mode',結果還是''(不是實時讀新的 global 值); - 新啓動會話 B,其
sql_mode初始值 =STRICT_TRANS_TABLES(複製新的 global 值)。
四、最終總結(幫你梳理核心邏輯)
- 會話啓動時,僅「既全局又會話的變量」會複製當前 global 值作為初始值,僅全局變量不繼承,僅會話變量自動創建;
- 不修改會話變量時,用的是 “初始值”(第 3 類 = 複製的 global 初始值,第 2 類 = 會話默認值),和後續 global 變量的修改無關;
- 變量能否修改:
- 僅全局變量:只能改 global(需權限,新會話生效);
- 僅會話變量:只能改 session(無權限限制,當前會話生效);
- 既全局又會話的變量:大部分能改兩者,少數改 session 不生效;
- 你的核心理解 “會話繼承部分 global 變量,按需修改,不修改則用初始值” 是對的,只是要注意 “繼承範圍” 和 “初始值不實時同步 global” 這兩個細節。
如果想快速判斷某個變量能否改會話級,直接執行
SET SESSION 變量名 = 新值,若報錯 Variable 'xxx' is a GLOBAL variable and should be set with SET GLOBAL,説明該變量只能改 global;若不報錯,且查詢 show VARIABLES like 'xxx' 是新值,説明改 session 級有效~
MySQL 中 STATUS 怎麼理解,和 variables 是關係區別?
要理解 MySQL 中
STATUS 和 variables 的關係與區別,核心一句話就能拎清:
variables 是「配置項」(靜態規則),STATUS 是「運行狀態 / 監控數據」(動態結果) —— 配置項決定 MySQL 如何運行,運行狀態反映 MySQL 實際運行的效果,兩者是 “因” 與 “果” 的關聯,但本質完全不同。
一、核心區別:用表格直觀對比(適配你的 MySQL 5.7.11)
| 對比維度 | variables(變量 / 配置項) |
STATUS(狀態 / 監控數據) |
|---|---|---|
| 本質 | 運行規則 / 參數設置(“遊戲規則”) | 運行時的實時數據 / 統計結果(“遊戲戰況”) |
| 用途 | 控制 MySQL 行為(比如字符集、超時時間、SQL 模式) | 監控 MySQL 狀態(比如連接數、查詢量、緩存命中率)、排查問題 |
| 讀寫性 | 大部分可修改(SET GLOBAL/SESSION),少數只讀(如 datadir) |
完全只讀(只能查詢,不能修改,數據由 MySQL 自動統計更新) |
| 生命週期 | 全局變量:實例啓動時加載(配置文件 / 命令行),修改後重啓 / 新連接生效;會話變量:連接生命週期 | 全局狀態:實例啓動後開始累計;會話狀態:連接啓動後開始累計,斷開連接後數據重置 |
| 作用域 | 支持 GLOBAL(實例級)和 SESSION(連接級),部分僅全局 / 僅會話 |
支持 GLOBAL(全實例累計)和 SESSION(當前連接累計),部分僅全局(如 Uptime) |
| 數據類型 | 字符串、數字、布爾等(配置值) | 多為數字(統計計數)、少數字符串(如 Version) |
| 查詢命令 | show GLOBAL/SESSION VARIABLES [like 'xxx'];performance_schema.global/session_variables |
show GLOBAL/SESSION STATUS [like 'xxx'];performance_schema.global/session_status |
二、分別詳解:用例子幫你落地理解
1. variables:管 “規則”,決定 MySQL 怎麼跑
variables 是你之前一直關注的 “配置”,核心是「提前設定好的規則」,告訴 MySQL 該用什麼字符集、允許多少連接、超時多久斷開等。
常見例子(既全局又會話的核心變量):
sql_mode:SQL 模式(規則),決定是否允許零日期、是否嚴格校驗數據;wait_timeout:連接超時時間(規則),決定客户端閒置多久斷開;character_set_client:客户端字符集(規則),決定 MySQL 如何解析客户端發送的字符;max_connections:最大連接數(規則),決定 MySQL 最多能同時接受多少連接。
查詢示例(你之前用過的):
sql
-- 查全局配置(規則)
show GLOBAL VARIABLES like 'sql_mode';
-- 查當前會話配置(規則)
show SESSION VARIABLES like 'wait_timeout';
2. STATUS:管 “結果”,反映 MySQL 跑的怎麼樣
STATUS 是 MySQL 運行過程中「自動統計的數據」,記錄規則執行後的實際效果,比如 “按 max_connections 規則,當前有多少連接在使用”“按 query_cache_type 規則,緩存命中了多少次”。
常見例子(按場景分類):
| 狀態變量名 | 作用説明(反映的 “結果”) |
|---|---|
| 連接相關 | |
| Threads_connected | 當前活躍的連接數(全局 / 會話,會話級 = 當前連接數 1) |
| Threads_running | 當前正在執行 SQL 的連接數(排查 “卡庫” 常用) |
| 查詢相關 | |
| Queries | 累計執行的 SQL 語句總數(全局 = 全實例,會話 = 當前連接) |
| Slow_queries | 累計執行時間超過 long_query_time(默認 10 秒)的慢查詢數(排查慢查詢常用) |
| 緩存相關 | |
| Qcache_hits | 查詢緩存命中次數(5.7 支持,8.0 已移除) |
| Qcache_inserts | 查詢緩存插入次數 |
| 服務器相關 | |
| Uptime | MySQL 實例啓動後的總秒數(僅全局,監控服務器運行時長) |
| Com_insert/update/delete | 累計執行的插入 / 更新 / 刪除語句數(全局 / 會話) |
查詢示例(適配你的 5.7.11):
sql
-- 查全局狀態:當前活躍連接數、總查詢數
show GLOBAL STATUS like 'Threads_connected';
show GLOBAL STATUS like 'Queries';
-- 查當前會話狀態:當前連接執行的 SQL 數、慢查詢數
show SESSION STATUS like 'Queries';
show SESSION STATUS like 'Slow_queries';
三、兩者的關聯:配置(variables)決定狀態(STATUS),狀態反映配置效果
variables 和 STATUS 不是孤立的,而是 “因” 與 “果” 的關係 —— 你修改了配置(variables),最終會體現在狀態(STATUS)上;通過狀態(STATUS),也能反推配置(variables)是否合理。
舉 2 個直觀關聯例子:
- 配置
max_connections(variables)= 100 → 狀態Threads_connected(STATUS)的最大值不會超過 100(如果超過,會出現 “連接數滿” 錯誤); - 配置
sql_mode(variables)=STRICT_TRANS_TABLES(嚴格模式)→ 狀態Com_insert(STATUS)中,因數據不符合規則導致的插入失敗數會增加(可結合錯誤日誌查看); - 配置
wait_timeout(variables)= 3600 → 狀態Threads_connected(STATUS)中,閒置超過 1 小時的連接會被自動斷開,連接數會減少。
四、關鍵避坑:這些細節別混淆
-
作用域一致性≠含義一致:兩者都支持
GLOBAL和SESSION,但含義不同:show SESSION VARIABLES like 'wait_timeout':當前連接的超時規則(比如 3600 秒);show SESSION STATUS like 'Threads_connected':當前連接的活躍狀態(固定為 1,因為是當前連接自己)。
-
STATUS 是 “累計值”,不是 “實時快照”:比如
Queries是從實例 / 連接啓動後開始累計的,不是 “當前正在執行的查詢數”(當前執行數看Threads_running)。 -
部分 STATUS 變量名和 variables 類似,但完全不同:比如
version(STATUS)是 MySQL 版本號(狀態),version_comment(variables)是版本註釋(配置),名稱接近但含義無關。
五、總結:什麼時候用哪個?
- 想「改規則、調配置」→ 用
variables(比如修改字符集、調整超時時間、開啓嚴格模式); - 想「看狀態、查問題」→ 用
STATUS(比如排查連接數滿、找慢查詢、監控緩存效果); - 核心邏輯:用 variables 定規則,用 STATUS 看規則的執行效果,兩者配合才能完整掌控 MySQL 的運行。
比如你之前想知道 “會話修改了哪些變量”,用
variables 對比;現在想知道 “修改後連接數是否下降”,就用 STATUS 查 Threads_connected —— 這就是兩者的實際配合場景。
如下的區別? show GLOBAL STATUS; show SESSION STATUS; show STATUS;
這三個命令的核心區別和
variables 系列完全一致 ——默認行為 + 統計數據的作用域(全局 / 會話),結合你熟悉的 MySQL 5.7.11 版本,用 “統計範圍 + 實際用途” 就能講透,還能直接對應到你的運維場景:
一、核心區別:一張表説清(延續之前的對比邏輯,好理解)
| 命令 | 作用域 | 統計範圍(數據來源) | 典型用途 |
|---|---|---|---|
show GLOBAL STATUS |
全局(實例級) | 從 MySQL 實例啓動後開始 累計 的全實例數據(所有連接的彙總統計) | 監控整個數據庫的運行狀態(比如總連接數、全實例慢查詢數、服務器運行時長) |
show SESSION STATUS |
會話(連接級) | 從當前連接啓動後開始 累計 的專屬數據(僅當前連接的操作統計) | 排查當前連接的問題(比如當前連接執行了多少 SQL、當前連接的慢查詢數) |
show STATUS |
默認 = 會話級(省略 SESSION) | 等價於 show SESSION STATUS,僅顯示 當前連接的累計統計數據 |
快速查看當前連接的操作狀態(比如剛執行的 SQL 有沒有觸發慢查詢) |
關鍵結論(和 variables 邏輯對齊,易記):
show STATUS沒有 “疊加”,默認只看「當前會話」的統計;- 全局狀態是 “全實例彙總”,會話狀態是 “當前連接單獨統計”,互不干擾;
- 數據都是 累計值(從實例 / 連接啓動時開始算),不是實時 “快照”(比如
Queries是累計執行的 SQL 總數,不是當前正在執行的數量)。
二、直觀例子:執行後看差異(直接複製到你的 5.7.11 測試)
假設場景:你的 MySQL 實例已運行 1000 秒,當前有 3 個活躍連接,你當前連接剛執行了 5 條 SQL,其中 1 條是慢查詢。
1. 查全局狀態(全實例彙總)
sql
show GLOBAL STATUS like 'Uptime'; -- 結果:1000(實例運行總秒數,僅全局有)
show GLOBAL STATUS like 'Threads_connected'; -- 結果:3(全實例當前活躍連接數)
show GLOBAL STATUS like 'Queries'; -- 結果:100(全實例所有連接累計執行100條SQL)
show GLOBAL STATUS like 'Slow_queries'; -- 結果:5(全實例所有連接累計5條慢查詢)
2. 查當前會話狀態(僅你當前連接)
sql
show SESSION STATUS like 'Uptime'; -- 結果:60(當前連接已建立60秒,不是實例時長)
show SESSION STATUS like 'Threads_connected'; -- 結果:1(當前連接自己,固定為1)
show SESSION STATUS like 'Queries'; -- 結果:5(當前連接累計執行5條SQL)
show SESSION STATUS like 'Slow_queries'; -- 結果:1(當前連接累計1條慢查詢)
3. 查默認 STATUS(等價於 SESSION)
sql
show STATUS like 'Queries'; -- 結果:5(和 SESSION 完全一致)
show STATUS like 'Slow_queries'; -- 結果:1(和 SESSION 完全一致)
差異一眼懂:
- 全局狀態是 “集體數據”,反映整個數據庫的負載;
- 會話狀態是 “個人數據”,只反映你當前連接的操作;
show STATUS就是偷懶寫法,默認看 “個人數據”。
三、關鍵注意點(避坑,適配 5.7.11)
-
部分狀態變量只有 “全局版”,沒有會話版:比如
Uptime(實例運行時長)、Com_show_databases(全實例累計執行show databases的次數),執行show SESSION STATUS like 'Uptime'也能查到,但值是「當前連接的存活時長」(不是實例時長),用途不同。 -
會話狀態的生命週期:會話狀態數據從連接建立時開始累計,斷開連接後數據會重置(下次重連重新從 0 開始算);而全局狀態數據從實例啓動時開始累計,重啓實例才會重置。
-
別把 “累計值” 當 “實時值”:
- 想查 “當前正在執行的 SQL 數”→ 用
show GLOBAL STATUS like 'Threads_running'(全局),不是Queries(累計總數); - 想查 “當前活躍連接數”→ 用
show GLOBAL STATUS like 'Threads_connected'(全局),不是Threads_running(正在執行的連接數)。
- 想查 “當前正在執行的 SQL 數”→ 用
-
權限要求:普通用户默認能查
SESSION STATUS;查GLOBAL STATUS可能需要PROCESS權限(如果報錯 “Access denied”,讓管理員授予GRANT PROCESS ON *.* TO '你的用户名'@'localhost';)。
四、實際使用場景(什麼時候用哪個?)
| 需求場景 | 推薦命令 | 原因 |
|---|---|---|
| 查看數據庫總連接數、總慢查詢數 | show GLOBAL STATUS |
需全實例彙總數據 |
| 排查當前連接的 SQL 執行情況(比如 “我剛執行的 SQL 有沒有算慢查詢”) | show SESSION STATUS / show STATUS |
只需當前連接的統計數據 |
| 監控數據庫運行時長、整體緩存命中率 | show GLOBAL STATUS |
全局累計數據才有意義 |
測試當前連接的參數效果(比如修改 sql_safe_updates 後,看當前連接的更新語句數) |
show SESSION STATUS |
僅關注當前連接的操作結果 |
最終總結(一句話記牢)
show GLOBAL STATUS:看 “整個數據庫的累計戰況”;show SESSION STATUS:看 “你當前連接的累計戰況”;show STATUS:簡寫 =SESSION STATUS,懶人的 “個人戰況” 查詢;- 核心還是「作用域」,和之前
variables系列的命令邏輯完全一致,不用額外記新規則~ -
show SESSION VARIABLES;=show LOCAL VARIABLES;(兩者完全一樣)。