搞懂这三个命令的区别,核心是 变量作用域(全局 / 会话),你的部分理解需要修正 ——
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;(两者完全一样)。
浙公网安备 33010602011771号