MySQL中ext的使用方法介绍(mysql中ext)

MySQL中ext的使用方法介绍

在MySQL中,ext是指扩展存储引擎。MySQL提供了多个内置的存储引擎,如MyISAM和InnoDB,但是有时候这些内置的存储引擎不能满足特殊的需求。这时就需要通过MySQL的扩展存储引擎来实现。本文将介绍MySQL中ext的使用方法。

一、ext的安装

MySQL扩展存储引擎需要用到C/C++编译器和MySQL头文件。在安装MySQL后,可以使用以下命令安装扩展存储引擎:

sudo apt-get install libmysqlclient-dev
sudo apt-get install libmysqld-dev

安装完成后,需要重新编译MySQL:

sudo cmake -DWITH_EXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8mb4 .
sudo make
sudo make install

二、ext的使用

在MySQL中使用ext,需要先创建扩展存储引擎。创建扩展存储引擎需要创建以下文件:

– ha_foo.cc:代码文件,实现存储引擎的核心逻辑。

– config.h:配置文件,定义需要使用哪些MySQL头文件和C++库。

– CMakeLists.txt:编译文件,用于编译生成扩展存储引擎的二进制文件。

下面我们以创建一个名为foo的扩展存储引擎为例,介绍具体步骤。

1. 创建ha_foo.cc文件,实现存储引擎的核心逻辑。

“`c++

#include “mysql/plugin.h”

#include “ha_foo.h”

static handler* foo_create_handler(handlerton*hton, TABLE_SHARE*table, MEM_ROOT*mem_root) {

return new (mem_root) ha_foo(hton, table);

}

ha_foo::ha_foo(handlerton*hton, TABLE_SHARE*table) : handler(hton, table) {

// 构造函数,可以初始化一些参数

}

ha_foo::~ha_foo() {

// 析构函数,需要释放资源

}

int ha_foo::open(const char*name, int mode, uint test_if_locked) {

// 打开表

}

int ha_foo::close(void) {

// 关闭表

}

int ha_foo::write_row(uchar*buf) {

// 写入行

}

int ha_foo::update_row(const uchar*old_data, uchar*new_data) {

// 更新行

}

int ha_foo::delete_row(const uchar*buf) {

// 删除行

}

int ha_foo::index_read_map(uchar*buf, const uchar*key, key_part_map keypart_map,

enum ha_rkey_function find_flag) {

// 索引读取行

}

/*

* 定义存储引擎的信息

*/

static struct st_mysql_storage_engine foo_storage_engine = {

MYSQL_HANDLERTON_INTERFACE_VERSION,

“foo”, /* 插件名称 */

NULL, /* 插件属性 */

foo_create_handler, /* handler创建函数 */

NULL, /* 插件初始化函数 */

NULL, /* 插件退出函数 */

NULL, /* 插件状态函数 */

NULL, /* 插件信息函数 */

1, /* 插件 API 版本号 */

STANDARD_MYSQL_EXTENSION_LAYER_BASE, /* 插件基础层次 */

0 /* 插件当前层次 */

};

/*

* 注册存储引擎

*/

mysql_declare_plugin(foo)

{

MYSQL_STORAGE_ENGINE_PLUGIN,

&foo_storage_engine,

“foo storage engine plugin”,

“GPL”,

NULL,

NULL,

NULL,

NULL,

NULL

}

mysql_declare_plugin_end;


2. 创建config.h文件,定义需要使用哪些MySQL头文件和C++库。

```c++
#ifndef __FOO_CONFIG_H__
#define __FOO_CONFIG_H__

/* MySQL头文件 */
#include
#include
#include
#include
#endif /* __FOO_CONFIG_H__ */

3. 创建CMakeLists.txt文件,用于编译生成扩展存储引擎的二进制文件。

