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...
