10年 Java程序员,硬核人生!勇往直前,永不退缩!

欢迎围观我的git:https://github.com/R1310328554/spring_security_learn 寻找志同道合的有志于研究技术的朋友,关注本人微信公众号: 觉醒的码农,或Q群 165874185

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

搞懂这三个命令的区别,核心是 变量作用域(全局 / 会话),你的部分理解需要修正 ——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 的优先级

假设场景:
 
  1. 全局变量 sql_mode 为 ''(宽松模式);
  2. 你当前会话执行 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 变量总数,两者有重叠(第三类),但各有独有的变量(第一、二类)。

四、补充注意点

  1. 全局变量修改后,已存在的会话不生效,只有新连接会继承新的全局值;
  2. 有些变量即使是 “既全局又会话”,修改 session 级也可能无效(比如 innodb_buffer_pool_size,虽然能查 session 值,但修改后不生效,因为是共享资源,只能全局配置);
  3. 权限要求:修改 global 变量需要 SUPER 权限(或 MySQL 8.0+ 的 SYSTEM_VARIABLES_ADMIN 权限),修改 session 变量一般不需要特殊权限;
  4. 简写:show LOCAL VARIABLES 等价于 show SESSION VARIABLES(LOCAL 是 SESSION 的别名)。

最终总结

  1. show GLOBAL VARIABLES:查实例级全局配置,影响所有新连接;
  2. show SESSION VARIABLES:查当前连接的专属配置,仅影响当前连接;
  3. show VARIABLES:默认查 SESSION 变量,即当前会话正在使用的配置(优先用自己的,没有则继承 global);
  4. 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),避免误判(比如字符集变量可能因客户端配置自动变化,并非手动修改,方案一会列出,方案二可排除)。

补充说明(避坑)

  1. 变量类型比对问题:
     
    部分变量的全局值和会话值类型可能不同(比如 max_connections 是数字,sql_mode 是字符串),方案一中用 CAST(xxx AS CHAR) 统一转成字符串比对,避免因类型差异导致的 “假阳性”(比如 123 和 '123' 本应相等,却因类型不同被判为不同)。
  2. 会话独有变量的处理:
     
    方案一用 INNER JOIN 只保留「既有全局又有会话」的变量,自动排除了 last_insert_id 这类「仅会话变量」(它们不存在全局值,自然不属于 “修改自全局” 的范畴),无需额外过滤。
  3. 权限要求:
     
    两种方案都需要 SELECT 权限(对 information_schema 或 performance_schema),普通用户默认拥有(除非管理员特意限制),无需 SUPER 权限。
  4. 修改后不生效的变量:
     
    有些变量(比如 innodb_buffer_pool_size)虽然能 SET SESSION 修改,但实际不生效(因为是全局共享资源),但这两个方案依然会列出它们(只要会话值≠全局值或来源为 SESSION),需注意这类变量的 “修改” 仅为表面值,未实际生效。

总结

  • 若使用 MySQL 8.0.11+,优先用 方案二(精准、高效,直接定位手动修改的变量);
  • 若使用 MySQL 5.7 及以下,用 方案一(兼容所有版本,能找出所有与全局值不同的变量);
  • 两种方案都无需手动比对,直接运行 SQL 即可得到结果,高效解决你的问题。

 

我是否可以理解为,当启动一个mysql 会话即session的时候, 会创建MySQL的一个session实例,然后 会自动从global实例中继承一些变量(是继承全部吗),然后按需对其中某些变量进行修改,(哪些是可以修改、哪些不能修改的呢?)如不修改, 那么直接去global的变量?
 
 
你的理解大体方向正确,但有几个关键细节需要修正和补充,核心结论先明确:
 
  1. 会话(session)启动时不会继承全部 global 变量,只继承「既全局又会话的变量」的初始值;
  2. 不修改会话变量时,用的是「启动时继承的全局初始值」(而非实时读取 global 变量);
  3. 变量能否修改,取决于它的「类型」和「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 值当初始值)。
 
