扩展 MySQL 8.0  / 第 4 章 MySQL 插件 API  / 4.4 编写插件  / 4.4.2 插件数据结构  /  4.4.2.2 服务器插件状态和系统变量

4.4.2.2 服务器插件状态和系统变量

服务器插件接口使插件能够使用通用插件描述符的 status_varssystem_vars成员公开状态和系统变量。

通用插件描述符的status_vars成员,如果不为0,则指向一个 st_mysql_show_var结构数组,每个结构描述一个状态变量,后面跟着一个所有成员都设置为0的结构。该 st_mysql_show_var结构有这样的定义:

struct st_mysql_show_var {
  const char *name;
  char *value;
  enum enum_mysql_show_type type;
};

下表显示了允许的状态变量 type值以及相应的变量应该是什么。

表 4.1 服务器插件状态变量类型

变量类型 意义
SHOW_BOOL 指向布尔变量的指针
SHOW_INT 指向整型变量的指针
SHOW_LONG 指向长整型变量的指针
SHOW_LONGLONG 指向 longlong 整型变量的指针
SHOW_CHAR 一个字符串
SHOW_CHAR_PTR 指向字符串的指针
SHOW_ARRAY 指向另一个st_mysql_show_var数组的指针
SHOW_FUNC 指向函数的指针
SHOW_DOUBLE 指向双精度的指针

对于SHOW_FUNC类型,调用函数并填充其out参数,然后提供有关要显示的变量的信息。该函数具有以下签名:

#define SHOW_VAR_FUNC_BUFF_SIZE 1024

typedef int (*mysql_show_var_func) (void *thd,
                                    struct st_mysql_show_var *out,
                                    char *buf);

system_vars成员如果不为 0,则指向一个st_mysql_sys_var 结构数组,每个结构描述一个系统变量(也可以从命令行或配置文件中设置),后面是一个所有成员都设置为 0 的结构。该st_mysql_sys_var 结构定义如下:

struct st_mysql_sys_var {
 int flags;
 const char *name, *comment;
 int (*check)(THD*, struct st_mysql_sys_var *, void*, st_mysql_value*);
 void (*update)(THD*, struct st_mysql_sys_var *, void*, const void*);
};

根据标志的需要附加字段。

为方便起见,定义了许多宏,使在插件中创建新系统变量变得更加简单。

在整个宏中,以下字段可用:

  • name:系统变量的不带引号的标识符。

  • varname: 静态变量的标识符。如果不可用,则与该name字段相同。

  • opt:系统变量的附加使用标志。下表显示了允许的标志。

    表 4.2 服务器插件系统变量标志

    标志值 描述
    PLUGIN_VAR_READONLY 系统变量是只读的
    PLUGIN_VAR_NOSYSVAR 系统变量在运行时用户不可见
    PLUGIN_VAR_NOCMDOPT 无法从命令行配置系统变量
    PLUGIN_VAR_NOCMDARG 命令行不需要参数(通常用于布尔变量)
    PLUGIN_VAR_RQCMDARG 命令行需要一个参数(这是默认值)
    PLUGIN_VAR_OPCMDARG 参数在命令行是可选的
    PLUGIN_VAR_MEMALLOC 用于字符串变量;指示要分配内存用于存储字符串

  • comment:要在服务器帮助消息中显示的描述性注释。 NULL如果要隐藏此变量。

  • check:勾选功能, NULL默认。

  • update:更新功能, NULL默认。

  • default:变量默认值。

  • minimum:变量最小值。

  • maximum:变量最大值。

  • blocksize:可变块大小。设置该值时,它会四舍五入到最接近的倍数blocksize

可以通过直接使用静态变量或使用 SYSVAR()访问器宏来访问系统变量。提供 SYSVAR()宏是为了完整性。通常只有当代码不能直接访问底层变量时才应该使用它。

例如:

static int my_foo;
static MYSQL_SYSVAR_INT(foo_var, my_foo,
                        PLUGIN_VAR_RQCMDARG, "foo comment",
                        NULL, NULL, 0, 0, INT_MAX, 0);
 ...
   SYSVAR(foo_var)= value;
   value= SYSVAR(foo_var);
   my_foo= value;
   value= my_foo;

会话变量只能通过访问 THDVAR()器宏访问。例如:

static MYSQL_THDVAR_BOOL(some_flag,
                         PLUGIN_VAR_NOCMDARG, "flag comment",
                         NULL, NULL, FALSE);
 ...
   if (THDVAR(thd, some_flag))
   {
     do_something();
     THDVAR(thd, some_flag)= FALSE;
   }

所有全局和会话系统变量必须在使用前发布到 mysqld。这是通过构造一个以NULL- 结尾的变量数组并在插件公共接口中链接到它来完成的。例如:

