MySQL 51简体中文手册 第16章编写自定义存储引擎.docx

上传人:b****6 文档编号:3640311 上传时间:2022-11-24 格式:DOCX 页数:29 大小:33.56KB
下载 相关 举报
MySQL 51简体中文手册 第16章编写自定义存储引擎.docx_第1页
第1页 / 共29页
MySQL 51简体中文手册 第16章编写自定义存储引擎.docx_第2页
第2页 / 共29页
MySQL 51简体中文手册 第16章编写自定义存储引擎.docx_第3页
第3页 / 共29页
MySQL 51简体中文手册 第16章编写自定义存储引擎.docx_第4页
第4页 / 共29页
MySQL 51简体中文手册 第16章编写自定义存储引擎.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

MySQL 51简体中文手册 第16章编写自定义存储引擎.docx

《MySQL 51简体中文手册 第16章编写自定义存储引擎.docx》由会员分享,可在线阅读,更多相关《MySQL 51简体中文手册 第16章编写自定义存储引擎.docx(29页珍藏版)》请在冰豆网上搜索。

MySQL 51简体中文手册 第16章编写自定义存储引擎.docx

MySQL51简体中文手册第16章编写自定义存储引擎

第16章:

编写自定义存储引擎

目录

16.1.前言

16.2.概述

16.3.创建存储引擎源文件

16.4.创建handlerton

16.5.对处理程序进行实例化处理

16.6.定义表扩展

16.7.创建表

16.8.打开表

16.9.实施基本的表扫描功能

16.9.1.实施store_lock()函数

16.9.2.实施external_lock()函数

16.9.3.实施rnd_init()函数

16.9.4.实施info()函数

16.9.5.实施extra()函数

16.9.6.实施rnd_next()函数

16.10.关闭表

16.11.为存储引擎添加对INSERT的支持

16.12.为存储引擎添加对UPDATE的支持

16.13.为存储引擎添加对DELETE的支持

16.14.API引用

16.14.1.bas_ext

16.14.2.close

16.14.3.create

16.14.4.delete_row

16.14.5.delete_table

16.14.6.external_lock

16.14.7.extra

16.14.8.info

16.14.9.open

16.14.10.rnd_init

16.14.11.rnd_next

16.14.12.store_lock

16.14.13.update_row

16.14.14.write_row

16.1.前言

对于MySQL5.1,MySQL

AB公司引入了插件式存储引擎体系结构,这样,就能创建新的存储引擎,并将它们添加到正在运行的MySQL服务器上,而不必重新编译服务器本身。

该体系结构简化了新存储引擎的开发和部署。

本章的意图是作为指南,用于帮助你为新的插件式存储引擎体系结构开发存储引擎。

关于MySQL插件式存储引擎体系结构的更多信息,请参见第14章:

插件式存储引擎体系结构。

16.2.概述

MySQL服务器采用了模块化风格。

图16.1:

MySQL体系结构

存储引擎负责管理数据存储,以及MySQL的索引管理。

通过定义的API,MySQL服务器能够与存储引擎进行通信。

每个存储引擎均是1个继承类,每个类实例作为处理程序而被引用。

针对需要与特殊表一起工作的每个线程,处理程序是在1个处理程序的基础上实例化的。

例如,如果3个连接全都在相同的表上工作,需要创建3个处理程序实例。

一旦创建了处理程序实例,MySQL服务器将向处理程序发送命令,以便执行数据存储和检索任务,如打开表、操纵行和管理索引等。

能够以累进方式创建定制存储引擎:

开发人员能够以只读存储引擎启动,随后添加对INSERT、UPDATE和DELETE操作的支持,甚至能够增加对索引功能、事务和其他高级操作的支持。

16.3.创建存储引擎源文件

实施新存储引擎的最简单方法是,通过拷贝和更改EXAMPLE存储引擎开始。

在MySQL

5.1源码树的sql/examples/目录下可找到文件ha_example.cc和ha_example.h。

关于如何获得5.1源码树的说明,请参见2.8.3节,“从开发源码树安装”。

复制文件时,将名称从ha_example.cc和ha_example.h更改为与存储引擎相适应的名称,如ha_foo.cc和ha_foo.h。

拷贝并重命名了这些文件后,必须更换所有的EXAMPLE示例,以及具有存储引擎名称的示例。

如果你熟悉sed,也能自动完成这些步骤:

seds/EXAMPLE/FOO/gha_example.h|seds/example/foo/gha_foo.hseds/EXAMPLE/FOO/gha_example.cc|seds/example/foo/gha_foo.cc16.4.创建handlerton

handlerton(“单个处理程序”的简称)定义了存储引擎,并包含指向函数的函数指针,它以整体方式作用在引擎上,而函数工作在单独的处理程序实例中。

