• 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/
    #ls
    Makefile                        lib_mysqludf_sys.html           
    install.sh                      lib_mysqludf_sys.so
    lib_mysqludf_sys.c              lib_mysqludf_sys.sql
    2.3编译源码:

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

    # cat Makefile
    LIBDIR=/usr/lib
    
    install:
            gcc -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so
    #修改后,根据自己的系统环境决定
    # cat Makefile
    LIBDIR=/usr/lib64/mysql/plugin
    
    install:
            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中测试:

    #mysql
    mysql> 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.txt
    Tue May 15 17:48:05 CST 2014
    Tue May 15 17:48:05 CST 2014
    Tue May 15 17:48:06 CST 2014
    Tue May 15 17:48:06 CST 2014
    # pwd
    /tmp
    
    #测试完成。。。成功。。。

    3.参考文章

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

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

  • 相关阅读:
    MySQL5.7修改字符集
    MySQL-day1数据库的安装与介绍
    简述Python中的break和continue的区别
    Python实现用户交互,显示省市县三级联动的选择
    Mac升级Node.js和npm到最新版本指令
    vue+Typescript初级入门
    js-md5加密
    create-react-app 工程,如何修改react端口号?
    chrome安装react-devtools开发工具插件
    mac下更新node版本
  • 原文地址:https://www.cnblogs.com/yunsicai/p/4080864.html
Copyright © 2020-2023  润新知