static struct st_mysql_sys_var *my_plugin_vars[]= {
  MYSQL_SYSVAR(foo_var),
  MYSQL_SYSVAR(some_flag),
  NULL
};
mysql_declare_plugin(fooplug)
{
  MYSQL_..._PLUGIN,
  &plugin_data,
  "fooplug",
  "foo author",
  "This does foo!",
  PLUGIN_LICENSE_GPL,
  foo_init,
  foo_fini,
  0x0001,
  NULL,
  my_plugin_vars,
  NULL,
  0
}
mysql_declare_plugin_end;

以下方便的宏使您能够声明不同类型的系统变量:

  • 类型的布尔系统变量 my_bool,它是一个 1 字节的布尔值。(0 = 假,1 = 真)

    MYSQL_THDVAR_BOOL(name, opt, comment, check, update, default)
    MYSQL_SYSVAR_BOOL(name, varname, opt, comment, check, update, default)
  • 类型为 的字符串系统变量 char*,它是指向以 null 结尾的字符串的指针。

    MYSQL_THDVAR_STR(name, opt, comment, check, update, default)
    MYSQL_SYSVAR_STR(name, varname, opt, comment, check, update, default)
  • 整数系统变量,其中有几个品种。

    • 一个int系统变量,通常是一个 4 字节的有符号字。

      MYSQL_THDVAR_INT(name, opt, comment, check, update, default, min, max, blk)
      MYSQL_SYSVAR_INT(name, varname, opt, comment, check, update, default,
                     minimum, maximum, blocksize)
    • 一个unsigned int系统变量,通常是一个 4 字节的无符号字。

      MYSQL_THDVAR_UINT(name, opt, comment, check, update, default, min, max, blk)
      MYSQL_SYSVAR_UINT(name, varname, opt, comment, check, update, default,
                      minimum, maximum, blocksize)
    • 系统变量,通常long是 4 字节或 8 字节的有符号字。

      MYSQL_THDVAR_LONG(name, opt, comment, check, update, default, min, max, blk)
      MYSQL_SYSVAR_LONG(name, varname, opt, comment, check, update, default,
                      minimum, maximum, blocksize)
    • unsigned long系统变量,通常是 4 字节或 8 字节的无符号字 。

      MYSQL_THDVAR_ULONG(name, opt, comment, check, update, default, min, max, blk)
      MYSQL_SYSVAR_ULONG(name, varname, opt, comment, check, update, default,
                       minimum, maximum, blocksize)
    • 一个long long系统变量,通常是一个 8 字节的有符号字。

      MYSQL_THDVAR_LONGLONG(name, opt, comment, check, update,
                          default, minimum, maximum, blocksize)
      MYSQL_SYSVAR_LONGLONG(name, varname, opt, comment, check, update,
                          default, minimum, maximum, blocksize)
    • 一个unsigned long long系统变量,通常是一个 8 字节的无符号字。

      MYSQL_THDVAR_ULONGLONG(name, opt, comment, check, update,
                           default, minimum, maximum, blocksize)
      MYSQL_SYSVAR_ULONGLONG(name, varname, opt, comment, check, update,
                           default, minimum, maximum, blocksize)
    • 一个double系统变量,通常是一个 8 字节的有符号字。

      MYSQL_THDVAR_DOUBLE(name, opt, comment, check, update,
                           default, minimum, maximum, blocksize)
      MYSQL_SYSVAR_DOUBLE(name, varname, opt, comment, check, update,
                           default, minimum, maximum, blocksize)
    • unsigned long系统变量,通常是 4 字节或 8 字节的无符号字 。可能值的范围是 中元素数的序数 typelib,从 0 开始。

      MYSQL_THDVAR_ENUM(name, opt, comment, check, update, default, typelib)
      MYSQL_SYSVAR_ENUM(name, varname, opt, comment, check, update,
                      default, typelib)
    • 一个unsigned long long系统变量,通常是一个 8 字节的无符号字。每个位代表 中的一个元素 typelib

      MYSQL_THDVAR_SET(name, opt, comment, check, update, default, typelib)
      MYSQL_SYSVAR_SET(name, varname, opt, comment, check, update,
                     default, typelib)

在内部,所有可变和插件系统变量都存储在一个HASH结构中。

服务器命令行帮助文本的显示是通过编译DYNAMIC_ARRAY与命令行选项相关的所有变量,对它们进行排序,然后遍历它们以显示每个选项来处理的。

argv处理命令行选项后, handle_option()函数 ( ) 会将其从中删除my_getopt.c;实际上,它被消耗掉了。

服务器在插件安装过程中处理命令行选项,在插件成功加载之后但在插件初始化函数被调用之前

在运行时加载的插件不会受益于任何配置选项,并且必须具有可用的默认值。安装后,它们会在 mysqld初始化时加载,并且可以在命令行或在my.cnf.

插件应将thd参数视为只读。