Ubuntu 安装 Mysql2redis 及错误日记
Summary: Author: 张亚飞 | Read Time: 5 minute read | Published: 2016-08-08
Filed under
—
Categories:
DevOps
—
Tags:
Linux,
Server,
Software,
DevOps,
mysql2redis 是 Mysql 的一个 UDF(user-defined function) 函数,它提供了 mysql 与 redis 之间的数据交互.当 mysql 的数据进行了更新,它就会调用相应 的 trigger 调用 mysql2redis 里面的函数对 redis 的数据进行更新.
安装前提
安装 mysql2redis 前,先在系统里安装 mysql, redis 并安装相关依赖:
jemalloc
apr 和 apr-util
hiredis
lib_mysqludf_json
安装过程–Ubuntu
安装 jemalloc
sudo apt install libjemalloc1 libjemalloc-dev -y
安装 apr
和 apr-util
apr
和apr-util
是两个依赖包,它们最新版本的下载地址请点击,下载 好的以后,它的安装过程如下(配制,编译,安装):
首先安装 apr
wget http://mirrors.hust.edu.cn/apache//apr/apr-1.6.5.tar.gz
sudo tar zxvf apr-1.6.5.tar.gz
cd apr-1.6.5
./configure
make
make test
sudo make install
完成编译后将会创建 /usr/local/apr
目录下
再次安装
apr-util
wget http://mirrors.hust.edu.cn/apache//apr/apr-util-1.6.1.tar.gz
tar zxvf apr-util-1.6.1.tar.gz
cd apr-util-1.6.1
./configure --with-apr=/usr/local/apr
make
sudo make install
完成编译后将会将 apr-util
添加至 /usr/local/apr/lib
目录下
注:编译完以上两个源码,需要将生成的 /usr/local/apr/lib/libapr-1.so.0
和 /usr/local/apr/lib/libaprutil-1.so.0
拷贝到 /usr/lib/x86_64-linux-gnu/
下
cp /usr/local/apr/lib/libapr-1.so.0 /usr/lib/x86_64-linux-gnu/libapr-1.so.0
cp /usr/local/apr/lib/libaprutil-1.so.0 /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0
安装
lib_mysqludf_json
lib_mysqludf_json
是一个支持json
数据格式的UDF函数,它提供给mysql
与redis
进行数据交互.它的下载安装过程如下:
sudo git clone https://github.com/mysqludf/lib_mysqludf_json.git
cp lib_mysqludf_json.so /usr/lib/mysql/plugin
安装
hiredis
hiredis
是redis
的一个调用接口,它提供了一些简单的redis
的操作,它 的安装和下载过程如下:
sudo git clone https://github.com/redis/hiredis.git
cd hiredis
make
sudo make install
完成编译后将会创建 /usr/local/include/hiredis/
和 /usr/local/lib/libhiredis.so
文件
将生成的 /usr/local/lib/libhiredis.so.0.13
文件拷备到 /lib/libhiredis.so.0.13
下
貌似不用将生成的 libhiredis.so
拷贝到 /usr/lib/mysql/plugins
下,
- 最后安装
mysql2redis
sudo git clone https://github.com/dawnbreaks/mysql2redis.git
cd mysql2redis
make
sudo make install
最后 make install
会将当前目录下生成的 lib_mysqludf_redis_v2.so
文件复制到 mysqlplugin_dir
下
注:另有一个类似库 https://github.com/aborn/mysql2redis.git
下载完 mysql2redis
后,记住修改以下几步:
修改
Makefile
将默认/usr/lib64/mysql/plugin
修改为当前系统的/usr/lib/mysql/plugin
(修改PLUGINDIR
参数 添加mysql
的include
如-I/usr/include/mysql
)并重新编译安装编译
make
的时候提示错误,貌似没有找到my_global.h
文件
/bin/sh: 1: /usr/bin/mysql_config: not found
In file included from lib_mysqludf_redis.c:5:0:
lib_mysqludf_redis.h:21:23: fatal error: my_global.h: No such file or directory
#include <my_global.h>
发现没有 Makefile
里指定的 /usr/include/mysql
文件,查看之前的服务器,发现存在并且里边包含有 my_global.h
文件,于是猜是这里出了问题,一番搜索之后,提示需要安装mysql开发包
sudo apt install libmysqlclient-dev
发现已创建此目录,重新编译没有提示上面的错误
- 注意,在
Ubuntu16.04
中,安装的libmysqlclient-dev(libmysqlclient20)
后与在Ubuntu14.04
中版本不一致libmysqlclient-dev(libmysqlclient18)
,执行mysql2redis > make
后出现如下两条错误:yafer@yafer-pc:/opt/data/mysql2redis$ make gcc -Werror -O2 -g `/usr/bin/mysql_config --include` -I/usr/local/include -I/usr/local/apr/include -I./ -I. -fPIC -shared -rdynamic lib_mysqludf_redis.c -lhiredis -L"/usr/lib/mysql/plugin" -L/usr/local/apr/lib -lapr-1 -laprutil-1 -o lib_mysqludf_redis_v2.so In file included from /usr/include/mysql/mysql/services.h:26:0, from /usr/include/mysql/mysql/plugin.h:59, from lib_mysqludf_redis.h:40, from lib_mysqludf_redis.c:5: /usr/include/mysql/mysql/service_srv_session_info.h:31:53: fatal error: violite.h: No such file or directory compilation terminated. Makefile:6: recipe for target 'compile' failed make: *** [compile] Error 1
yafer@yafer-pc:/opt/data/mysql2redis$ make gcc -Werror -O2 -g `/usr/bin/mysql_config --include` -I/usr/local/include -I/usr/local/apr/include -I./ -I. -fPIC -shared -rdynamic lib_mysqludf_redis.c -lhiredis -L"/usr/lib/mysql/plugin" -L/usr/local/apr/lib -lapr-1 -laprutil-1 -o lib_mysqludf_redis_v2.so In file included from /usr/include/mysql/mysql/services.h:43:0, from /usr/include/mysql/mysql/plugin.h:59, from lib_mysqludf_redis.h:40, from lib_mysqludf_redis.c:5: /usr/include/mysql/mysql/service_parser.h:19:25: fatal error: my_md5_size.h: No such file or directory compilation terminated. Makefile:6: recipe for target 'compile' failed make: *** [compile] Error 1
大概是指 /usr/include/mysql/mysql/services.h
中包含的 service_srv_session_info.h
和 service_parser.h
中的文件错误
修改 /usr/include/mysql/mysql/services.h
并注释掉以下两行:
//[/usr/include/mysql/mysql/services.h-Line:26]//#include <mysql/service_srv_session_info.h>
//[/usr/include/mysql/mysql/services.h-Line:43]//#include <mysql/service_parser.h>
重新 make
编译 mysql2redis
即可顺利通过
sudo apt install libmysqlclient-dev
sudo apt install libmysql++-dev
Tue May 30 21:54:38 coam@ms:/usr/local/mysql$ sudo find / -name services.h
/usr/include/mysql/mysql/services.h
/usr/local/mysql/include/mysql/services.h
注意:实际统一修改 /usr/local/mysql/include/mysql/services.h Mysql 源码编译的库文件…
- 错误 lib_mysqludf_redis.c:271:13: error: format not a string literaland no format arguments
将 lib_mysqludf_redis.c [Line:271]行的 fprintf(pFile, buf) 改为 fputs(buf, pFile),或注释掉 [Line:46] /debug_print(buf);/
MYSQL 的配制
- 对于 lib_mysqludf_json 在 mysql 中执行以下sql命令:
DROP FUNCTION IF EXISTS json_members;
DROP FUNCTION IF EXISTS json_array;
DROP FUNCTION IF EXISTS json_object;
DROP FUNCTION IF EXISTS json_values;
CREATE FUNCTION json_members RETURNS STRING SONAME 'lib_mysqludf_json.so';
CREATE FUNCTION json_array RETURNS STRING SONAME 'lib_mysqludf_json.so';
CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';
CREATE FUNCTION json_values RETURNS STRING SONAME 'lib_mysqludf_json.so';
- json_array json_object
mysql> CREATE FUNCTION json_array RETURNS STRING SONAME 'lib_mysqludf_json.so';
ERROR 1585 (HY000): This function 'json_array' has the same name as a native function
注:自Mysql5.7开始已有内建 json_array json_object 方法,虽然用法不一样,但是可以稍作调整替换这里的同名方法–所以 lib_mysqludf_json 该库可以不用了
- 对于 mysql2redis 在 mysql 中执行以下 sql 命令:
DROP FUNCTION IF EXISTS redis_servers_set_v2;
CREATE FUNCTION redis_servers_set_v2 RETURNS int SONAME "lib_mysqludf_redis_v2.so";
DROP FUNCTION IF EXISTS redis_command_v2;
CREATE FUNCTION redis_command_v2 RETURNS int SONAME "lib_mysqludf_redis_v2.so";
DROP FUNCTION IF EXISTS redis_command_v3;
CREATE FUNCTION redis_command_v3 RETURNS int SONAME "lib_mysqludf_redis_v2.so";
DROP FUNCTION IF EXISTS free_resources;
CREATE FUNCTION free_resources RETURNS int SONAME "lib_mysqludf_redis_v2.so";
- 查看当前创建的用户自定义方法
mysql> select name,dl from mysql .func;
- 测试:
select redis_servers_set_v2("127.0.0.1",6379); select redis_command_v2("hset","hkey","hfield",json_object("op","insert","value","valuettt"));
在安装过程中遇到的问题,请参照 mysql2redis.md
- 创建 redis_servers_set_v2 FUNCTION 出现如下错误 ‘lib_mysqludf_redis_v2.so’ (errno: 2 libapr-1.so.0: cannot open shared object file
mysql> CREATE FUNCTION redis_servers_set_v2 RETURNS int SONAME "lib_mysqludf_redis_v2.so";
ERROR 1126 (HY000): Can't open shared library 'lib_mysqludf_redis_v2.so' (errno: 2 libapr-1.so.0: cannot open shared object file: No such file or directory)
mysql> CREATE FUNCTION redis_servers_set_v2 RETURNS int SONAME "lib_mysqludf_redis_v2.so";
ERROR 1126 (HY000): Can't open shared library 'lib_mysqludf_redis_v2.so' (errno: 11 libaprutil-1.so.0: cannot open shared object file: No such file or directory)
查看 libapr-1.so.0 和 libaprutil-1.so.0 均在 /usr/local/apr/lib/ 下
查看已安装好的 Ali 服务器
Thu May 19 10:54:21 coam@coam:/usr/lib/x86_64-linux-gnu$ sudo find / -name libapr-1.so.0
/usr/local/apr/lib/libapr-1.so.0
/usr/lib/x86_64-linux-gnu/libapr-1.so.0
...
可以看到 libapr-1.so.0
和 libaprutil-1.so.0
都已复制到系统的 /usr/lib/x86_64-linux-gnu/
路径下,可能是当前服务器 Vultr 系统安装有差异,于是手动复制这两个文件,问题解决
cp /usr/local/apr/lib/libapr-1.so.0 /usr/lib/x86_64-linux-gnu/libapr-1.so.0
cp /usr/local/apr/lib/libaprutil-1.so.0 /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0
- 最后登陆 Mysql 命令行测试 redis udf
# 设定连接 Redis 数据库
select redis_servers_set_v2("127.0.0.1", 6379);
select redis_command_v2("HSET","AccountInfoList","C-1",json_object("C-1", "C-1")); // 测试连接
select redis_command_v2("hset","hkey","hfield",json_object(json_members("op","insert","value","valuettt"))); // 测试 json_object 方法
select free_resources();
- 一次阿里云服务器不能 CREATE FUNCTION redis_servers_set_v2 并报错
mysql> DROP FUNCTION IF EXISTS redis_servers_set_v2;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE FUNCTION redis_servers_set_v2 RETURNS int SONAME "lib_mysqludf_redis_v2.so";
ERROR 1125 (HY000): Unknown error 1125
之前是可以的,但是现在突然出现问题,折腾了一天重装 mysql 等都没有解决,也不能查看执行这两条 sql 的错误日志,后来通过重启 mysql 查看 /data/home/data/mysql/coam.err 发现如下两条几条错误
* [ERROR] Can't open shared library 'lib_mysqludf_redis_v2.so' (errno: 0 libapr-1.so.0: cannot open shared object file: No such file or directory)
2016-08-01T12:13:36.368731Z 0 [ERROR] Can't open shared library 'lib_mysqludf_redis_v2.so' (errno: 0 libapr-1.so.0: cannot open shared object file: No such file or directory)
2016-08-01T12:13:36.368954Z 0 [ERROR] Can't open shared library 'lib_mysqludf_redis_v2.so' (errno: 0 libapr-1.so.0: cannot open shared object file: No such file or directory)
与前面出现的错误一致,只是现在没有在 sql 下显示该错误,于是仿照之前的问题处理方式解决尝试该问题
Mon Aug 01 20:13:37 coam@coam:/etc/mysql$ cd /usr/local/apr/lib/
Mon Aug 01 20:14:59 coam@coam:/usr/local/apr/lib$ ls
apr.exp libapr-1.a libapr-1.so libapr-1.so.0.5.2 libaprutil-1.la libaprutil-1.so.0 pkgconfig
aprutil.exp libapr-1.la libapr-1.so.0 libaprutil-1.a libaprutil-1.so libaprutil-1.so.0.5.4
Mon Aug 01 20:15:00 coam@coam:/usr/local/apr/lib$ sudo find / -name libapr-1.so.0
/usr/local/apr/lib/libapr-1.so.0
/data/run/mysql2redis/apr-1.5.2/.libs/libapr-1.so.0
/opt/data/apr-1.5.2/.libs/libapr-1.so.0
可以看到 libapr-1.so.0 和 libaprutil-1.so.0 已不在系统的 /usr/lib/x86_64-linux-gnu/ 路径下,于是手动复制这两个文件,问题解决(可能是执行了什么 sudo apt autoremove 系统自动删除了这两个文件吧,以后要定期检查这个目录的两个so文件)
cp /usr/local/apr/lib/libapr-1.so.0 /usr/lib/x86_64-linux-gnu/libapr-1.so.0
cp /usr/local/apr/lib/libaprutil-1.so.0 /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0
- 编译项目时提示如下错误:
/usr/bin/ld: cannot find -lapr-1
/usr/bin/ld: cannot find -laprutil-1
- 按以下方式添加系统编译搜索路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib/
重启 Mysql 恢复,可重新执行
mysql> DROP FUNCTION IF EXISTS redis_servers_set_v2;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE FUNCTION redis_servers_set_v2 RETURNS int SONAME "lib_mysqludf_redis_v2.so";
Query OK, 0 rows affected (0.00 sec)
错误记录
- 错误 lib_mysqludf_json.so: wrong ELF class: ELFCLASS32) 产生原因是: lib_mysqludf_json.so 是32位的文件-解决方法:重新编译
cd /opt/data/lib_mysqludf_json
sudo gcc -Wall -m64 -I/usr/include/mysql -I. -shared lib_mysqludf_json.c -o ./lib_mysqludf_json.so -fPIC
注意:-I 为 mysql 的 include 目录
- 错误 libhiredis.so.0.10: cannot open shared object file 执行以下命令:
sudo cp /usr/local/lib/libhiredis.so.0.10 /lib
- Mysql SQL 创建 json_members 方法的时候,提示如下错误:
mysql> CREATE FUNCTION json_members RETURNS STRING SONAME 'lib_mysqludf_json.so';
ERROR 1126 (HY000): Can't open shared library 'lib_mysqludf_json.so' (errno: 2 /usr/local/mysql/usr/lib/mysql/plugin/lib_mysqludf_json.so: cannot open shared object file: No such file or directory)
检查发现 /usr/lib/mysql/plugin/lib_mysqludf_json.so 文件存在,可能是安装 Mysql 配置的 plugin-dir 有问题 /usr/local/mysql/
Sat May 14 18:02:00 coam@coam:/opt/data/mysql2redis$ sudo ps -ef | grep mysql
root 958 1 0 May13 ? 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/home/data/mysq --pid-file=/data/home/data/mysql/coam.pid
mysql 1204 958 0 May13 ? 00:00:19 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/home/data/mysql --plugin-dir=/usr/local/mysql//usr/lib/mysql/plugin --user=mysql --log-error=/var/log/mysql/error.log --pid-file=/data/home/data/mysql/coam.pid --socket=/var/run/mysqld/mysqld.sock --port=3306
coam 8559 24523 0 18:05 pts/0 00:00:00 mysql -u zhangyanxi -p
coam 12036 29119 0 18:12 pts/4 00:00:00 grep --color=auto mysql
可以看见 –plugin-dir=/usr/local/mysql//usr/lib/mysql/plugin 这里配置有问题
- 我是 Mysql 源码编译安装,并且在 cmake 中设定参数 *-DINSTALL_PLUGINDIR=/usr/lib/mysql/plugin * 也没有问题.修改 /etc/mysql/my.cnf 添加以下内容
* [mysqld]
plugin_dir=/usr/lib/mysql/plugin
重启 mysql 发现问题已修正
参考列表
- 怎样安装 mysql2redis
- 疑难杂症
- https://github.com/dawnbreaks/mysql2redis
- https://github.com/jackeylu/mysql2redis
- http://www.mysqludf.org/
- 通过Gearman实现MySQL到Redis的数据复制
- 使用MySQL触发器同步数据到Memcached
Comments