mysql程式碼閱讀-外掛載入及儲存引擎接入
初始化plugin流程
plugin_init從兩個plugin陣列裡提取plugin。
一個是mysql_mandatory_plugins,儲存強制外掛
第二個是mysql_optional_plugins,存放可選外掛
陣列的最後一個元素時0,這點很重要
sql/sql_builtin.cc:
plugin_init初始化外掛的程式碼
各類plugin的初始化函式被放到一個由這些函式的指標組成的陣列plugin_type_initialize裡
每個plugin的型別plugin->plugin->type是一個整數,用它作為下標訪問plugin_type_initialize,就能得到初始化這類plugin所需的函式。
plugin_initialize裡具體初始化plugin的地方,調的是函式指標
如果plugin是儲存引擎,plugin->plugin->type的值就是1,初始化工作就是呼叫plugin_type_initialize[1],也就是ha_initialize_handlerton。
前面程式碼的(*plugin_type_initialize[plugin->plugin->type])(plugin)就等價於ha_initialize_handlerton(plugin)
plugin_type_initialize主要工作初始化handlerton,存到plugin->data裡。然後將儲存引擎的handlerton記錄下來。
以後使用儲存引擎需要用到handlerton裡的資訊。
每個儲存引擎還需要載入不同的handler,儲存引擎各自的“plugin->plugin->init”函式指標指向其handler的初始化函式。
ha_initialize_handlerton直接呼叫“plugin->plugin->init”
以innodb為例plugin->plugin->init指向的是下面的innobase_init。每個儲存引擎有自己的xxx_init
innobase_create_handler內容很簡單,就是呼叫ha_innobase的建構函式。
其它的也類似比如myisam的就是調ha_myisam的建構函式
ha_innobase繼承自mysql定義的handler類,handler裡規定了儲存引擎需要完成的各類操作
如:
因此mysql不需要知道innodb的細節,
只要將ha_innobase視為handler,呼叫handler的函式,就能使用innodb的功能
這就是mysql與plugin形式的儲存引擎對接的方式
點選(此處)摺疊或開啟
-
main()
-
-> mysqld_main()
-
-> init_server_components()
-
-> plugin_init()
- -> plugin_initialize(struct st_plugin_int *plugin)
plugin_init從兩個plugin陣列裡提取plugin。
一個是mysql_mandatory_plugins,儲存強制外掛
第二個是mysql_optional_plugins,存放可選外掛
陣列的最後一個元素時0,這點很重要
sql/sql_builtin.cc:
點選(此處)摺疊或開啟
-
struct st_mysql_plugin *mysql_optional_plugins[]=
-
{
-
builtin_blackhole_plugin, builtin_innobase_plugin, builtin_federated_plugin, builtin_perfschema_plugin, builtin_archive_plugin, builtin_partition_plugin, 0
-
};
-
-
struct st_mysql_plugin *mysql_mandatory_plugins[]=
-
{
-
builtin_binlog_plugin, builtin_mysql_password_plugin, builtin_myisam_plugin, builtin_csv_plugin, builtin_heap_plugin, builtin_myisammrg_plugin, 0
- }
plugin_init初始化外掛的程式碼
點選(此處)摺疊或開啟
-
// 先迴圈mysql_mandatory_plugins
-
for (builtins= mysql_mandatory_plugins; *builtins || mandatory; builtins++)
-
{
-
/*
-
當迴圈到mysql_mandatory_plugins最後,遇到0,"!*builtins"就會成立,
-
此時將builtins指向mysql_optional_plugins並且將mandatory標記設為false。
-
這樣雖然builtins指向其它陣列了,但是最外層for的“builtins++”可以正常執行
-
由於mandatory變成false了,因此當遇到mysql_optional_plugins最後一個元素“0”的時候,
-
就不滿足最外層的“*builtins || mandatory”了,至此外掛載入順利結束。
-
*/
-
if (!*builtins)
-
{
-
builtins= mysql_optional_plugins;
-
mandatory= false;
-
if (!*builtins)
-
break;
-
}
-
for (plugin= *builtins; plugin->info; plugin++)
-
{
-
...
-
if (plugin_ptr->state != PLUGIN_IS_UNINITIALIZED ||
-
// 外掛的初始化工作由plugin_initialize函式來組織
-
plugin_initialize(plugin_ptr))
-
goto err_unlock;
- ...
各類plugin的初始化函式被放到一個由這些函式的指標組成的陣列plugin_type_initialize裡
每個plugin的型別plugin->plugin->type是一個整數,用它作為下標訪問plugin_type_initialize,就能得到初始化這類plugin所需的函式。
點選(此處)摺疊或開啟
-
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
-
{
-
0,ha_initialize_handlerton,0,0,initialize_schema_table,
-
initialize_audit_plugin,0,0,0
- };
plugin_initialize裡具體初始化plugin的地方,調的是函式指標
點選(此處)摺疊或開啟
-
if (plugin_type_initialize[plugin->plugin->type])
-
{
-
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
-
{
-
sql_print_error("Plugin '%s' registration as a %s failed.",
-
plugin->name.str, plugin_type_names[plugin->plugin->type].str);
-
goto err;
-
}
- ...
如果plugin是儲存引擎,plugin->plugin->type的值就是1,初始化工作就是呼叫plugin_type_initialize[1],也就是ha_initialize_handlerton。
前面程式碼的(*plugin_type_initialize[plugin->plugin->type])(plugin)就等價於ha_initialize_handlerton(plugin)
plugin_type_initialize主要工作初始化handlerton,存到plugin->data裡。然後將儲存引擎的handlerton記錄下來。
以後使用儲存引擎需要用到handlerton裡的資訊。
每個儲存引擎還需要載入不同的handler,儲存引擎各自的“plugin->plugin->init”函式指標指向其handler的初始化函式。
ha_initialize_handlerton直接呼叫“plugin->plugin->init”
點選(此處)摺疊或開啟
-
int ha_initialize_handlerton(st_plugin_int *plugin)
-
{
-
handlerton *hton;
-
...
-
hton= (handlerton *)my_malloc(sizeof(handlerton),
-
MYF(MY_WME | MY_ZEROFILL));
-
...
-
plugin->data= hton; // shortcut for the future
-
if (plugin->plugin->init && plugin->plugin->init(hton))
-
{
-
sql_print_error("Plugin '%s' init function returned error.",
-
plugin->name.str);
-
goto err;
- }
以innodb為例plugin->plugin->init指向的是下面的innobase_init。每個儲存引擎有自己的xxx_init
點選(此處)摺疊或開啟
-
static
-
int
-
innobase_init(
-
/*==========*/
-
void *p) /*!< in: InnoDB handlerton */
-
{
-
...
-
/*
-
將建立innodb的handler的函式指標放到handlerton->create。
-
以後每次開啟一張innodb表都需要用它建立一個innodb handler。
-
*/
-
innobase_hton->create = innobase_create_handler;
- ...
innobase_create_handler內容很簡單,就是呼叫ha_innobase的建構函式。
其它的也類似比如myisam的就是調ha_myisam的建構函式
點選(此處)摺疊或開啟
-
static
-
handler*
-
innobase_create_handler(
-
/*====================*/
-
handlerton* hton, /*!< in: InnoDB handlerton */
-
TABLE_SHARE* table,
-
MEM_ROOT* mem_root)
-
{
-
return(new (mem_root) ha_innobase(hton, table));
- }
ha_innobase繼承自mysql定義的handler類,handler裡規定了儲存引擎需要完成的各類操作
如:
點選(此處)摺疊或開啟
-
virtual int update_row(const uchar *old_data __attribute__((unused)),
-
uchar *new_data __attribute__((unused)))
-
{
-
return HA_ERR_WRONG_COMMAND;
-
}
-
-
-
virtual int delete_row(const uchar *buf __attribute__((unused)))
-
{
-
return HA_ERR_WRONG_COMMAND;
-
}
-
virtual int truncate()
-
{ return HA_ERR_WRONG_COMMAND; }
- ...
因此mysql不需要知道innodb的細節,
只要將ha_innobase視為handler,呼叫handler的函式,就能使用innodb的功能
點選(此處)摺疊或開啟
-
class ha_innobase: public handler
-
{
-
...
- }
這就是mysql與plugin形式的儲存引擎對接的方式
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26239116/viewspace-1870316/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL入門--儲存引擎MySql儲存引擎
- TiFlash 原始碼閱讀(三)TiFlash DeltaTree 儲存引擎設計及實現分析 - Part 1原始碼儲存引擎
- MySQL儲存引擎入門介紹MySql儲存引擎
- MySQL 儲存引擎MySql儲存引擎
- MySQL儲存引擎MySql儲存引擎
- Mysql之儲存引擎及字符集MySql儲存引擎
- Appdash原始碼閱讀——Store儲存APP原始碼
- MySQL系列-儲存引擎MySql儲存引擎
- MySQL InnoDB儲存引擎MySql儲存引擎
- MySQL-05.儲存引擎MySql儲存引擎
- 理解mysql的儲存引擎MySql儲存引擎
- MySQL之四 儲存引擎MySql儲存引擎
- 搜尋和線上閱讀 Github 程式碼的外掛推薦Github
- MySQL InnoDB 儲存引擎探祕MySql儲存引擎
- 2_mysql(索引、儲存引擎)MySql索引儲存引擎
- MySQL federated儲存引擎測試MySql儲存引擎
- Java類載入原始碼閱讀Java原始碼
- 外掛化之程式碼呼叫與載入資源
- Oracle 共享儲存掛載Oracle
- MySQL儲存引擎簡介及MyISAM和InnoDB的區別MySql儲存引擎
- 外掛式換膚框架搭建 setContentView原始碼閱讀框架View原始碼
- TiFlash 原始碼閱讀(一) TiFlash 儲存層概覽原始碼
- OceanBase 原始碼解讀(九):儲存層程式碼解讀之「巨集塊儲存格式」原始碼
- (MariaDB/MySQL)MyISAM儲存引擎讀、寫操作的優先順序MySql儲存引擎
- 如何選擇mysql的儲存引擎MySql儲存引擎
- 小談mysql儲存引擎優化MySql儲存引擎優化
- MySQL資料庫操作、儲存引擎MySql資料庫儲存引擎
- MySQL索引、事務與儲存引擎MySql索引儲存引擎
- 簡單認識MySQL儲存引擎MySql儲存引擎
- 聊一聊MySQL的儲存引擎MySql儲存引擎
- 【MySQL】MySQL(四)儲存引擎、索引、鎖、叢集MySql儲存引擎索引
- Props 混入 外掛 插槽 本地儲存
- OceanBase 儲存層程式碼解讀(三)巨集塊儲存格式
- OceanBase 儲存層程式碼解讀(二)微塊儲存格式
- MySQL入門系列:儲存程式(三)之儲存過程簡介MySql儲存過程
- MySQL入門系列:儲存程式(二)之儲存函式簡介MySql儲存函式
- Admob Unity外掛介紹及接入教程Unity
- 從零開始入門 K8s | Kubernetes 儲存架構及外掛使用K8S架構
- opentracing-go原始碼閱讀——Log儲存(完結篇)Go原始碼