MySQL如何创建自定义储存引擎(一)

MySQL如何创建自定义储存引擎 - Custom Storage Engine

前言

MySQL 是支持动态可插拔的储存引擎体系架构,从而可以创建新的储存引擎并直接将其添加到正在运行的 MySQL 中,而无需重新编译 MySQL。

这种架构使得为 MySQL 开发新的储存引擎和部署变得更加容易。

本系列文章主要是想谈谈自定义储存引擎的一些创建指南,部分是官网的翻译,部分是自己的理解。

概述

储存引擎在 MySQL 中的作用主要是进行 data 和 index 数据的存储和管理。

MySQL 服务器通过一系列的 API 来与储存引擎交互。

每一个储存引擎都有一个类定义,并且都继承于一个特殊的接口类 handler,这个类通常都会被命名为 ha_xxx (比如说 innodb 命名为 ha_innobasendb 命名为 ha_ndbcluster)。

handler 类上定义了一系列表 table 的接口:

create 创建表;
open 打开表;
delete_table 删除表;
write_row 插入记录;
delete_row 删除记录;
update_row 更新记录
……
等等

实现自定义的储存引擎,需要一一实现这些接口,这些接口就是 SQL 层与储存引擎交互的 API

在实现这些接口之前,需要搞明白 handler 的一些特性。

  • handler 是表级别的
    handler 是句柄的概念,而且是表的句柄,所有的接口方法都是针对于表的:
  • handler 句柄与连接会话的关系
    MySQL 是单进程多线程的 CS 模型,每条 SQL 可能涉及到一张表或多张表,但每涉及到一张表时,必然是通过先获取到该表的一个handler句柄,然后通过句柄对该表进行 DDLCRUD 等操作的。

所以 handler 是基于表和连接会话的,每一个连接的每一个表都有一个独立的句柄,保证互相独立。

举例:
如果有 3 个连接同时访问同一张表, 那么需要初始化创建3个该表的handler句柄。
同理,一个连接的一条 SQL 涉及到 2 张表,那么也需要分别获取这 2 张表的各 1 个句柄。

Tips:
本处句柄概念同文件系统的文件句柄,在一个文件系统中,不同应用同时打开同一个文件,其实每一个应用都会创建获取到该文件的一个句柄,如果同一个应用需要打开多个文件,那么需要获取每一个文件的句柄。
文件系统已经定义了文件的 API 接口,通过句柄调用不同的方法对文件进行操作。

实现自定义的储存引擎,即是通过继承 handler 类,通常命名为 ha_xxx ,实现其对应与表的接口即是。

handler 和 handlerton

handler 是每个存储引擎定义表相关行为操作的接口类,是表级别的行为接口。

handlerton ( handler singleton 的缩写),则是定义了一个存储引擎插件属性和行为的类,可视为引擎级别。

通常一个储存引擎只会实例出一个 handlerton 实例,目的是提供存储引擎的一些 global 级别的特性行为。

例如:
涉及到存储引擎上的事务操作,commitrollback 方法等。
handler 类(通常由自定义的 ha_xxx 继承),是 table 级别的方法,涉及的是的 per-table 的一些操作。

两者的区别可以这么理解:

  • 对于数据库而言,事务是一个单位操作,即每一个操作或一系列操作都是以事务为一个单位的。而特定的存储引擎,其事务的提交、回滚行为是统一的,即 global 级别的,与表无关,由 handlerton 负责。

  • 具体到事务操作中的每一条 SQL 时,其可能是简单的单表操作,也有可能是多表操作(multi_update/multi_delete/union/join等)。操作时,每一个表都有其属性或特定记录的 CRUD 操作,所以每个表都应该有自己的句柄,这是由 handler 类(通常由 ha_xxx 继承并实现)负责的,所以 handler 是表级别的,并且不同连接应该是有独立的 handler,即使是操作同一张表。

简而言之,存储引擎级别的,放在 handlerton 类上,表级别的,放在 handler 上。

下面分别来看看各自的定义

  • handlerton
