探索MySQL源代码–添加一个variable

我们来为mysql添加一个variable, 名字是options_hoterrans,要达到的效果如下

mysql> show variables like '%hoterrans%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| options_hoterrans | 4     |
+------------------+-------+
1 row in set (0.00 sec)

mysql里的variable 有一部分是来自于my.cnf里的option。为了添加一个可配置的variale, 我们先来添加一个option, 名字是options_hoterran,没有s。

sql/mysqld.cc 查找关键字 my_long_options, 会找到一个很大的类型为my_options的结构体,这个结构体用于存储所有的long_options。
我们调到这个结构体的尾部,可以利用vim的{键。
在结构体的尾部有个哨兵,我们的选项就添加到哨兵的前面

struct my_option my_long_options[] =
....
  {"wait_timeout", OPT_WAIT_TIMEOUT,
   "The number of seconds the server waits for activity on a connection before closing it.",
   (uchar**) &global_system_variables.net_wait_timeout,
   (uchar**) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
   REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
   0, 1, 0},
   /* start*/
  {"options_hoterran", OPT_HOTERRAN,
        "This is option just for test",
        (uchar**)  &global_system_variables.opt_hoterran,
        NULL,
        0, GET_ULONG,
        REQUIRED_ARG, 2, 1, 1000,
        0, 1, 0
  },                                        

   /* end */
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};

/*start*/ /*end*/ 之间的就是我们所添加的代码,下同。

简单介绍一下my_option这个结构体

struct my_option
{
  const char *name;                     /* Name of the option */
  int        id;                        /* unique id or short option */
  const char *comment;                  /* option comment, for autom. --help */
  uchar      **value;                   /* The variable value */
  uchar      **u_max_value;             /* The user def. max variable value */
  struct st_typelib *typelib;           /* Pointer to possible values */
  ulong     var_type;
  enum get_opt_arg_type arg_type;
  longlong   def_value;                 /* Default value */
  longlong   min_value;                 /* Min allowed value */
  longlong   max_value;                 /* Max allowed value */
  longlong   sub_size;                  /* Subtract this from given value */
  long       block_size;                /* Value should be a mult. of this */
  void       *app_type;                 /* To be used by an application */
};

我们要注意其中2个字段, id:option的内部序列号; typelib:option的值指向了一个地址。
所以我们还需要添加这2个变量。

sql/mysqld.cc 里查找关键字enum options_mysqld,在这个枚举中我们添加一个枚举类型

   OPT_SLOW_QUERY_LOG_FILE,
+  /*rry start*/
+  OPT_HOTERRAN,
+  /*rry end*/
   OPT_IGNORE_BUILTIN_INNODB
 };

转到global_system_variables的类型system_variables定义处,sql/sql_class.h里。
在system_variables最末尾添加一个变量

  my_bool sysdate_is_now;
/*start*/
  u_long opt_hoterran;
/*end*/
};

目前为止,我们已经添加一个option, 你可以在my.cnf 添加

[mysqld]
....
options_hoterran=4

这个参数会被mysqld采用。

继续添加variable, 只要把上面的option与variable关联上即可。
打开sql/set_var.cc 文件,找到关键字net_wait_timeout, 修改后效果如下

 static sys_var_thd_ulong       sys_net_wait_timeout(&vars, "wait_timeout",
                                             &SV::net_wait_timeout);
+/*start*/
+static sys_var_thd_ulong        sys_opt_hoterran(&vars, "options_hoterrans",
+                                             &SV::opt_hoterran);
+/*end*/

这里是创建一个名为sys_opt_hoterran 的 sys_var_thd_ulong类,这个类的构造函数实际上就是在vars这个全局变量chain中添加一个名为options_hoterrans的variable。
SV就是上面options里的global_system_variables。

我们来看效果。

make&&make install

这里会比较慢,因为sql/sql_class.h 这个文件被修改了,而reference这个文件的target很多。

重启mysqld,mysql登上去

mysql> show variables like '%hoterrans%';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| options_hoterrans | 5     |
+-------------------+-------+
1 row in set (0.00 sec)

2 Comments

  1. [...] 在MySQL里添加一个system、status variables的比较复杂的,需要修改sql/sql_show.cc,sql/mysqld.cc, 还要修改sql/sql_yacc.yy,然后重新编译等等,前面的文章可见其复杂度,很容易出错。 [...]

  2. [...] 在MySQL里添加一个system、status variables的比较复杂的,需要修改sql/sql_show.cc,sql/mysqld.cc, 还要修改sql/sql_yacc.yy,然后重新编译等等,前面的文章可见其复杂度,很容易出错。 [...]

Leave a Reply