举个直观例子:
 
  1. 全局变量 wait_timeout = 86400(默认 24 小时);
  2. 你启动一个新会话(session A),会话的 wait_timeout 初始值 = 86400(复制当时的 global 值);
  3. 之后管理员修改全局变量 SET GLOBAL wait_timeout = 3600(1 小时);
  4. 会话 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 的变量?”—— 这个理解不准确,正确逻辑是:
 
  1. 对于第 3 类变量(既全局又会话):不修改的话,用的是「会话启动时复制的 global 初始值」(不是实时去读 global);
  2. 对于第 2 类变量(仅会话变量):不修改的话,用的是「MySQL 的会话默认值」(和 global 无关);
  3. 对于第 1 类变量(仅全局变量):会话中根本查不到,不存在 “取值” 一说。
 
再举个例子验证:
 
  1. 全局 sql_mode = ''(宽松模式);
  2. 启动会话 A,会话 A 的 sql_mode 初始值 = ''(复制当时的 global 值);
  3. 管理员修改全局 sql_mode = STRICT_TRANS_TABLES(严格模式);
  4. 会话 A 不修改自己的 sql_mode,此时查询 show VARIABLES like 'sql_mode',结果还是 ''(不是实时读新的 global 值);
  5. 新启动会话 B,其 sql_mode 初始值 = STRICT_TRANS_TABLES(复制新的 global 值)。

四、最终总结(帮你梳理核心逻辑)

  1. 会话启动时,仅「既全局又会话的变量」会复制当前 global 值作为初始值,仅全局变量不继承,仅会话变量自动创建;
  2. 不修改会话变量时,用的是 “初始值”(第 3 类 = 复制的 global 初始值,第 2 类 = 会话默认值),和后续 global 变量的修改无关;
  3. 变量能否修改:
    • 仅全局变量:只能改 global(需权限,新会话生效);
    • 仅会话变量:只能改 session(无权限限制,当前会话生效);
    • 既全局又会话的变量:大部分能改两者,少数改 session 不生效;
  4. 你的核心理解 “会话继承部分 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 个直观关联例子:
 
  1. 配置 max_connections(variables)= 100 → 状态 Threads_connected(STATUS)的最大值不会超过 100(如果超过,会出现 “连接数满” 错误);
  2. 配置 sql_mode(variables)= STRICT_TRANS_TABLES(严格模式)→ 状态 Com_insert(STATUS)中,因数据不符合规则导致的插入失败数会增加(可结合错误日志查看);
  3. 配置 wait_timeout(variables)= 3600 → 状态 Threads_connected(STATUS)中,闲置超过 1 小时的连接会被自动断开,连接数会减少。

四、关键避坑:这些细节别混淆

  1. 作用域一致性≠含义一致:
     
    两者都支持 GLOBAL 和 SESSION,但含义不同:
    • show SESSION VARIABLES like 'wait_timeout':当前连接的超时规则(比如 3600 秒);
    • show SESSION STATUS like 'Threads_connected':当前连接的活跃状态(固定为 1,因为是当前连接自己)。
  2. STATUS 是 “累计值”,不是 “实时快照”:
     
    比如 Queries 是从实例 / 连接启动后开始累计的,不是 “当前正在执行的查询数”(当前执行数看 Threads_running)。
  3. 部分 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)

  1. 部分状态变量只有 “全局版”,没有会话版:
     
    比如 Uptime(实例运行时长)、Com_show_databases(全实例累计执行 show databases 的次数),执行 show SESSION STATUS like 'Uptime' 也能查到,但值是「当前连接的存活时长」(不是实例时长),用途不同。
  2. 会话状态的生命周期:
     
    会话状态数据从连接建立时开始累计,断开连接后数据会重置(下次重连重新从 0 开始算);而全局状态数据从实例启动时开始累计,重启实例才会重置。
  3. 别把 “累计值” 当 “实时值”:
    • 想查 “当前正在执行的 SQL 数”→ 用 show GLOBAL STATUS like 'Threads_running'(全局),不是 Queries(累计总数);
    • 想查 “当前活跃连接数”→ 用 show GLOBAL STATUS like 'Threads_connected'(全局),不是 Threads_running(正在执行的连接数)。
  4. 权限要求:
     
    普通用户默认能查 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;(两者完全一样)。
     

 

 

posted on 2025-11-23 00:07  CanntBelieve  阅读(0)  评论(0)    收藏  举报