struct handlerton
+---------------------------------------------------------------+
| state                                   : SHOW_COMP_OPTION    |
| db_type                                 : enum legacy_db_type |
| slot                                    : uint                |
| savepoint_offset                        : uint                |
| flags                                   : uint32              |
| license                                 : uint32              |
| data                                    : void *              |
| (*close_connection)()                   : int                 |
| (*kill_connection)()                    : void                |
| (*savepoint_set)()                      : int                 |
| (*savepoint_rollback)()                 : int                 |
| (*savepoint_rollback_can_release_mdl)() : bool                |
| (*savepoint_release)()                  : int                 |
| (*commit)()                             : int                 |
| (*rollback)()                           : int                 |
| (*prepare)()                            : int                 |
| (*recover)()                            : int                 |
| (*commit_by_xid)()                      : int                 |
| (*rollback_by_xid)()                    : int                 |
| *(*create)()                            : handler             |
| (*drop_database)()                      : void                |
| (*panic)()                              : int                 |
| (*start_consistent_snapshot)()          : int                 |
| (*flush_logs)()                         : bool                |
| (*show_status)()                        : bool                |
| (*partition_flags)()                    : uint                |
| (*get_tablespace)()                     : int                 |
| (*alter_tablespace)()                   : int                 |
| (*fill_is_table)()                      : int                 |
| (*binlog_func)()                        : int                 |
| (*binlog_log_query)()                   : void                |
| (*release_temporary_latches)()          : int                 |
| (*discover)()                           : int                 |
| (*find_files)()                         : int                 |
| (*table_exists_in_engine)()             : int                 |
| (*make_pushed_join)()                   : int                 |
| (*system_database)()                    : const char*         |
| (*is_supported_system_table)()          : bool                |
| (*get_cost_constants)()                 : SE_cost_constants * |
| (*replace_native_transaction_in_thd)()  : void                |
| (*notify_exclusive_mdl)()               : bool                |
| (*notify_alter_table)()                 : bool                |
| (*rotate_encryption_master_key)()       : bool                |
----------------------------------------------------------------+

对于 handlerton 来说,总体上大概有40多个成员,但只要几个是必需的,db_typecommentstatecreate()等。
+

下面是handlertonhandler 的关系,MySQL 在初始化的时候,为每一个储存引擎实例化出了各自的一个handlerton类(实例化大致流程可以参考MySQL插件(二)源码分析-InnoDB储存引擎插件定义和初始化过程),
handler有一个handlerton的指针,

handlerton
+-----Fake_handlerton
+-----hton_list_st
+-----st_alter_tablespace
+-----st_ha_create_information
+-----handler
| 		+-----ha_archive     //archive引擎
| 		+-----ha_blackhole   
| 		+-----ha_example     //示范例子
| 		+-----ha_federated   //federated存储引擎
| 		+-----ha_heap        //MEMORY存储引擎
| 		+-----ha_innobase    //innodb引擎,默认储存引擎,支持事务
| 		+-----ha_myisam      //myisam引擎,不支持事务;
| 		+-----ha_myisammrg
| 		+-----ha_ndbcluster  //分布式存储引擎
| 		+-----ha_ndbinfo
| 		+-----ha_partition  
| 		+-----ha_perfschema
| 		+-----ha_tina
| 		+-----QUICK_RANGE_SELECT
| 		+-----Partition_helper
| 		+-----TABLE
+-----partition_element
+-----partition_info
+-----YYSTYPE
+-----TABLE_SHARE
+-----Ha_trx_info

对 MySQL 自定义引擎工作感兴趣的
v 信:yutellite

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
MySQL 5.6自定义安装配置教程如下: 1. 下载MySQL 5.6安装包,可以从官网下载,也可以从其他可信渠道下载。 2. 解压安装包,将解压后的文件夹复制到你想安装的目录下。 3. 进入MySQL安装目录,找到my-default.ini文件,将其复制并重命名为my.ini。 4. 打开my.ini文件,进行以下配置: (1) 修改[mysql]部分的默认字符集为utf8mb4:default-character-set=utf8mb4 (2) 修改[mysqld]部分的默认字符集为utf8mb4:character-set-server=utf8mb4 (3) 修改[mysqld]部分的默认存储引擎为InnoDB:default-storage-engine=InnoDB (4) 修改[mysqld]部分的日志文件路径: log-error=<安装目录>\mysql_error.log general-log-file=<安装目录>\mysql_general.log slow-query-log-file=<安装目录>\mysql_slow.log (5) 如果需要设置MySQL的root用户密码,则需要在[mysqld]部分加上以下一行: skip-grant-tables 然后保存文件并退出。 5. 打开cmd命令行窗口,进入MySQL的bin目录,执行以下命令: (1) 初始化MySQL数据目录:mysqld --initialize --console (2) 安装MySQL服务:mysqld install (3) 启动MySQL服务:net start mysql 6. 如果在步骤4中设置了root用户密码,则需要执行以下命令取消skip-grant-tables选项: (1) 打开my.ini文件,注释掉skip-grant-tables这一行。 (2) 重启MySQL服务:net stop mysql && net start mysql 7. 进入MySQL的bin目录,打开mysql.exe客户端,输入用户名和密码登录MySQL数据库。 希望以上步骤能够帮助你成功安装和配置MySQL 5.6。如果你有其他问题,请继续提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

抡着鼠标扛大旗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值