擴展 MySQL 8.4  /  外掛程式的 MySQL 服務

第 5 章 外掛程式的 MySQL 服務

MySQL 伺服器外掛程式可以存取伺服器的外掛程式服務。外掛程式服務介面公開了外掛程式可以呼叫的伺服器功能。它補充了外掛程式 API,並具有以下特性:

  • 服務使外掛程式可以使用普通函數呼叫來存取伺服器內部的程式碼。服務也適用於可載入函數。

  • 服務是可攜式的,並且可以在多個平台上運作。

  • 該介面包括版本控制機制,以便可以在載入時檢查伺服器支援的服務版本與外掛程式版本。版本控制可以防止伺服器提供的服務版本與外掛程式預期或需要的服務版本之間的不相容性。

  • 有關測試外掛程式服務的外掛程式的資訊,請參閱 MySQL 伺服器 Doxygen 文件中的「測試外掛程式服務的外掛程式」章節,網址為 https://mysqldev.dev.org.tw/doc/index-other.html

外掛程式服務介面與外掛程式 API 的不同之處如下:

  • 外掛程式 API 使外掛程式能夠被伺服器使用。呼叫主動權在於伺服器調用外掛程式。這使外掛程式能夠擴展伺服器功能或註冊以接收有關伺服器處理的通知。

  • 外掛程式服務介面使外掛程式能夠呼叫伺服器內部的程式碼。呼叫主動權在於外掛程式調用服務函數。這使伺服器中已實作的功能可以被許多外掛程式使用;它們無需單獨實作它自己。

要確定存在哪些服務以及它們提供哪些函數,請查看 MySQL 原始碼發行版本的 include/mysql 目錄。相關檔案為:

  • plugin.h 包含 services.h,它是包含所有可用的特定服務標頭檔案的總括標頭。

  • 特定服務標頭的名稱格式為 service_xxx.h

每個特定服務標頭都應包含註解,這些註解提供給定服務的完整用法文件,包括可用的服務函數、其呼叫順序和傳回值。

對於希望修改伺服器以新增服務的開發人員,請參閱 MySQL 內部:外掛程式的 MySQL 服務

可用的服務包括以下內容:

  • get_sysvar_source:一種服務,使外掛程式能夠檢索系統變數設定的來源。

  • locking_service:一種實作具有三個屬性的鎖定的服務:鎖定命名空間、鎖定名稱和鎖定模式。此鎖定介面可在兩個層級存取:1) 在 SQL 層級,作為一組可載入函數,每個函數都對應於對服務例程的呼叫;2) 作為 C 語言介面,可以從伺服器外掛程式或可載入函數作為外掛程式服務呼叫。如需更多資訊,請參閱 鎖定服務

  • my_plugin_log_service:一種使外掛程式能夠報告錯誤並指定錯誤訊息的服務。伺服器將訊息寫入其錯誤記錄檔。

  • status_variable_registration。一種用於註冊狀態變數的服務。

  • my_thd_scheduler:一種供外掛程式選擇線程排程器的服務。

  • mysql_keyring:一種用於金鑰環儲存的服務,可在兩個層級存取:1) 在 SQL 層級,作為一組可載入函數,每個函數都對應於對服務例程的呼叫;2) 作為 C 語言介面,可以從伺服器外掛程式或可載入函數作為外掛程式服務呼叫。如需更多資訊,請參閱 金鑰環服務

  • mysql_password_policy:一種用於密碼驗證和強度檢查的服務。

  • plugin_registry_service:MySQL 伺服器包含一個基於組件的基礎架構,用於改進伺服器可擴展性;請參閱 MySQL 組件。但是,MySQL 外掛程式使用早於組件介面的介面。plugin_registry_service 使外掛程式能夠存取組件註冊表及其服務。

  • security_context:一種使外掛程式能夠檢查或操作線程安全性內容的服務。此服務提供 Setter 和 Getter 例程,以存取伺服器 Security_context 類別的屬性,其中包括作業系統使用者和主機、經過驗證的使用者和主機以及用戶端 IP 位址等屬性。

  • thd_alloc:一種記憶體配置服務。

  • thd_wait:一種供外掛程式報告其何時進入休眠或停滯狀態的服務。

本節的其餘部分說明外掛程式如何使用以服務形式提供的伺服器功能。另請參閱 守護進程範例外掛程式的原始碼,該外掛程式使用 my_snprintf 服務。在 MySQL 原始碼發行版本中,該外掛程式位於 plugin/daemon_example 目錄中。

若要從外掛程式內部使用一項或多項服務,外掛程式原始檔必須包含 plugin.h 標頭檔,才能存取與服務相關的資訊:

#include <mysql/plugin.h>

這不代表任何額外的設定成本。外掛程式無論如何都必須包含該檔案,因為它包含每個外掛程式都需要的定義和結構。

若要存取服務,外掛程式會像呼叫任何其他函數一樣呼叫服務函數。

若要報告伺服器將寫入錯誤記錄檔的錯誤,請先選擇錯誤層級。mysql/service_my_plugin_log.h 定義了這些層級:

enum plugin_log_level
{
  MY_ERROR_LEVEL,
  MY_WARNING_LEVEL,
  MY_INFORMATION_LEVEL
};

然後調用 my_plugin_log_message()

int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
                          const char *format, ...);

例如:

my_plugin_log_message(plugin_ptr, MY_ERROR_LEVEL, "Cannot initialize plugin");

某些外掛程式服務可能外掛程式提供,因此僅在載入提供服務的外掛程式時才可用。任何使用此類服務的 MySQL 組件都應檢查該服務是否可用。

建置外掛程式時,請在連結時使用 -lmysqlservices 旗標來連結 libmysqlservices 程式庫。例如,對於 CMake,請將此放入頂層 CMakeLists.txt 檔案中:

FIND_LIBRARY(MYSQLSERVICES_LIB mysqlservices
 PATHS "${MYSQL_SRCDIR}/libservices" NO_DEFAULT_PATH)

將此放入包含外掛程式原始碼的目錄中的 CMakeLists.txt 檔案中:

# the plugin needs the mysql services library for error logging
TARGET_LINK_LIBRARIES (your_plugin_library_name ${MYSQLSERVICES_LIB})