MySQL通过UDF实现扩展功能(Linux环境和Windows环境)

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 17:23   2507   0

最近项目数据库选型,对于自治事务这个特性,MySQL不支持,在MySQL和PostGreSQL之间权衡对比了一段时间,后来发现,通过UDF可以实现,因此,最终敲定了MySQL,下面来记录下过程:

环境说明:

- 服务器环境: 前面基于CentOS7.1测试,后面基于Windows NT架构的系统进行测试

- 数据库环境: MYSQL5.7.19

UDF,也就是user definition function,通过动态库方式实现,因此,我们要做的,就是需要编译出一个动态链接库so或dll。

测试代码如下:

#include <my_global.h>
#include <my_sys.h>

#include <mysql.h>
#include <m_ctype.h>
#include <m_string.h>
#include <stdlib.h>

#include <ctype.h>

#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
    #define DLLEXP __declspec(dllexport)
#else
    #define DLLEXP
#endif

/* 自定义的函数 */
DLLEXP long long udf_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
/* 对应自定义函数的初始化和结束的函数,在调用udf_add函数时由系统调用 */
DLLEXP my_bool udf_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
DLLEXP void udf_add_deinit(UDF_INIT *initid);

long long udf_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
        int a = *((long long *)args->args[0]);
        int b = *((long long *)args->args[1]);

        return a + b;
}

my_bool udf_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
        return 0;
}

void udf_add_deinit(UDF_INIT *initid)
{
        //
}
Makefile文件如下:
LIBDIR=/usr/local/mysql/lib/plugin

install:
        gcc -Wall -fPIC -I/usr/local/mysql/include -I. -shared my_udf.c -o ${LIBDIR}/my_udf.so

编译:


可以看到,动态库已经正确生成了,下面调用测试一下,步骤如下:

1. 登录数据库

2. 新建测试库

3. 安装动态库,新建函数

4. 调用测试

如下截图步骤:


基本的功能可以实现,那么,接下来,就可以通过linux系统下的编程,实现系统命令的调用,在mysql中就可以调用shell脚本和python等功能脚本了。

在GitHub上有这个项目了,可以下载下来使用。


把这个文件夹放到linux服务器,执行install.sh脚本就行,注意,需要修改一下Makefile文件中相关参数为你自己系统的路径,另外,要生成so动态链接库,gcc需要加参数-fPIC,生成so库后,执行lib_mysqludf_sys.sql脚本就可以通过函数调用脚本了,当然,后面还可以自己扩展更多实用的功能,注意,如果涉及目录及文件的操作,其权限必须对mysql用户开放,因为我的mysql是用mysql用户启动运行的。

------------------------------ 华丽丽的分割线 --------------------------------------------

上面实在linux系统上测试的,接下来,在windows下面进行测试:

1. 开发环境IDE使用VS2015社区版,新建工程


//


2. 导入下载的C文件,修改文件后缀为c


3. 配置环境参数:


//


//

修改函数popen等为_popen,这是windows平台下的函数:


4. 生成dll


5. 测试调用:

首先创建函数:

DROP FUNCTION IF EXISTS lib_mysqludf_sys_info;
DROP FUNCTION IF EXISTS sys_get;
DROP FUNCTION IF EXISTS sys_set;
DROP FUNCTION IF EXISTS sys_exec;
DROP FUNCTION IF EXISTS sys_eval;

CREATE FUNCTION lib_mysqludf_sys_info RETURNS string SONAME 'Win32Project1.dll';
CREATE FUNCTION sys_get RETURNS string SONAME 'Win32Project1.dll';
CREATE FUNCTION sys_set RETURNS int SONAME 'Win32Project1.dll';

CREATE FUNCTION sys_exec RETURNS int SONAME 'Win32Project1.dll';

CREATE FUNCTION sys_eval RETURNS string SONAME 'Win32Project1.dll';

调用:



更多扩展知识可以参考mysql5.7版本的手册:


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP