擴充 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 指向 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 位元組無符號字。可能值的範圍是 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、對它們進行排序,然後逐一顯示每個選項來處理。

當處理完命令列選項時,會由 handle_option() 函式 (my_getopt.c) 從 argv 中移除它;實際上,它被消耗掉了。

伺服器會在成功載入外掛程式之後,但在呼叫外掛程式初始化函式之前,於外掛程式安裝過程中處理命令列選項

在執行階段載入的外掛程式不會受益於任何設定選項,並且必須具有可用的預設值。一旦安裝完成,它們會在 mysqld 初始化時載入,並且可以在命令列或 my.cnf 中設定組態選項。

外掛程式應該將 thd 參數視為唯讀。