在这类函数的一些示例中,包含用于处理注释和回滚的事务函数。

下面给出了一个来自EXAMPLE存储引擎的示例:

handlertonexample_hton={"EXAMPLE",SHOW_OPTION_YES,"Examplestorageengine",DB_TYPE_EXAMPLE_DB,NULL,/*Initialize*/0,/*slot*/0,/*savepointsize.*/NULL,/*close_connection*/NULL,/*savepoint*/NULL,/*rollbacktosavepoint*/NULL,/*releasesavepoint*/NULL,/*commit*/NULL,/*rollback*/NULL,/*prepare*/NULL,/*recover*/NULL,/*commit_by_xid*/NULL,/*rollback_by_xid*/NULL,/*create_cursor_read_view*/NULL,/*set_cursor_read_view*/NULL,/*close_cursor_read_view*/example_create_handler,/*Createanewhandler*/NULL,/*Dropadatabase*/NULL,/*Paniccall*/NULL,/*Releasetemporarylatches*/NULL,/*UpdateStatistics*/NULL,/*StartConsistentSnapshot*/NULL,/*Flushlogs*/NULL,/*Showstatus*/NULL,/*ReplicationReportSentBinlog*/HTON_CAN_RECREATE};下面给出了来自handler.h的handlerton定义:

typedefstruct{constchar*name;SHOW_COMP_OPTIONstate;constchar*comment;enumdb_typedb_type;bool(*init)();uintslot;uintsavepoint_offset;int(*close_connection)(THD*thd);int(*savepoint_set)(THD*thd,void*sv);int(*savepoint_rollback)(THD*thd,void*sv);int(*savepoint_release)(THD*thd,void*sv);int(*commit)(THD*thd,boolall);int(*rollback)(THD*thd,boolall);int(*prepare)(THD*thd,boolall);int(*recover)(XID*xid_list,uintlen);int(*commit_by_xid)(XID*xid);int(*rollback_by_xid)(XID*xid);void*(*create_cursor_read_view)();void(*set_cursor_read_view)(void*);void(*close_cursor_read_view)(void*);handler*(*create)(TABLE*table);void(*drop_database)(char*path);int(*panic)(enumha_panic_functionflag);int(*release_temporary_latches)(THD*thd);int(*update_statistics)();int(*start_consistent_snapshot)(THD*thd);bool(*flush_logs)();bool(*show_status)(THD*thd,stat_print_fn*print,enumha_stat_typestat);int(*repl_report_sent_binlog)(THD*thd,char*log_file_name,my_off_tend_offset);uint32flags;}handlerton;共有30个handlerton元素,但只有少量元素是强制性的(明确地讲是前4个元素和第21个元素)。

1.存储引擎的名称。

这是创建表时将使用的名称(CREATETABLE...ENGINE=FOO;)。

2.确定使用SHOWSTORAGEENGINES命令时是否列出存储引擎。

3.存储引擎注释,对使用SHOWSTORAGEENGINES命令时显示的存储引擎的描述。

4.在MySQL服务器内唯一识别存储引擎的整数。

内置存储引擎使用的常数定义在handler.h文件中。

作为创建常数的可选方法,可使用大于25的整数。

5.指向存储引擎初始化程序的指针。

仅当启动服务器时才调用该函数,以便在实例化处理程序之前,存储引擎类能执行必要的内务操作。

6.

插槽。

保存每连接的信息时,每个存储引擎在thd中有自己的内存区域(实际上为指针)。

它是作为thd->ha_data[foo_hton.slot]访问的。

插槽编号在调用foo_init()后由MySQL初始化。

7.保存点偏移。

为了保存每个savepoint数据,为存储引擎提供了请求的大小(典型情况下为0)。

必须以静态方式初始化savepoint偏移,使其具有所有的内存大小,以便保存每个savepoint的信息。

在foo_init之后,它被更改为savepoint存储区域的偏移,存储引擎不需要使用它。

8.由事务性存储引擎使用,清理其存储段内分配的内存,和/或回滚任何未完成的事务。

9.由事务性存储引擎选择性使用,创建savepoint(保存点),并将其保存到提供的内存中。

10.指向处理程序rollback_to_savepoint()函数的函数指针。

它用于在事务期间返回savepoint。

仅对支持保存点的存储引擎才会填充它。

11.指向处理程序release_savepoint()函数的函数指针。

它用于在事务期间释放保存点的资源。

仅对支持保存点的存储引擎才会填充它。

12.指向处理程序commit()函数的函数指针。

它用于提交事务。

仅对支持事务的存储引擎才会填充它。

