每個包含伺服器外掛程式的外掛程式庫都必須包含一個庫描述符,其中包含檔案中每個伺服器外掛程式的一般外掛程式描述符。本節討論如何為伺服器外掛程式撰寫庫和一般描述符。
庫描述符必須定義兩個符號
_mysql_plugin_interface_version_
指定一般外掛程式框架的版本號碼。這由MYSQL_PLUGIN_INTERFACE_VERSION
符號給定,該符號在plugin.h
檔案中定義。_mysql_plugin_declarations_
定義一個外掛程式宣告的陣列,以所有成員設為 0 的宣告終止。每個宣告都是st_mysql_plugin
結構的執行個體 (也在plugin.h
中定義)。對於程式庫中的每個伺服器外掛程式,都必須有一個此類宣告。
如果伺服器在程式庫中找不到這兩個符號,則不會將其接受為合法的外掛程式庫,並會拒絕它並顯示錯誤。這會防止將程式庫用於外掛程式目的,除非它是專門作為外掛程式庫建立的。
定義兩個必要符號的傳統方法是使用 plugin.h
檔案中的 mysql_declare_plugin()
和 mysql_declare_plugin_end
巨集。
mysql_declare_plugin(name)
... one or more server plugin descriptors here ...
mysql_declare_plugin_end;
每個伺服器外掛程式都必須有一個一般描述符,以向伺服器外掛程式 API 提供資訊。一般描述符對於所有外掛程式類型都具有相同的結構。plugin.h
檔案中的 st_mysql_plugin
結構定義了這個描述符。
struct st_mysql_plugin
{
int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
void *info; /* pointer to type-specific plugin descriptor */
const char *name; /* plugin name */
const char *author; /* plugin author (for I_S.PLUGINS) */
const char *descr; /* general descriptive text (for I_S.PLUGINS) */
int license; /* the plugin license (PLUGIN_LICENSE_XXX) */
int (*init)(void *); /* the function to invoke when plugin is loaded */
int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
unsigned int version; /* plugin version (for I_S.PLUGINS) */
struct st_mysql_show_var *status_vars;
struct st_mysql_sys_var **system_vars;
void * __reserved1; /* reserved for dependency checking */
unsigned long flags; /* flags for plugin */
};
以下列方式使用 st_mysql_plugin
描述符結構成員。char *
成員應指定為 Null 終止的字串。
-
type
:外掛程式類型。這必須是來自plugin.h
的外掛程式類型值之一/* The allowable types of plugins */ #define MYSQL_UDF_PLUGIN 0 /* User-defined function */ #define MYSQL_STORAGE_ENGINE_PLUGIN 1 /* Storage Engine */ #define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */ #define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */ #define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */ #define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */ #define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */ #define MYSQL_AUTHENTICATION_PLUGIN 7 /* The authentication plugin type */ #define MYSQL_VALIDATE_PASSWORD_PLUGIN 8 /* validate password plugin type */ #define MYSQL_GROUP_REPLICATION_PLUGIN 9 /* The Group Replication plugin */ #define MYSQL_KEYRING_PLUGIN 10 /* The Keyring plugin type */ #define MYSQL_CLONE_PLUGIN 11 /* The Clone plugin type */
例如,對於全文解析器外掛程式,
type
值為MYSQL_FTPARSER_PLUGIN
。 info
:指向外掛程式的類型特定描述符的指標。此描述符的結構取決於特定類型外掛程式,與一般外掛程式描述符結構不同。為了進行版本控制,預期每種外掛程式類型的類型特定描述符的第一個成員是該類型的介面版本。這使伺服器能夠檢查每種外掛程式的類型特定版本,無論其類型為何。在版本號碼之後,描述符包含任何其他需要的成員,例如回呼函式和伺服器正確叫用外掛程式所需的其他資訊。稍後關於撰寫特定類型伺服器外掛程式的章節將說明其類型特定描述符的結構。-
name
:提供外掛程式名稱的字串。這是將在mysql.plugin
資料表中列出,以及您在 SQL 陳述式 (例如INSTALL PLUGIN
和UNINSTALL PLUGIN
) 或使用--plugin-load
選項中參照外掛程式的名稱。該名稱也會顯示在INFORMATION_SCHEMA.PLUGINS
資料表或SHOW PLUGINS
的輸出中。外掛程式名稱不應以任何伺服器選項的名稱開頭。如果這樣做,伺服器將無法初始化它。例如,伺服器有一個
--socket
選項,因此您不應使用諸如socket
、socket_plugin
等外掛程式名稱。 author
:命名外掛程式作者的字串。這可以是任何您喜歡的內容。desc
:提供外掛程式一般描述的字串。這可以是任何您喜歡的內容。license
:外掛程式授權類型。該值可以是PLUGIN_LICENSE_PROPRIETARY
、PLUGIN_LICENSE_GPL
或PLUGIN_LICENSE_BSD
之一。init
:一個僅執行一次的初始化函式,如果沒有此類函式,則為NULL
。伺服器會在載入外掛程式時執行此函式,這會針對INSTALL PLUGIN
或,對於mysql.plugin
資料表中列出的外掛程式,在伺服器啟動時發生。該函式接受一個指向用於識別外掛程式的內部結構的引數。它在成功時傳回零,在失敗時傳回非零值。deinit
:一個僅執行一次的反初始化函式,如果沒有此類函式,則為NULL
。伺服器會在卸載外掛程式時執行此函式,這會針對UNINSTALL PLUGIN
或,對於mysql.plugin
資料表中列出的外掛程式,在伺服器關閉時發生。該函式接受一個指向用於識別外掛程式的內部結構的引數。它在成功時傳回零,在失敗時傳回非零值。version
:外掛程式版本號碼。安裝外掛程式後,可以從INFORMATION_SCHEMA.PLUGINS
資料表中擷取此值。該值包括主要和次要號碼。如果您將該值撰寫為十六進位常數,則格式為0x
,其中MMNN
MM
和NN
分別是主要和次要號碼。例如,0x0302
代表版本 3.2。-
status_vars
:指向與外掛程式關聯的狀態變數結構的指標,如果沒有此類變數,則為NULL
。安裝外掛程式後,這些變數會顯示在SHOW STATUS
陳述式的輸出中。如果
status_vars
成員不是NULL
,則它會指向描述狀態變數的st_mysql_show_var
結構陣列。請參閱 第 4.4.2.2 節,「伺服器外掛程式狀態和系統變數」。 -
system_vars
:指向與外掛程式關聯的系統變數結構的指標,如果沒有此類變數,則為NULL
。這些選項和系統變數可用於協助初始化外掛程式中的變數。安裝外掛程式後,這些變數會顯示在SHOW VARIABLES
陳述式的輸出中。如果
system_vars
成員不是NULL
,則它會指向描述系統變數的st_mysql_sys_var
結構陣列。請參閱 第 4.4.2.2 節,「伺服器外掛程式狀態和系統變數」。 __reserved1
:未來佔位符。它應設為NULL
。-
flags
:外掛程式旗標。各個位元對應不同的旗標。該值應設為適用旗標的 OR。這些旗標可用#define PLUGIN_OPT_NO_INSTALL 1UL /* Not dynamically loadable */ #define PLUGIN_OPT_NO_UNINSTALL 2UL /* Not dynamically unloadable */ #define PLUGIN_OPT_ALLOW_EARLY 4UL /* allow --early-plugin-load */
啟用時,旗標具有以下含義
PLUGIN_OPT_NO_INSTALL
:無法使用INSTALL PLUGIN
陳述式在執行階段載入外掛程式。這適用於必須使用--plugin-load
、--plugin-load-add
或--early-plugin-load
選項在伺服器啟動時載入的外掛程式。PLUGIN_OPT_NO_UNINSTALL
:無法使用UNINSTALL PLUGIN
陳述式在執行階段卸載外掛程式。PLUGIN_OPT_ALLOW_EARLY
:外掛程式可以使用--early-plugin-load
選項在伺服器啟動順序中提早載入。此標記不影響外掛程式是否可以使用--plugin-load
或--plugin-load-add
選項在伺服器啟動時載入,或是在執行時使用INSTALL PLUGIN
陳述式載入。
只有在載入和卸載外掛程式時,伺服器才會調用一般外掛程式描述符中的 init
和 deinit
函式。它們與外掛程式的使用無關,例如當 SQL 陳述式導致外掛程式被調用時。
例如,包含名為 simple_parser
的單一全文解析器外掛程式的程式庫的描述符資訊如下所示:
mysql_declare_plugin(ftexample)
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
"simple_parser", /* name */
"Oracle Corporation", /* author */
"Simple Full-Text Parser", /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
mysql_declare_plugin_end;
對於全文解析器外掛程式,類型必須是 MYSQL_FTPARSER_PLUGIN
。這個值識別此外掛程式為在建立 FULLTEXT
索引時,在 WITH PARSER
子句中合法使用的外掛程式。(此子句不允許其他外掛程式類型。)
plugin.h
定義了 mysql_declare_plugin()
和 mysql_declare_plugin_end
巨集,如下所示:
#ifndef MYSQL_DYNAMIC_PLUGIN
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int PSIZE= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin DECLS[]= {
#else
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
#endif
#define mysql_declare_plugin(NAME) \
__MYSQL_DECLARE_PLUGIN(NAME, \
builtin_ ## NAME ## _plugin_interface_version, \
builtin_ ## NAME ## _sizeof_struct_st_plugin, \
builtin_ ## NAME ## _plugin)
#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
只有在定義了 MYSQL_DYNAMIC_PLUGIN
符號時,這些宣告才會定義 _mysql_plugin_interface_version_
符號。這表示必須在編譯命令中提供 -DMYSQL_DYNAMIC_PLUGIN
,才能將外掛程式建置為共享程式庫。
當巨集如範例所示使用時,它們會展開為以下程式碼,該程式碼會定義兩個必要的符號(_mysql_plugin_interface_version_
和 _mysql_plugin_declarations_
):
int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION;
int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin);
struct st_mysql_plugin _mysql_plugin_declarations_[]= {
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
"simple_parser", /* name */
"Oracle Corporation", /* author */
"Simple Full-Text Parser", /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
,{0,0,0,0,0,0,0,0,0,0,0,0}}
};
前面的範例在一般描述符中宣告了單一外掛程式,但可以宣告多個外掛程式。在 mysql_declare_plugin()
和 mysql_declare_plugin_end
之間,將宣告一個接一個地列出,並以逗號分隔。
MySQL 伺服器外掛程式必須編譯為 C++ 程式碼。您不應該使用的一個 C++ 功能是使用非常數變數初始化全域結構。諸如 st_mysql_plugin
結構等結構的成員只能使用常數變數初始化。前面顯示的 simple_parser
描述符在 C++ 外掛程式中是允許的,因為它滿足該要求。
mysql_declare_plugin(ftexample)
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
"simple_parser", /* name */
"Oracle Corporation", /* author */
"Simple Full-Text Parser", /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
mysql_declare_plugin_end;
以下是編寫一般描述符的另一種有效方式。它使用常數變數來表示外掛程式的名稱、作者和描述:
const char *simple_parser_name = "simple_parser";
const char *simple_parser_author = "Oracle Corporation";
const char *simple_parser_description = "Simple Full-Text Parser";
mysql_declare_plugin(ftexample)
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
simple_parser_name, /* name */
simple_parser_author, /* author */
simple_parser_description, /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
mysql_declare_plugin_end;
但是,以下一般描述符無效。它使用結構成員來表示外掛程式的名稱、作者和描述,但在 C++ 中,結構不被視為常數初始設定式。
typedef struct
{
const char *name;
const char *author;
const char *description;
} plugin_info;
plugin_info parser_info = {
"simple_parser",
"Oracle Corporation",
"Simple Full-Text Parser"
};
mysql_declare_plugin(ftexample)
{
MYSQL_FTPARSER_PLUGIN, /* type */
&simple_parser_descriptor, /* descriptor */
parser_info.name, /* name */
parser_info.author, /* author */
parser_info.description, /* description */
PLUGIN_LICENSE_GPL, /* plugin license */
simple_parser_plugin_init, /* init function (when loaded) */
simple_parser_plugin_deinit,/* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
simple_system_variables, /* system variables */
NULL,
0
}
mysql_declare_plugin_end;