十分钟包会MySQL插件开发

请看下面的MySQL UDF插件模版,通过C执行shell语句。所以只要替换shell语句的位置,保存并编译。duang的一下,你的MySQL插件就成功出炉。 模板代码如下:

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

#ifdef STANDARD
#include <string.h>
#include <stdlib.h>
#include <time.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong;
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#else
#include <my_global.h>
#include <my_sys.h>
#endif
#include <mysql.h>
#include <m_ctype.h>
#include <m_string.h>
#include <stdlib.h>

#include <ctype.h>

#ifdef HAVE_DLOPEN
#ifdef  __cplusplus
extern "C" {
#endif

#define LIBVERSION "wx_man_func alpha,ver 0.1a"

#ifdef __WIN__
#define SETENV(name,value)              SetEnvironmentVariable(name,value);
#else
#define SETENV(name,value)              setenv(name,value,1);
#endif

/**
 * wx_get_datadirsize
 * 
 * mysql datadir's dir du size.
 * 下面是函数注册信息,UDF函数名。
 */

DLLEXP 
my_bool wx_get_datadirsize_init(
        UDF_INIT *initid
,       UDF_ARGS *args
,       char *message
);

DLLEXP 
void wx_get_datadirsize_deinit(
        UDF_INIT *initid
);

DLLEXP 
char* wx_get_datadirsize(
        UDF_INIT *initid
,       UDF_ARGS *args
,       char* result
,       unsigned long* length
,       char *is_null
,       char *error
);



#ifdef  __cplusplus
}
#endif


/**
* common functions
**/

char* shell_exec(
        char* cmd,
        char* result,
        char *is_null
){
        FILE *pipe;
        char line[1024];
        unsigned long outlen, linelen;

        result = malloc(1);
        outlen = 0;

        pipe = popen(cmd, "r");

        while (fgets(line, sizeof(line), pipe) != NULL) {
                linelen = strlen(line);
                result = realloc(result, outlen + linelen);
                strncpy(result + outlen, line, linelen);
                outlen = outlen + linelen;
        }

        pclose(pipe);

        if (!(*result) || result == NULL) {
                *is_null = 1;
        } else {
                result[outlen] = 0x00;
        }

        return result;
}

char * str_replace(char* ori, char* pat, char* rep)  
{
        size_t const replen = strlen(rep);  
        size_t const patlen = strlen(pat);  
        size_t const orilen = strlen(ori);  
        int patcnt = 0;  

        char* pOri;
        char* pOriPat;

        for (pOri = ori; (pOriPat = strstr(pOri, pat)); pOri = pOriPat + patlen) patcnt++;
        char * sRt = (char *) malloc( sizeof(char) * (orilen + patcnt * (replen - patlen) + 1) );

        if (sRt != NULL)  
        {
                char * pRt = sRt;  
                for (pOri = ori; (pOriPat = strstr(pOri, pat)); pOri = pOriPat + patlen)
                {
                        int pos = pOriPat - pOri;
                        strncpy(pRt, pOri, pos);
                        pRt += pos;
                        strncpy(pRt, rep, replen);
                        pRt += replen;  
                }

                strcpy(pRt, pOri);
        }
        sRt[sizeof(char) * (orilen + patcnt * (replen - patlen))] = '\0';
        return sRt;
}



my_bool wx_get_datadirsize_init(
        UDF_INIT *initid
,       UDF_ARGS *args
,       char *message
){
        if(args->arg_count!=0){
                strcpy(
                        message
                ,       "No arguments allowed (udf: wx_man_func)"
                );
                return 1;
        } else {
                return 0;
        }
}
void wx_get_datadirsize_deinit(
        UDF_INIT *initid
){
}
char* wx_get_datadirsize(
        UDF_INIT *initid,
        UDF_ARGS *args,
        char* result,
        unsigned long* length,
        char *is_null,
        char *error
){
        char *cmd = "du -h|sed 's/\\.\\///'|awk '{print $2,$1}'|sort";
        result = shell_exec(cmd, result, is_null);
        *length = strlen(result);
return result;
}
#endif /* HAVE_DLOPEN */