13.指向处理程序rollback()函数的函数指针。

它用于回滚交易。

仅对支持事务的存储引擎才会填充它。

14.XA事务性存储引擎所需。

为提交操作准备事务。

将XID与事务关联起来。

15.XA事务性存储引擎所需。

恢复由XID标识的事务。

16.XA事务性存储引擎所需。

提交由XID标识的事务。

17.XA事务性存储引擎所需。

回滚由XID标识的事务。

18.与服务器端光标一起使用,尚未实施。

19.与服务器端光标一起使用,尚未实施。

20.与服务器端光标一起使用,尚未实施。

21.MANDATORY:

构造并返回处理程序实例。

22.撤销方案时,如果存储引擎需要执行特殊步骤时使用(如在使用表空间的存储引擎中使用)。

23.清理在服务器关闭和崩溃时调用的函数。

24.InnoDB特殊函数。

25.在启动SHOWSTATUS时调用InnoDB特殊函数。

26.调用InnoDB特殊函数以开始连续读取。

27.调用它,指明应将日志刷新为可靠的存储。

28.在存储引擎上提供可被人员读取的状态信息。

29.InnoDB特殊函数用于复制。

30.Handlerton标志,通常与ALTERTABLE相关。

可能的值定义于sql/handler.h文件中,并在此列出;

31.#defineHTON_NO_FLAGS032.#defineHTON_CLOSE_CURSORS_AT_COMMIT(1<<0)33.#defineHTON_ALTER_NOT_SUPPORTED(1<<1)34.#defineHTON_CAN_RECREATE(1<<2)35.#defineHTON_FLUSH_AFTER_RENAME(1<<3)36.#defineHTON_NOT_USER_SELECTABLE(1<<4)HTON_ALTER_NOT_SUPPORTED由FEDERATED存储引擎使用,用以指明存储引擎不接受AFTERTABLE语句。

HTON_FLUSH_AFTER_RENAME指明,重命名表后,必须调用FLUSHLOGS。

HTON_NOT_USER_SELECTABLE指明存储引擎不能由用户选择,而是用作系统存储引擎,如用于二进制日志的伪存储引擎。

16.5.对处理程序进行实例化处理

调用存储引擎的第1个方法是调用新的处理程序实例。

在存储引擎源文件中定义handlerton之前,必须定义用于函数实例化的函数题头。

下面给出了1个来自CSV引擎的示例:

statichandler*tina_create_handler(TABLE*table);正如你所见到的那样,函数接受指向处理程序准备管理的表的指针,并返回处理程序对象。

定义了函数题头后,用第21个handlerton元素中的函数指针命名函数,指明函数负责生成新的处理程序实例。

下面给出了MyISAM存储引擎的实例化函数示例:

statichandler*myisam_create_handler(TABLE*table){returnnewha_myisam(table);}该调用随后与存储引擎的构造程序一起工作。

下面给出了来自FEDERATED存储引擎的1个示例:

ha_federated:

:

ha_federated(TABLE*table_arg):

handler(&federated_hton,table_arg),mysql(0),stored_result(0),scan_flag(0),ref_length(sizeof(MYSQL_ROW_OFFSET)),current_position(0){}下面给出了来自EXAMPLE存储引擎的另一个示例:

ha_example:

:

ha_example(TABLE*table_arg):

handler(&example_hton,table_arg){}FEDERATED示例中的附加元素是处理程序的额外初始化要素。

所要求的最低实施是EXAMPLE示例中显示的handler()初始化。

16.6.定义表扩展

就给定的表、数据和索引,要求存储引擎为MySQL服务器提供存储引擎所使用的扩展列表。

扩展应采用以Null终结的字符串数组形式。

下面给出了CSV引擎使用的数组:

staticconstchar*ha_tina_exts[]={".CSV",NullS};调用bas_ext()函数时返回该数组。

constchar**ha_tina:

:

bas_ext()const{returnha_tina_exts;}通过提供扩展信息,你还能忽略DROPTABLE功能的实施,这是因为,通过关闭表并用你指定的扩展删除所有文件,MySQL服务器能实现该功能。

16.7.创建表

一旦实例化了处理程序,所需的第1个操作很可能是创建表。

你的存储引擎必须实现create()虚拟函数:

virtualintcreate(constchar*name,TABLE*form,HA_CREATE_INFO*info)=0;该函数应创建所有必须的文件,然后关闭表。

MySQL服务器将调用随后需打开的表。

*name参数是表的名称。

*form参数是st_table结构,该结构定义了表并与MySQL服务器已创建的tablename.frm文件的内容匹配。

在大多数情况下,存储引擎不需要更改tablename.frm文件,也没有支持该操作的预置功能。

