mysql 插件开发_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里规定了存储引擎需要完成的各类操作

如:

点击(此处)折叠或打开

virtualint update_row(const uchar *old_data __attribute__((unused)),

uchar *new_data __attribute__((unused)))

{

return HA_ERR_WRONG_COMMAND;

}

virtualint 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: publichandler

{

...

}

这就是mysql与plugin形式的存储引擎对接的方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值