写出一个能够正常运行的存储引擎不难,难的是写出一个稳定高效的存储引擎。同时如果还能方便运维的话,那就能得到更广泛的使用。一个经常出问题的引擎首先会受到DBA自身的排斥。
写内核写了这么久,一直没有全程的定制过一下存储引擎接口,虽然经验认为不难,不过因为各种编译依赖问题还是折腾了不下一天的时间,由于mysql的版本各异,经验方法在实施过程中要做各种调整,当然前提是需要知道一个存储引擎的加载运行原理,才能在正确的地方添加正确的代码。总结 写mysql代码的经历就是写出一个新功能或是修复一个bug只需要几分钟来写代码,但要知道把代码写到哪儿可能需要几天的时间来研究。
今天整理一下在mysql当中添加一个自定义存储引擎的步骤,这里基于mysql的example存储引擎,只是修改了一下名字。创建好接口之后,就可以基于ha_abc.h和ha_abc.cc提供的模板来实现一个存储引擎的功能,方案还不完善,目前还不能通过configure定制编译选项。
5.0.51b当中的代码,automake基于1.9.6版本,其他版本可能会有一些问题。
创建一个名为ABC的存储引擎,最终修改的文件如下。 其中client/mysql_pri.h是 sql/mysql_pri.h的一个链接。基于5.0.51b版本的代码。
[flashdb@com src]$ grep -i -s -n -r have_abc_db .
./client/mysql_priv.h:45:#ifndef HAVE_ABC_DB
./client/mysql_priv.h:46:#define HAVE_ABC_DB
./client/mysql_priv.h:1398:#ifdef HAVE_ABC_DB
./client/mysql_priv.h:1400:#define have_abc_db abc_hton.state
./client/mysql_priv.h:1402:extern SHOW_COMP_OPTION have_abc_db;
./sql/handler.cc:33:#ifdef HAVE_ABC_DB
./sql/handler.cc:320:#ifdef HAVE_ABC_DB
./sql/handler.cc:322: if (have_abc_db == SHOW_OPTION_YES)
./sql/mysqld.cc:6677:#if defined(HAVE_ABC_DB)
./sql/mysqld.cc:6678: have_abc_db= SHOW_OPTION_YES;
./sql/mysqld.cc:6680: have_abc_db= SHOW_OPTION_NO;
./sql/mysqld.cc:7789:#undef have_abc_db
./sql/mysqld.cc:7800:SHOW_COMP_OPTION have_abc_db= SHOW_OPTION_NO;
./sql/ha_abc.cc:71:#ifdef HAVE_ABC_DB
./sql/ha_abc.cc:706:#endif /* HAVE_ABC_DB */
./sql/mysql_priv.h:45:#ifndef HAVE_ABC_DB
./sql/mysql_priv.h:46:#define HAVE_ABC_DB
./sql/mysql_priv.h:1398:#ifdef HAVE_ABC_DB
./sql/mysql_priv.h:1400:#define have_abc_db abc_hton.state
./sql/mysql_priv.h:1402:extern SHOW_COMP_OPTION have_abc_db;
拷贝 sql/example/ha_examples.h ha_examples.cc 至sql目录命名为ha_abc.h ha_abc.cc.
替换ha_abc.h 和 ha_abc.cc当中的 example为abc,EXAMPLE替换为ABC。
同时修改ha_abc.cc当中的#include "../mysql_priv.h" 为#include "mysql_pri.h"(目录变更)
修改sql/handler.h ,在enum db_type枚举变量中,添加一个类型为DB_TYPE_ABC_DB
修改sql/handler.cc ,首先引入abc_hton(在ha_abc.cc当中的定义的handlerton).
修改get_new_handler()函数,添加创建ABC存储引擎的的分支,
当create table的时候,mysql会根据选定的engine来调用相应的handler的子类,ABC存储引擎的handler构造函数为ha_abc.
修改sql/mysql_pri.h 引入have_abc_db 这个枚举变量。其类型是SHOW_COMP_OPTION,意思是是否支持ABC存储引擎,其可选值有三个
首先判断当前是否定义了ABC存储引擎的HANDLERTON,如果已经定义则引入在ha_abc.cc当中定义的abc_hton。
同时定义have_abc_db的值为abc_hton的stat字段,该字段是SHOW_COMP_OPTION类型。
如果未定义ABC存储引擎,则引入在mysqld.cc当中定义的have_abc_db, 这里引入的have_abc_db是为了显示是否支持ABC存储引擎。
修改sql/mysqld.cc 添加have_abc_db的定义,可以搜索have_csv_db找到。默认为不支持即SHOW_OPTION_NO。
修改mysql_init_variables函数的实现,在其中添加have_abc_db的初始化代码。
最后为了让添加的存储引擎能够被mysql的编译系统支持,还需要做如下修改
a.修改sql文件夹当中的Makefile.am文件,将ha_abc.h 添加到noinst_HEADER集合,将ha_abc.cct添加到mysqld_SOURCES集合。
b.在sql/mysql_pri.h文件的头部定义HAVE_ABC_DB宏,告知编译系统支持ABC存储引擎,这个宏定义可以放进configure文件里面支持,即通过编译参数
--with-abc-storage-engine来可选的编译ABC存储引擎的代码。这里为了方便直接放在mysql_pri.h里面。
最后一步,在代码目录的顶层使用编译工具编译代码
a. 执行autoconf,这一步是为了生成新的configure文件
b.执行automake,这一步是更新Makefile.in.即使得在sql文件夹当中编辑的Makefile.am文件的变更生效。后面可以通过configure得到新的Makefile文件。
c../configure && make
完成之后在 sql 目录下可以找到mysqld 可执行文件。 通过mysql的启动一个mysql实例,执行命令show engines,应该能得到如下结果
可以创建名为ABC的存储引擎
可以参照myisam innodb csv 等存储引擎来逐步实现ABC存储引擎的一些功能。如增删改查等。
--转自