请看下面的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里的内容。鹅们可以自己想想实现其它的功能。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。