扩展 MySQL 8.4  /  ...  /  服务器插件状态和系统变量

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 指向长长整型变量的指针
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;

以下便捷宏使您可以声明不同类型的系统变量

  • 类型为 bool 的布尔系统变量,这是一个 1 字节的布尔值。(0 = false,1 = true

    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 字节的无符号字。可能值的范围是从 0 开始的 typelib 中元素数量的序数。

      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、对其进行排序,然后遍历它们以显示每个选项来处理的。

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

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

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

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