mysql> status,MySQL · 引擎特性 · MySQL 状态信息Status实现

什么是MySQL状态信息

MySQL Status代码实现

本文将和大家一起看看Status的内部实现机制,相关的代码是基于MySQL 8.0。

MySQL使用了两张Performance_Schema数据库的表,global_status分别对应Session级别以及Global级别的状态信息访问。 两张表的定义如下,包含的字段是一样的。

CREATE TABLE `session_status` (

`VARIABLE_NAME` varchar(64) NOT NULL DEFAULT '',

`VARIABLE_VALUE` varchar(1024) DEFAULT NULL

) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

CREATE TABLE `global_status` (

`VARIABLE_NAME` varchar(64) NOT NULL DEFAULT '',

`VARIABLE_VALUE` varchar(1024) DEFAULT NULL

) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

Show session|global Status命令会在MySQL server层解析成对performance_schema.session_status或者performance_schema.global_status的Select语句。具体参见 build_show_session_status或build_show_global_status方法,这两个方法都会调用build_query方法来真正生成对应的SELECT_LEX,之后执行。

主要的数据结构

Status变量定义见SHOW_VAR结构体

struct SHOW_VAR {

const char *name; //Status名字

char *value; //Status的值

enum enum_mysql_show_type type; //Status类型,比如SHOW_ARRAY, SHOW_LONGLONG,不同的类型Status处理的方法不同

enum enum_mysql_show_scope scope; //Status作用范围,包括 SHOW_SCOPE_UNDEF,SHOW_SCOPE_GLOBAL, SHOW_SCOPE_SESSION和SHOW_SCOPE_ALL

};

SHOW_SCOPE_UNDEF

未定义作用域,。当成SHOW_SCOPE_ALL对待

SHOW_SCOPE_GLOBAL

全局作用域。这种Status在整个MySQL实例生命周期里面只有一个,且全局的值。只可以通过SHOW GLOBAL STATUS,或者Select Performance_Schema.global_status表查看。 例子: Aborted_connects, Binlog_cache_use

SHOW_SCOPE_SESSION

Session级别作用域。这种Status只作用于各自的连接,不会在全局范围做聚集。只可以通过SHOW SESSION STATUS,或者Select Performance_Schema.session_status表查看。 例子: Compression, Last_query_cost

SHOW_SCOPE_ALL

这种Status变量可以作用于各自的连接,也会在全局范围做聚集。既可以通过SHOW SESSION STATUS,或者Select Performance_Schema.session_status表查看,也可以通过SHOW GLOBAL STATUS 或者 Select Performance_Schema.global_status查看。 例子: Bytes_sent, Open_tables, Com variables

all_status_vars

在mysqld.cc文件中定义的Status变量的全局动态SHOW_VAR数组,所有的server以及plugin的Status变量都会在里面定义。在MySQL实例初始化阶段,Status变量都会被组装成这个all_status_vars的全局动态数组,plugin在load的时候,带入的新的status变量会被加到这个数组里面。all_status_vars里面包含的Status的定义都是有序的存放的,以方便Show Status命令或者是对相关系统表session_status或者是global_status的访问。

System_status_var

thread级别的status变量,变量类型必须是long/ulong。

Global locks

LOCK_status 是一个全局mutex,它被用来在初始化阶段以及SHOW STATUS执行阶段保护all_status_vars。

Thread locks

在做多个thread Status聚合的时候后,global thread manager会持有两把锁来防止thread被移除。Global_THD_manager::LOCK_thd_remove和Global_THD_manager::LOCK_thd_count。 但,两种锁的持有时间不同,LOCK_thd_remove会在整个聚合执行期间一直持有, LOCK_thd_count 锁 会在当前thread list的快照做了copy之后就会释放。

Show Status实现

对Performance_schema.session_status或者是Performance_schema.global_status的访问,会需要调用join_materialize_scan方法,并进一步调用ha_perfschema::rnd_init/rnd_next, PFS_variable_cache ::materialize_all等。

取session域的Status的调用栈如下

join_materialize_derived-> TABLE_LIST::materialize_derived->…

->ha_perfschema::rnd_init->table_session_status::rnd_init

-> PFS_variable_cache::materialize_all //Materialize output status

-> PFS_status_variable_cache::do_materialize_all->PFS_status_variable_cache::manifest

join_materialize_derived-> TABLE_LIST::materialize_derived…->ha_perfschema::rnd_next->table_session_status::rnd_next //访问所有的status,做过滤

取global域的Status的调用栈如下,和session域的调用栈很类似

join_materialize_derived-> TABLE_LIST::materialize_derived->…

->ha_perfschema::rnd_init->table_session_status::rnd_init

-> PFS_variable_cache::materialize_all //Materialize output status

->PFS_status_variable_cache::do_materialize_all->PFS_status_variable_cache::manifest

join_materialize_derived-> TABLE_LIST::materialize_derived->…

->ha_perfschema::rnd_next->table_session_status::rnd_next

type为SHOW_FUNC的Status,例如Aborted_connects,访问方法比较特别,会调用SHOW_VAR里面定义的函数来处理,

PFS_status_variable_cache::manifest

/*

If the value is a function reference, then execute the function and

reevaluate the new SHOW_TYPE and value. Handle nested case where

SHOW_FUNC resolves to another SHOW_FUNC.

*/

if (show_var_ptr->type == SHOW_FUNC) {

show_var_tmp = *show_var_ptr;

/*

Execute the function reference in show_var_tmp->value, which returns

show_var_tmp with a new type and new value.

*/

for (const SHOW_VAR *var = show_var_ptr; var->type == SHOW_FUNC;

var = &show_var_tmp) {

((mysql_show_var_func)(var->value))(thd, &show_var_tmp, value_buf.data); //调用指定的函数,函数名在status_vars数组里定义

}

show_var_ptr = &show_var_tmp;

}

例如取Aborted_connects,就会调用show_aborted_connects这个函数来获取真正的值。

{"Aborted_connects", (char *)&show_aborted_connects, SHOW_FUNC, SHOW_SCOPE_GLOBAL},

如何添加一个新的Status

MySQL当前的架构已经对Status扩展做了很好的支持。我们如果想添加一个新的Status,一般的步骤是在System_status_var里面添加一个相应的变量,并在status_vars数组里面 也对应添加一个对应的SHOW_VAR条目。需要处理的是对Status 变量做累计,这个就要根据具体的逻辑了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值