我定义了一个wx_get_datadirsizehh函数,函数的内容是执行shell命令"du -h|sed 's/\\.\\///'|awk '{print $2,$1}'|sort",并输出结果。 所以要做实现自己的功能,只要替换函数名称,并且修改cmd变量(下划线部分)为需要的shell命令,保存为.c文件并编译,就可以使用了。 安装方式: 1、文件保存为 wx_man_func.c 2、编译 gcc wx_man_func.c -I /usr/local/mysql/include -fPIC -shared -o wx_man_func 3、复制.so到mysql安装目录的plugin文件夹,如 /usr/local/mysql/lib/mysql/plugin/wx_man_func.so 4、install plugin:create function wx_getbigtable RETURNS int SONAME 'wx_man_func.so' 使用效果:

MySQL [(none)]> create function wx_get_datadirsize RETURNS string SONAME 'wx_man_func.so';        
Query OK, 0 rows affected (0.03 sec)

MySQL [(none)]> select wx_get_datadirsize();                                              
+-----------------------------------------------------------------+
| wx_get_datadirsize()                                            |
+-----------------------------------------------------------------+
| . 914G
  test 914G
  mysql 22M
  performance_schema 1.1M
  sys 676K                                                         |
+------------------------------------------------------------------+
1 row in set (0.13 sec)

MySQL [(none)]> create function wx_get_cnf RETURNS string SONAME 'wx_man_func.so';           
Query OK, 0 rows affected (0.03 sec)

MySQL [(none)]> select wx_get_cnf('key_buffer');                                                 
+--------------------------------+
| wx_get_cnf('key_buffer')       |
+--------------------------------+
| 256M                           |
+--------------------------------+
1 row in set (0.12 sec)

可以看到,wx_get_datadirsize函数获取了mysql数据目录的文件夹内容。

如上,我在插件里还做了个wx_get_cnf函数,可以获取指定my.cnf里的内容。鹅们可以自己想想实现其它的功能。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逸鹏说道

程序猿是如何解决SQLServer占CPU100%的

文章目录 遇到的问题 使用SQLServer Profiler监控数据库 SQL1:查找最新的30条告警事件 SQL2:获取当前的总报警记录数 有哪些SQL语句...

38480
来自专栏维C果糖

史上最简单的 MySQL 教程(十四)「列属性 之 主键」

主键:primary key,表中主要的键,每张表只能有一个字段(复合主键,可以多个字段)使用此属性,用来唯一的约束该字段里面的数据,不能重复。

455110
来自专栏唐郑望的专栏

Django数据处理的一些实践

提到 Django 肯定避不开 MVC 模式,即模型(Model)-视图(View)-控制器(Controller),通过将业务逻辑、数据、界面显示分离的方法组...

34010
来自专栏程序猿

mysql 命令大全

1、连接到本机上的MYSQL。 首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root -p,回车后提示你输密码.注意用户名前...

368110
来自专栏C/C++基础

MySQL入门常用命令大全

SQL(Structured Query Language)是结构化查询语言,也是一种高级的非过程化编程语言。SQL语句可用于增删查改数据以及管理关系型数据库,...

12720
来自专栏idba

MySQL 5.7 新特性之三

本系列文章基于5.7.20 版本讲述MySQL的新特性,从安装,文件结构,SQL,优化,复制等几个方面展开介绍5.7 的新特性和功能,同时也建议大家跟踪官方bl...

10520
来自专栏码神联盟

珍藏 | Java 岗位 【数据库】 面试题及答案详解

29520
来自专栏JavaWeb

MySQL-大批量数据如何快速的数据迁移

31220
来自专栏运维技术迷

连仕彤博客Mysql数据库归档利器之pt-archiver

25960
来自专栏高爽的专栏

Oracle学习记录

       oracle学习过程中记录的一些知识点,包括sqlplus一些命令、角色、DML、DCL、DDL、数据字典、表空间、函数。 1. sys 超级管...

20800

扫码关注云+社区

领取腾讯云代金券