首页 > 代码库 > MySql UDF 调用外部程序和系统命令

MySql UDF 调用外部程序和系统命令

1.mysql利用mysqludf的一个mysql插件可以实现调用外部程序和系统命令

下载lib_mysqludf_sys程序:https://github.com/mysqludf/lib_mysqludf_sys

2.安装说明:

2.1查询mysql插件路径:

在mysql里查询mysql插件目录的路径:show variables like “plugin_dir”;

2.2解压源码:

将下载下的插件(lib_mysqludf_sys-master.zip)解压后拷贝进/tmp目录下

#cd /tmp#cd /ib/mysqludf_sys/lib_mysqludf_sys-master/#lsMakefile                        lib_mysqludf_sys.html           install.sh                      lib_mysqludf_sys.solib_mysqludf_sys.c              lib_mysqludf_sys.sql
2.3编译源码:

修改一下Makefile文件, 根据自身系统的MySQL环境而定

# cat MakefileLIBDIR=/usr/libinstall:        gcc -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so#修改后,根据自己的系统环境决定# cat MakefileLIBDIR=/usr/lib64/mysql/plugininstall:        gcc -fPIC -Wall -I/usr/local/include/mysql -I. -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so
# make
gcc -Wall -I/usr/local/include/mysql -I. -shared lib_mysqludf_sys.c -o /usr/lib64/mysql/plugin/lib_mysqludf_sys.so
#说明:不确定需不需要执行这一步,我执行了。有的教程说用,有的没说。
#chcon -t texrel_shlib_t mysql/lib/mysql/plugin/lib_mysqludf_sys.so

#备注:
#下面是另一个教程的编译方法,未测试,不知道可以不可以,上面是我自己的编译方法,建议上面的方法(如果用上个编译方法,则不需要再执行下面的编译)
#gcc -DMYSQL_DYNAMIC_PLUGIN -fPIC -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so

到这里就已经正常的编译出了.so文件了,可以查看/usr/lib64/mysql/plugin目录下是否有lib_mysqludf_sys.so文件。如果在编译的过程中出现问题,请自行google

2.4创建函数

在mysql中执行下面的命令

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 ‘lib_mysqludf_sys.so‘;CREATE FUNCTION sys_get RETURNS string SONAME ‘lib_mysqludf_sys.so‘;CREATE FUNCTION sys_set RETURNS int SONAME ‘lib_mysqludf_sys.so‘;CREATE FUNCTION sys_exec RETURNS int SONAME ‘lib_mysqludf_sys.so‘;CREATE FUNCTION sys_eval RETURNS string SONAME ‘lib_mysqludf_sys.so‘;
2.5测试
2.5.1验证step 1:

在mysql中执行命令

mysql> SELECT sys_exec (touch /var/lib/mysql/test.txt );+---------------------------------------------+| sys_exec (touch /var/lib/mysql/test.txt ) |+---------------------------------------------+| 32512 |+---------------------------------------------+1 row in set (0.00 sec)mysql> SELECT sys_eval(id);+----------------+| sys_eval(id) |+----------------+| NULL           |+----------------+1 row in set (0.40 sec)mysql> SELECT sys_eval(cp /home/cassiano/Desktop/index.html /home/cassiano/);+------------------------------------------------------------------+| sys_eval(cp /home/cassiano/Desktop/index.html /home/cassiano/) |+------------------------------------------------------------------+|                                                                  |+------------------------------------------------------------------+1 row in set (0.02 sec)

从上面的执行结果看出,所有执行都失败了,这是由于apparmor引起(具体原因未知),在shell命令行执行下面的命令

#sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/#sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysql
2.5.2验证step 2:
mysql> SELECT sys_eval(id);+-------------------------------------------------+| sys_eval(id)                                  |+-------------------------------------------------+| uid=116(mysql) gid=125(mysql) groups=125(mysql) |+-------------------------------------------------+1 row in set (0.09 sec)mysql> SELECT sys_eval(pwd);+-----------------+| sys_eval(pwd) |+-----------------+| /var/lib/mysql  |+-----------------+1 row in set (0.01 sec)BUT...下面的操作失败了...     -_-mysql> SELECT sys_eval(cp /home/cassiano/Desktop/index.html /home/cassiano/);+------------------------------------------------------------------+| sys_eval(cp /home/cassiano/Desktop/index.html /home/cassiano/) |+------------------------------------------------------------------+| NULL                                                             |+------------------------------------------------------------------+1 row in set (0.02 sec)mysql> SELECT sys_exec(cp /home/cassiano/Desktop/index.html /home/cassiano/);+------------------------------------------------------------------+| sys_exec(cp /home/cassiano/Desktop/index.html /home/cassiano/) |+------------------------------------------------------------------+|                                                              256 |+------------------------------------------------------------------+1 row in set (0.00 sec)

原因未知,解决办法,在shell中执行下面的命令:

#sudo chown mysql:mysql /home/cassiano/teste/ -R
2.5.3验证step3:

写一个小脚本测试一下:

#cd /tmp#vi test.sh    #/bin/sh    date > testlog.txt    exit 0#chmod +x ./test.sh

在mysql中测试:

#mysqlmysql> select sys_exec("/tmp/test.sh");+--------------------------+| sys_exec("/tmp/test.sh") |+--------------------------+|                        0 |+--------------------------+1 row in set (0.03 sec)mysql> select sys_exec("/tmp/test.sh");+--------------------------+| sys_exec("/tmp/test.sh") |+--------------------------+|                        0 |+--------------------------+1 row in set (0.02 sec)mysql> select sys_exec("/tmp/test.sh");+--------------------------+| sys_exec("/tmp/test.sh") |+--------------------------+|                        0 |+--------------------------+1 row in set (0.02 sec)mysql> select sys_exec("/tmp/test.sh");+--------------------------+| sys_exec("/tmp/test.sh") |+--------------------------+|                        0 |+--------------------------+1 row in set (0.02 sec)mysql> exit;

验证是否执行成功:

# cat test.txtTue May 15 17:48:05 CST 2014Tue May 15 17:48:05 CST 2014Tue May 15 17:48:06 CST 2014Tue May 15 17:48:06 CST 2014# pwd/tmp#测试完成。。。成功。。。

3.参考文章

MySQL使用udf调用系统程序
mysql通过函数执行本地命令和外部程序MySQL UDF执行外部命令
mysql UDF 遇到问题解答
apparmor

 

最后说明:技术问题,baidu搜索的结果太少,建议google...

MySql UDF 调用外部程序和系统命令