*info参数是包含CREATETABLE语句用于创建表所需信息的结构。

该结构定义于handler.h文件中,并为了便于参考列于下面:

typedefstructst_ha_create_information{CHARSET_INFO*table_charset,*default_table_charset;LEX_STRINGconnect_string;constchar*comment,*password;constchar*data_file_name,*index_file_name;constchar*alias;ulonglongmax_rows,min_rows;ulonglongauto_increment_value;ulongtable_options;ulongavg_row_length;ulongraid_chunksize;ulongused_fields;SQL_LISTmerge_list;enumdb_typedb_type;enumrow_typerow_type;uintnull_bits;/*NULLbitsatstartofrecord*/uintoptions;/*ORofHA_CREATE_options*/uintraid_type,raid_chunks;uintmerge_insert_method;uintextra_size;/*lengthofextradatasegment*/booltable_existed;/*1increateiftableexisted*/boolfrm_only;/*1ifnoha_create_table()*/boolvarchar;/*1iftablehasaVARCHAR*/}HA_CREATE_INFO;基本的存储引擎能忽略*form和*info的内容,这是因为,真正所需的是创建存储引擎所使用的数据文件,以及对数据文件的可能初始化操作(假定存储文件是基于文件的)。

下面给出了来自CSV存储引擎的实施示例:

intha_tina:

:

create(constchar*name,TABLE*table_arg,HA_CREATE_INFO*create_info){charname_buff[FN_REFLEN];Filecreate_file;DBUG_ENTER("ha_tina:

:

create");if((create_file=my_create(fn_format(name_buff,name,"",".CSV",MY_REPLACE_EXT|MY_UNPACK_FILENAME),0,O_RDWR|O_TRUNC,MYF(MY_WME)))<0)DBUG_RETURN(-1);my_close(create_file,MYF(0));DBUG_RETURN(0);}在前面的例子中,CSV引擎未引用*table_arg或*create_info参数,而是简单地创建了所需的数据文件,关闭它们,并返回。

my_create和my_close函数是定义于src/include/my_sys.h文件中的助手函数。

16.8.打开表

在表上执行任何读或写操作之前,MySQL服务器将调用open()方法打开表数据和索引文件(如果存在的话)。

intopen(constchar*name,intmode,inttest_if_locked);第1个参数是要打开的表的名称。

第2个参数确定了要打开的文件或准备执行的操作。

它们的值定义于handler.h中,并为了方便起见列在下面:

#defineHA_OPEN_KEYFILE1#defineHA_OPEN_RNDFILE2#defineHA_GET_INDEX4#defineHA_GET_INFO8/*doaha_info()afteropen*/#defineHA_READ_ONLY16/*Fileopenedasreadonly*/#defineHA_TRY_READ_ONLY32/*Tryreadonlyifcan'topenwithreadandwrite*/#defineHA_WAIT_IF_LOCKED64/*Waitiflockedonopen*/#defineHA_ABORT_IF_LOCKED128/*skipiflockedonopen.*/#defineHA_BLOCK_LOCK256/*unlockwhenreadingsomerecords*/#defineHA_OPEN_TEMPORARY512最后一个选项规定了是否要在打开表之前检查表上的锁定。

在典型情况下,存储引擎需要实施某种形式的共享访问控制,以防止在多线程环境下的文件损坏。

关于如何实施文件锁定的示例,请参见sql/examples/ha_tina.cc的get_share()和free_share()方法。

16.9.实施基本的表扫描功能

16.9.1.实施store_lock()函数

16.9.2.实施external_lock()函数

16.9.3.实施rnd_init()函数

16.9.4.实施info()函数

16.9.5.实施extra()函数

16.9.6.实施rnd_next()函数

最基本的存储引擎能实现只读表扫描功能。

这类引擎可用于支持SQL日志查询、以及在MySQL之外填充的其他数据文件。

本节介绍的方法实施提供了创建更高级存储引擎的基础。

下面给出了在CSV引擎的9行表扫描过程中进行的方法调用:

ha_tina:

:

store_lock

ha_tina:

:

external_lock

ha_tina:

:

info

ha_tina:

:

rnd_init

ha_tina:

:

extra-ENUMHA_EXTRA_CACHECacherecordinHA_rrnd()

ha_tina:

:

rnd_next

ha_tina:

:

rnd_next

ha_tina:

:

rnd_next

ha_tina:

:

rnd_next

ha_tina:

:

rnd_next

ha_tina:

:

rnd_next

ha_tina:

:

rnd_next

ha_tina:

:

rnd_next

ha_tina:

:

rnd_next

ha_tina:

:

extra-ENUMHA_EXTRA_NO_CACHEEnd

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1