背景:文件上传至hdfs,上传成功后插将hdfs文件目录存至mysql数据库,当文件目录成功插入mysql后,触发系统执行shell脚本,将hdfs文件建立solr索引
一、lib_mysqludf_sys相关配置
1、安装mysql (见mysql安装文档)
2、下载lib_mysqludf_sys-master.zip并解压 unzip lib_mysqludf_sys-master.zip
对应github地址: https://github.com/mysqludf/lib_mysqludf_sys
3、查看mysql plugin位置:登录mysql客户端 -->执行-->show variables like 'plugin_dir',mysql会默认加载plugin下.so里面的函数
4、进入Makefile,修改脚本:
修改前:
修改后:
5、安装gcc,yum install gcc (若存在则忽略)
后执行脚本:sh install.sh,执行完后再对应上述mysql/plugin目录下会多出如下文件:
注:其中第4、5步骤也可也按下方式操作:
直接在解压后的目录里面执行语句编译lib_mysqludf_sys.so:
gcc -DMYSQL_DYNAMIC_PLUGIN -fPIC -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o lib_mysqludf_sys.so
然后将编译后的lib_mysqludf_sys.so文件复制到plugin_dir目录下即可
注:第五步执行脚本可能报错如图:
解决方法:
则此处需此处应安装:rpm -ivh ./mysql-community-devel-5.7.19-1.el7.x86_64.rpm ,然后在执行 sh install.sh成功 (此处大坑花半天才跳出来)
参考:https://blog.csdn.net/juan131006/article/details/52703184
6、登录mysql客户端mysql -uroot -p,找到解压好的包下的文件lib_mysqludf_sys.sql,执行:source /home/mysqludf/lib_mysqludf_sys-master/lib_mysqludf_sys.sql 执行结果如下图:
(此处也可直接将lib_mysqludf_sys.sql中的创建语句复制出来在mysq 客户端执行)
7、测试:mysql客户端测试执行shell脚本:select sys_eval("ifconfig") -->终端会输出相应ip信息
到此为止,mysql函数导入成功(此处测试千万别省事直接复制网上的,网上好多是windows系统,搞得我测试时候没结果,以为自己搞错了,花浪费一天时间来排查,已哭晕)
注:此处会遇执行看不到结果的情况 (纠结并找原因花一天多时间,尴尬了),跟 Linux系统安全应用程序有关
分系统处理:(我的是centOS7)
1)、centOS7:终端输入getenforce查看状态
如果不是Disabled,则需要修改配置文件:/etc/selinux/config,修改为如图:
然后reboot重启生效
2)、ubuntu:
执行:
sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
然后重启mysql服务:systenctl mysql restart
二、创建触发器执行系统命令
1、通过ssh远程连接(带密码)到另一台服务器执行脚本:
#创建触发器,表中插入数据路径时,触发shell脚本执行并创建索引,221.6远程链接221.3执行
DROP TRIGGER IF EXISTS executor_shell
CREATE TRIGGER executor_shell
AFTER INSERT ON tb_dept
FOR EACH ROW
BEGIN
IF LENGTH(NEW.HADOOP_PATH)<=35 THEN
SET @a=sys_exec(concat(concat(concat(concat(concat("sshpass -p 'password' ssh root@ip",' '),"sh /home/mysql_test/jschexecutor.sh"),' '),IF(right(NEW.HADOOP_PATH,1)='/',NEW.HADDOP_PATH,concat(NEW.HADOOP_PATH,'/'))),NEW.HADOOP_NAME));
end if;
END;
此种方式需先安装sshpass:
wget http://sourceforge.net/projects/sshpass/files/sshpass/1.05/sshpass-1.05.tar.gz
tar xvzf sshpass-1.05.tar.gz
./configure
make
sudo make install
连接方式:sshpass -p 'password' ssh user@IP
参考地址:https://blog.csdn.net/weixin_41088891/article/details/93167034
2、直接在mysql服务器上执行脚本:
#创建触发器,表中插入数据路径时,触发shell脚本执行并创建索引,直接221.3执行
DROP TRIGGER IF EXISTS executor_shell
CREATE TRIGGER executor_shell
AFTER INSERT ON bd_batch_file
FOR EACH ROW
BEGIN
IF LENGTH(NEW.HADOOP_PATH)<=35 THEN
SET @a=sys_exec(concat(concat(concat("sh /home/mysql_test/jschexecutor.sh",' '),IF(right(NEW.HADOOP_PATH,1)='/',NEW.HADOOP_PATH,concat(NEW.HADOOP_PATH,'/'))),NEW.HADOOP_NAME));
end if;
END;
再此特别提醒:
在mysqludf执行脚本时,执行的脚本相关的所有目录都应该修改用户和组与mysql的保持一致
例如:
1、mysql为mysql用户,则对相关文件目录授权和修改所属于用户组:
修改所属用户组:chown -R mysql:mysql /dir
修改权限为可执行:最高权限: chmod 777 /dir 或 可执行权限:chmod u+x /dir
2、若为root用户,则对应修改为:
修改所属用户组:chown -R root:root /dir
修改权限为可执行:最高权限: chmod 777 /dir 或 可执行权限:chmod u+x /dir
若不清楚mysql归属那个用户组,最简单的方式,打开mysql client:执行select sys_eval("touch /home/mysql_test/test.sh")在对应修改权限后的目录里面随便创建一个文件,查看文件所属的用户和组,如下图:
用户组为mysql:mysql,所以mysql归属mysql用户组
若执行的系统脚本里面调用了其他路径的配置文件或将其他路径的文件或配置文件当参数传进去,则涉及的相关所有文件都得修改按上述步骤修改权限 (此处大坑花一天时间才跳出来)
eg:我在shell脚本里面将hdfs上的一个文件路径作为参数传进去,则需修改hdfs上此文件的用户组为mysql:mysql
hdfs dfs -chown -R mysql:mysql /user/systest/input
否则没有操作权限脚本不会执行成功