system var mysql_mysql系统变量存储

以下语句

select @@read_buffer_size;

mysql最终是如何解析的呢?

yacc的归纳过程如下:

select_item——>remember_name

expr remember_end

select_alias——>expr——>bool_pri——>predicate——>bit_expr——>simple_expr——>variable——>variable_aux

variable_aux:

ident_or_text SET_VAR expr

{

Item_func_set_user_var *item;

$$= item=

new (YYTHD->mem_root) Item_func_set_user_var($1, $3, false);

if ($$ == NULL)

MYSQL_YYABORT;

LEX *lex= Lex;

lex->uncacheable(UNCACHEABLE_RAND);

lex->set_var_list.push_back(item);

}

| ident_or_text

{

$$= new (YYTHD->mem_root) Item_func_get_user_var($1);

if ($$ == NULL)

MYSQL_YYABORT;

LEX *lex= Lex;

lex->uncacheable(UNCACHEABLE_RAND);

}

|'@' opt_var_ident_type ident_or_text opt_component

{

/* disallow "SELECT @@global.global.variable" */

if ($3.str && $4.str && check_reserved_words(&$3))

{

my_parse_error(ER(ER_SYNTAX_ERROR));

MYSQL_YYABORT;

}

if (!($$= get_system_var(YYTHD, $2, $3, $4)))

MYSQL_YYABORT;

if (!((Item_func_get_system_var*) $$)->is_written_to_binlog())

Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_VARIABLE);

}

;

get_system_var函数用来查找系统变量,返回结果是item类型,因为select中的字段的类型是item的子类

Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,

LEX_STRING component)

内部调用find_sys_var不查找系统变量

sys_var *find_sys_var(THD *thd, const char *str, uint length)

{

sys_var *var;

sys_var_pluginvar *pi= NULL;

plugin_ref plugin;

DBUG_ENTER("find_sys_var");

mysql_mutex_lock(&LOCK_plugin);

mysql_rwlock_rdlock(&LOCK_system_variables_hash);

if ((var= intern_find_sys_var(str, length)) &&

(pi= var->cast_pluginvar()))

{

mysql_rwlock_unlock(&LOCK_system_variables_hash);

LEX *lex= thd ? thd->lex : 0;

if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))

var= NULL; /* failed to lock it, it must be uninstalling */

else

if (!(plugin_state(plugin) & PLUGIN_IS_READY))

{

/* initialization not completed */

var= NULL;

intern_plugin_unlock(lex, plugin);

}

}

else

mysql_rwlock_unlock(&LOCK_system_variables_hash);

mysql_mutex_unlock(&LOCK_plugin);

if (!var)

my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);

DBUG_RETURN(var);

}

find_sys_var调用intern_find_sys_var查找系统变量

sys_var *intern_find_sys_var(const char *str, uint length)

{

sys_var *var;

/*

This function is only called from the sql_plugin.cc.

A lock on LOCK_system_variable_hash should be held

*/

var= (sys_var*) my_hash_search(&system_variable_hash,

(uchar*) str, length ? length : strlen(str));

/* Don't show non-visible variables. */

if (var && var->not_visible())

return NULL;

return var;

}

即所有的系统变量定义在文件:sql/sys_vars_shared.h文件中

extern sys_var_chain all_sys_vars;

这个变量在何时赋值进行初始的呢?

我们来看如何声明一个变量:打开文件sql/sys_vars.cc,查看变量performance_schema的声明

static Sys_var_mybool Sys_pfs_enabled(

"performance_schema",

"Enable the performance schema.",

READ_ONLY GLOBAL_VAR(pfs_param.m_enabled),

CMD_LINE(OPT_ARG), DEFAULT(TRUE),

PFS_TRAILING_PROPERTIES);

这里performance_schema系统变量用类Sys_var_mybool 表示,看这个类的构造函数

class Sys_var_mybool: public Sys_var_typelib

{

public:

Sys_var_mybool(const char *name_arg,

const char *comment, int flag_args, ptrdiff_t off, size_t size,

CMD_LINE getopt,

my_bool def_val, PolyLock *lock=0,

enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,

on_check_function on_check_func=0,

on_update_function on_update_func=0,

const char *substitute=0,

int parse_flag= PARSE_NORMAL)

: Sys_var_typelib(name_arg, comment, flag_args, off, getopt,

SHOW_MY_BOOL, bool_values, def_val, lock,

binlog_status_arg, on_check_func, on_update_func,

substitute, parse_flag)

{

……

这个类继承自Sys_var_typelib,再看这个类的构造函数

Sys_var_typelib(const char *name_arg,

const char *comment, int flag_args, ptrdiff_t off,

CMD_LINE getopt,

SHOW_TYPE show_val_type_arg, const char *values[],

ulonglong def_val, PolyLock *lock,

enum binlog_status_enum binlog_status_arg,

on_check_function on_check_func, on_update_function on_update_func,

const char *substitute, int parse_flag= PARSE_NORMAL)

:sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,

getopt.arg_type, show_val_type_arg, def_val, lock,

binlog_status_arg, on_check_func,

on_update_func, substitute, parse_flag)

而Sys_var_typelib又继承自sys_var类,这个时候把all_sys_vars这个全局变量的指针传到sys_var的构造函数中

最后看sys_var类的构造函数

sys_var::sys_var(sys_var_chain *chain, const char *name_arg,

const char *comment, int flags_arg, ptrdiff_t off,

int getopt_id, enum get_opt_arg_type getopt_arg_type,

SHOW_TYPE show_val_type_arg, longlong def_val,

PolyLock *lock, enum binlog_status_enum binlog_status_arg,

on_check_function on_check_func,

on_update_function on_update_func,

const char *substitute, int parse_flag) :

next(0),

binlog_status(binlog_status_arg),

flags(flags_arg), m_parse_flag(parse_flag), show_val_type(show_val_type_arg),

guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func),

deprecation_substitute(substitute),

is_os_charset(FALSE)

{

/*

There is a limitation in handle_options() related to short options:

- either all short options should be declared when parsing in multiple stages,

- or none should be declared.

Because a lot of short options are used in the normal parsing phase

for mysqld, we enforce here that no short option is present

in the first (PARSE_EARLY) stage.

See handle_options() for details.

*/

DBUG_ASSERT(parse_flag == PARSE_NORMAL || getopt_id <= 0 || getopt_id >= 255);

name.str= name_arg;     // ER_NO_DEFAULT relies on 0-termination of name_arg

name.length= strlen(name_arg);                // and so does this.

DBUG_ASSERT(name.length <= NAME_CHAR_LEN);

memset(&option, 0, sizeof(option));

option.name= name_arg;

option.id= getopt_id;

option.comment= comment;

option.arg_type= getopt_arg_type;

option.value= (uchar **)global_var_ptr();

option.def_value= def_val;

if (chain->last)

chain->last->next= this;

else

chain->first= this;

chain->last= this;

}

这里会把新声明的系统变量加到all_sys_vars这个全局变量所指向的链表中

整个类的层次如下,Sys_var_mybool——Sys_var_typelib——sys_var,其中在sys_var这个类中实现将所有系统变量加入到链表中的功能

而添加系统变量调用mysql_add_sys_var_chain来完成的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值