“`cmake

project(foo)

include_directories(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/include)

set(PLUGIN_FOO_SRC ha_foo.cc)

add_library(foo MODULE ${PLUGIN_FOO_SRC})

target_link_libraries(foo mysqlclient)

set_target_properties(foo PROPERTIES PREFIX “”)

set_target_properties(foo PROPERTIES OUTPUT_NAME “foo”)


4. 编译扩展存储引擎。

执行以下命令:

cmake ../

make

make install


5. 在MySQL中加载扩展存储引擎。

在MySQL的配置文件中添加以下内容:

[mysqld]

plugin_dir=/usr/local/mysql/lib/plugin


将上面创建的扩展存储引擎文件复制到/usr/local/mysql/lib/plugin目录下。然后在MySQL中执行以下命令来加载扩展存储引擎:

```sql
CREATE TABLE t1 (id INT, name VARCHAR(100)) ENGINE=foo;

在以上命令中,ENGINE=foo指定使用扩展存储引擎foo来创建表t1。

三、ext的示例

以下为一个示例程序,实现了一个简单的存储引擎,可以写入、更新、删除、读取和扫描数据:

“`c++

#include “mysql/plugin.h”

#include “ha_foo.h”

static handler* foo_create_handler(handlerton*hton, TABLE_SHARE*table, MEM_ROOT*mem_root) {

return new (mem_root) ha_foo(hton, table);

}

ha_foo::ha_foo(handlerton*hton, TABLE_SHARE*table) : handler(hton, table) {

row_size = 7;

}

ha_foo::~ha_foo() {

}

int ha_foo::open(const char*name, int mode, uint test_if_locked) {

return 0;

}

int ha_foo::close(void) {

return 0;

}

int ha_foo::write_row(uchar*buf) {

uint32_t id = uint4korr(buf);

uint16_t len = uint2korr(buf + 4);

char*name = (char*)(buf + 6);

std::cout<"write_row: id="<<id<<" name="<<name<<std::endl;

data[id] = std::string(name, len);

return 0;

}

int ha_foo::update_row(const uchar*old_data, uchar*new_data) {

uint32_t id = uint4korr(old_data);

uint32_t old_len = uint2korr(old_data + 4);

char*old_name = (char*)(old_data + 6);

uint32_t new_len = uint2korr(new_data + 4);

char*new_name = (char*)(new_data + 6);

std::cout<<" update_row:="" id="<<id<<" old_name="<<old_name<<" new_name="<<new_name<<std::endl;

if (data.find(id) == data.end()) {

return HA_ERROR_RECORD_NOT_FOUND;

}

data[id] = std::string(new_name, new_len);

return 0;

}

int ha_foo::delete_row(const uchar*buf) {

uint32_t id = uint4korr(buf);

std::cout<<" delete_row:="" id="<<id<<std::endl;

if (data.find(id) == data.end()) {

return HA_ERROR_RECORD_NOT_FOUND;

}

data.erase(id);

return 0;

}

int ha_foo::index_read_map(uchar*buf, const uchar*key, key_part_map keypart_map,

enum ha_rkey_function find_flag) {

uint32_t id = uint4korr(key);

std::cout<<" index_read_map:="" id="<<id<<std::endl;

auto it = data.find(id);

if (it == data.end()) {

return HA_ERR_END_OF_FILE;

}

uint16_t len = it->second.length();

memcpy(buf, key, 4);

memcpy(buf + 4, &len, 2);

memcpy(buf + 6, it->second.c_str(), len);

return 0;

}

int ha_foo::index_read(uchar*buf, const uchar*key, uint key_len, enum ha_rkey_function find_flag) {

uint32_t id = uint4korr(key);

std::cout<<" index_read:="" id="<<id<<std::endl;

auto it = data.find(id);

if (it == data.end()) {

return HA_ERR_END_OF_FILE;

}

uint16_t len = it->second.length();

memcpy(buf, key, 4);

memcpy(buf + 4, &len, 2);

memcpy(buf + 6, it->second.c_str(), len);

return 0;

}

int ha_foo::index_first(uchar*buf, enum ha_rkey_function find_flag) {

if (data.empty()) {

return HA_ERR_END_OF_FILE;

}

auto it = data.begin();

uint16_t len = it->second.length();

memcpy(buf, &it->first, 4);

memcpy(buf + 4, &len, 2);

memcpy(buf + 6, it->second.c_str(), len);

return 0;

}

int ha_foo::index_next(uchar*buf, enum ha_rkey_function find_flag) {

uint32_t id = uint4korr(buf);

std::cout<<" index_next:="" id="<<id<<std::endl;

auto it = data.find(id);

if (it == data.end()) {

return HA_ERR_END_OF_FILE;

}

++it;

if (it == data.end()) {

return HA_ERR_END_OF_FILE;

}

uint16_t len = it->second.length();

memcpy(buf, &it->first, 4);

memcpy(buf + 4, &len, 2);

memcpy(buf + 6, it->second.c_str(), len);

return 0;

}

int ha_foo::index_prev(uchar*buf, enum ha_rkey_function find_flag) {

uint32_t id = uint4korr(buf);

std::cout<<" index_prev:="" id="<<id<<std::endl;

auto it = data.find(id);

if (it == data.end()) {

return HA_ERR_END_OF_FILE;

}

if (it == data.begin()) {

return HA_ERR_END_OF_FILE;

}

–it;

uint16_t len = it->second.length();

memcpy(buf, &it->first, 4);

memcpy(buf + 4, &len, 2);

memcpy(buf + 6, it->second.c_str(), len);

return 0;

}

int ha_foo::index_last(uchar*buf, enum ha_rkey_function find_flag) {

if (data.empty()) {

return HA_ERR_END_OF_FILE;

}

auto it = data.end();

–it;

uint16_t len = it->second.length();

memcpy(buf, &it->first, 4);

memcpy(buf + 4, &len, 2);

memcpy(buf + 6, it->second.c_str(), len);

return 0;

}

const char* ha_foo::table_type() const {

return “>

}

/*

* 定义存储引擎的信息

*/

static struct st_mysql_storage_engine foo_storage_engine = {

MYSQL_HANDLERTON_INTERFACE_VERSION,

“foo”, /* 插件名称 */

NULL, /* 插件属性 */

foo_create_handler, /* handler创建函数 */

NULL, /* 插件初始化函数 */

NULL, /* 插件退出函数 */

NULL, /* 插件状态函数 */

NULL, /* 插件信息函数 */

1, /* 插件 API 版本号 */

STANDARD_MYSQL_EXTENSION_LAYER_BASE, /* 插件基础层次 */

0 /* 插件当前层次 */

};

/*

* 注册存储引擎

*/

mysql_declare_plugin(foo)

{

MYSQL_STORAGE_ENGINE_PLUGIN,

&foo_storage_engine,

“foo storage engine plugin”,

“GPL”,

NULL,

NULL,

NULL,

NULL,

NULL

}

mysql_declare_plugin_end;


执行以下命令编译扩展存储引擎:

mkdir -p build

cd build

cmake ../

make


然后将生成的文件复制到/usr/local/mysql/lib/plugin目录下。在MySQL中执行以下命令来加载扩展存储引擎:

```sql
CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(100)) ENGINE=foo;
INSERT INTO t1 VALUES (1, "foo"), (2, "bar"), (3, "baz");

SELECT * FROM t1 WHERE id = 2;

UPDATE t1 SET name = "bbb" WHERE id = 2;

SELECT * FROM t1;

DELETE FROM t1 WHERE id = 1;

SELECT * FROM t1;

SELECT * FROM t1 WHERE id > 1;

以上命令创建表t1,插入数据,并执行了一些操作。每个操作都会在控制台输出一些信息,以便查看扩展存储引擎的运行情况。


数据运维技术 » MySQL中ext的使用方法介绍(mysql中ext)