擴充 MySQL 8.4  /  ...  /  編寫 INFORMATION_SCHEMA 外掛程式

4.4.6 編寫 INFORMATION_SCHEMA 外掛程式

本節說明如何編寫伺服器端 INFORMATION_SCHEMA 資料表外掛程式。如需實作此類外掛程式的範例程式碼,請參閱 MySQL 來源發行版的 sql/sql_show.cc 檔案。您也可以查看 InnoDB 來源中找到的範例外掛程式。請參閱 InnoDB 原始程式碼樹狀結構(在 storage/innobase 目錄中)內的 handler/i_s.cchandler/ha_innodb.cc 檔案。

若要編寫 INFORMATION_SCHEMA 資料表外掛程式,請在該外掛程式來源檔案中包含下列標頭檔。根據外掛程式的功能和需求,可能也需要其他 MySQL 或一般標頭檔。

#include <sql_class.h>
#include <table.h>

這些標頭檔位於 MySQL 原始程式碼發行版的 sql 目錄中。它們包含 C++ 結構,因此 INFORMATION_SCHEMA 外掛程式的來源檔案必須編譯為 C++ 程式碼。

此處開發的範例外掛程式的來源檔案名稱為 simple_i_s_table.cc。它會建立名為 SIMPLE_I_S_TABLE 的簡單 INFORMATION_SCHEMA 資料表,該資料表有兩個名為 NAMEVALUE 的欄位。實作資料表的的外掛程式庫的一般描述符如下

mysql_declare_plugin(simple_i_s_library)
{
  MYSQL_INFORMATION_SCHEMA_PLUGIN,
  &simple_table_info,                /* type-specific descriptor */
  "SIMPLE_I_S_TABLE",                /* table name */
  "Author Name",                     /* author */
  "Simple INFORMATION_SCHEMA table", /* description */
  PLUGIN_LICENSE_GPL,                /* license type */
  simple_table_init,                 /* init function */
  NULL,
  0x0100,                            /* version = 1.0 */
  NULL,                              /* no status variables */
  NULL,                              /* no system variables */
  NULL,                              /* no reserved information */
  0                                  /* no flags */
}
mysql_declare_plugin_end;

name 成員 (SIMPLE_I_S_TABLE) 指示在陳述式(例如 INSTALL PLUGINUNINSTALL PLUGIN)中用於參考外掛程式的名稱。這也是 SHOW PLUGINSINFORMATION_SCHEMA.PLUGINS 所顯示的名稱。

一般描述符的 simple_table_info 成員指向類型特定的描述符,該描述符僅包含類型特定的 API 版本號碼

static struct st_mysql_information_schema simple_table_info =
{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };

一般描述符指向初始化和解除初始化的函式

  • 初始化函式會提供資料表結構以及填入資料表的函式資訊。

  • 解除初始化函式會執行任何必要的清理。如果不需要清理,此描述符成員可以是 NULL(如範例所示)。

初始化函式應該在成功時傳回 0,如果發生錯誤則傳回 1。該函式會接收一般指標,應該將其解譯為資料表結構的指標

static int table_init(void *ptr)
{
  ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE*)ptr;

  schema_table->fields_info= simple_table_fields;
  schema_table->fill_table= simple_fill_table;
  return 0;
}

該函式應該設定資料表結構的這兩個成員

  • fields_info:一個 ST_FIELD_INFO 結構的陣列,其中包含每個欄位的相關資訊。

  • fill_table:填入資料表的函式。

fields_info 指向的陣列應該包含 INFORMATION_SCHEMA 的每個欄位一個元素,以及一個終止元素。範例外掛程式的下列 simple_table_fields 陣列指出 SIMPLE_I_S_TABLE 有兩個欄位。NAME 是字串值,長度為 10,而 VALUE 是整數值,顯示寬度為 20。最後一個結構標示陣列的結尾。

static ST_FIELD_INFO simple_table_fields[]=
{
  {"NAME", 10, MYSQL_TYPE_STRING, 0, 0 0, 0},
  {"VALUE", 6, MYSQL_TYPE_LONG, 0, MY_I_S_UNSIGNED, 0, 0},
  {0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0}
};

如需欄位資訊結構的詳細資訊,請參閱 table.h 標頭檔中 ST_FIELD_INFO 的定義。允許的 MYSQL_TYPE_xxx 類型值是在 C API 中使用的值;請參閱C API 基本資料結構

fill_table 成員應該設定為填入資料表且在成功時傳回 0,如果發生錯誤則傳回 1 的函式。針對範例外掛程式,simple_fill_table() 函式如下所示

static int simple_fill_table(THD *thd, TABLE_LIST *tables, Item *cond)
{
  TABLE *table= tables->table;

  table->field[0]->store("Name 1", 6, system_charset_info);
  table->field[1]->store(1);
  if (schema_table_store_record(thd, table))
    return 1;
  table->field[0]->store("Name 2", 6, system_charset_info);
  table->field[1]->store(2);
  if (schema_table_store_record(thd, table))
    return 1;
  return 0;
}

針對 INFORMATION_SCHEMA 資料表的每一列,此函式會初始化每個欄位,然後呼叫 schema_table_store_record() 以安裝該列。store() 方法引數取決於要儲存的值的類型。對於欄位 0 (NAME,字串),store() 會接受字串指標、其長度,以及關於字串字元集的資訊

store(const char *to, uint length, CHARSET_INFO *cs);

對於欄位 1 (VALUE,整數),store() 會接受值和一個旗標,指示是否為不帶正負號

store(longlong nr, bool unsigned_value);

如需如何填入 INFORMATION_SCHEMA 資料表的其他範例,請在 sql_show.cc 中搜尋 schema_table_store_record() 的執行個體。

若要編譯和安裝外掛程式庫檔案,請使用第 4.4.3 節「編譯和安裝外掛程式庫」中的指示。若要讓程式庫檔案可供使用,請將其安裝在外掛程式目錄中(由 plugin_dir 系統變數命名的目錄)。

若要測試外掛程式,請安裝它

mysql> INSTALL PLUGIN SIMPLE_I_S_TABLE SONAME 'simple_i_s_table.so';

確認資料表存在

mysql> SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
    -> WHERE TABLE_NAME = 'SIMPLE_I_S_TABLE';
+------------------+
| TABLE_NAME       |
+------------------+
| SIMPLE_I_S_TABLE |
+------------------+

嘗試從中選取

mysql> SELECT * FROM INFORMATION_SCHEMA.SIMPLE_I_S_TABLE;
+--------+-------+
| NAME   | VALUE |
+--------+-------+
| Name 1 |     1 |
| Name 2 |     2 |
+--------+-------+

解除安裝它

mysql> UNINSTALL PLUGIN SIMPLE_I_S_TABLE;