mysql-proxy需要先安装好lua,libevent.lua
到www.lua.org下载,libevent见这篇文章http://blog.sina.com.cn/s/blog_53fab15a01016grx.html。
mysql-proxy可以到官网下载二进制版。源码版make的时候总是出错:
Lua安装好后需要设定几个环境变量:
export
LUA_CFLAGS="-I/usr/local/lua/include"
export LUA_LIBS="-L/usr/local/lua/lib -llua -ldl"
export LDFLAGS="-L/usr/local/lib -lm"
export CFLAGS="-I/usr/local/lib"
mysql-proxy-0.8.4]# ./configure
--with-mysql=/usr/local/mysql
报错:
“
configure:16659: error: Package requirements (glib-2.0
>= 2.16.0) were not met:
No package 'glib-2.0' found
Consider adjusting the PKG_CONFIG_PATH environment variable
if you
installed software in a non-standard prefix.
”
解决办法:
安装glib2.0后仍不行,经查询分析后是pkgconfig的路径配置问题:
# find /usr/local/lib -name "*.pc"
/usr/local/lib/pkgconfig/glib-2.0.pc
/usr/local/lib/pkgconfig/gmodule-export-2.0.pc
/usr/local/lib/pkgconfig/gio-unix-2.0.pc
/usr/local/lib/pkgconfig/gio-2.0.pc
/usr/local/lib/pkgconfig/gobject-2.0.pc
/usr/local/lib/pkgconfig/gmodule-no-export-2.0.pc
/usr/local/lib/pkgconfig/gthread-2.0.pc
/usr/local/lib/pkgconfig/gmodule-2.0.pc
#export
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
然后再次编译就没有这个错误了
mysql-proxy-0.8.4]# ./configure
--with-mysql=/usr/local/mysql
解下来说没用libevent,然后安装git 下载libevent(2.1.)报错 “undefined reference
to
`SSL_set_tlsext_host_name'”。后面换2.0来装 http://cloud.github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz,configure&&make&&make
install无错完毕
接下来mysql-proxy-0.8.4]# ./configure
--with-mysql=/usr/local/mysql --with-lua
报lua-load-factory.c:122: error: too few arguments to function
‘lua_load’的错误,如下图
查看lua-load-factory.c:122的函数需要4个参数,如下:
mysql-proxy-0.8.4]# vi src/lua-load-factory.c
定位到122行:return lua_load(L, loadstring_factory_reader,
&factory, s); 4个参数
然后到lua的源码里查看这个lua_load的原型,注意这是lua5.2
可以看到在src/lauxlib.c里面lua_load是5个参数。
于是试一下lua5.1
看到,是4个参数
然后去搜索系统中所有lua_load的函数定义的文件,发现有两个:
vi /usr/include/lua.h 4个参数
vi /usr/local/include/lua.h 5个参数
于是把/usr/local/include/lua.h的删掉了,也rm -rf
/usr/local/bin/lua*
这个可能是装了2个版本的lua,把5.2的删掉后,系统中保留的是5.1了。验证一下:
[root@10-4-5-183 bin]# lua -v
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org,
PUC-Rio
再次编译:mysql-proxy-0.8.4]# ./configure
--with-mysql=/usr/local/mysql
又报错
解决办法:# yum erase lua-devel.x86_64 lua.x86_64 -y
手工安装 lua-5.1.5]# make linux install解决,configure没有错误。
接下来make,
报错:
/usr/local/lib/liblua.a: could not read symbols: Bad
value
有两种解决办法:
搞了半天,还是Lua版本问题:用以下方式纠正:
方法一. lua-5.1.5]# cp
/usr/local/lua/lib/liblua.a /usr/local/lib/
make就无错误了
最后make install
方法二. 问题的原因是lua5.1.5编译时需要多加一个编译参数: -fPIC (src/MakeFile的第11行
“CFLAGS= -O2 -Wall $(MYCFLAGS) -fPIC”)
编译lua
可以看到 gcc后面带了-fPIC .
最后lua-5.1.5]# make install 完成lua5.1.5的安装。
注:安装glib2.0的时候有一个报错:
GNU libiconv not in use but included
iconv.h is from libiconv
解决方法:
编译glib2.0的时候,这样: ./configure --with-libiconv=gnu
测试一:
二进制包安装:把mysql-proxy的二进制文件打开,改名放到/usr/local/mysql-proxy,添加/usr/local/mysql-proxy/bin到PATH就可以用了。使用
mysql-proxy --help验证一下。或者看下版本信息,如下:
使用以下命令打开mysql-proxy服务:
mysql-proxy --proxy-backend-addresses=192.168.1.117:3307
--proxy-read-only-backend-addresses=192.168.1.117:3306
--proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
以上命令也可以写入到一个init脚本里去,如下:
#!/bin/sh
export
LUA_CFLAGS="-I/usr/local/lua/include"
export LUA_LIBS="-L/usr/local/lua/lib -llua -ldl"
export LDFLAGS="-L/usr/local/lib -lm"
export CFLAGS="-I/usr/local/lib"
export
LUA_PATH=/usr/local/mysql-proxy/share/doc/mysql-proxy
mode=$1
if [ -z "$mode" ] ; then
mode="start"
fi
case $mode in
'start')
mysql-proxy
--proxy-backend-addresses=192.168.1.117:3307
--proxy-read-only-backend-addresses=192.168.1.117:3306
--proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
;;
'stop')
killall
mysql-proxy
;;
'restart')
if $0 stop ;
then
$0
start
else
echo
"retart failed!!!"
exit
1
fi
;;
esac
exit 0
从102上连接进去发现一些奇怪的现象,如下图:
1.30是proxy所在服务器。proxydb.ta表一会不在一会又在了,不太明白
现在又打开几个客户端连接proxy,但都被指向到 192.168.1.17:3307,没有一个到192.168.1.17:3306的,这是为什么
下面是另一个实验:
3306是read-only
3307是backend
3306的表里写入330601
3307的表里写入330701
从客户端连接proxy,3个客户端都是被导入3307,就是可读可写的后端,只读的没办法被分配到。
测试二:
测试一用mysql客户端登录进mysql服务器不太符合一般情况。更普遍的情况是,每一条语句直接发送给proxy.proxy会判断这条语句应该传递给哪个后台mysqld.
proxy安装在 192.168.10.1
# cat mysql-proxy.cnf
[mysql-proxy]
admin-username=root
admin-password=123456
admin-lua-script=/usr/local/mysql-proxy/lua/admin.lua
proxy-read-only-backend-addresses=192.168.10.2:3306
proxy-backend-addresses=192.168.10.3:3306
#proxy-address=localhost:4040
proxy-lua-script=/usr/local/mysql-proxy/lua/rw-splitting.lua
log-file=/usr/local/mysql-proxy/log/mysql-proxy.log
log-level=debug
daemon = 1
keepalive=1
启动mysql-proxy:
#/usr/local/mysql-proxy/bin/bin/mysql-proxy
--defaults-file=mysql-proxy.cnf
proxy-read-only-backend-addresses=192.168.10.2
上面有1,2,3,4
proxy-backend-addresses=192.168.10.3:3306
上面有5,6
那么这个命令的结果:
# mysql -uproxy_test -p test
-h10.4.5.183 -P4040 -e "select * from proxytest;insert into
proxytest values(6,'2343');select * from
proxytest;commit"
Enter password:
+------+------+
| a | b
|
+------+------+
| 1 | abc
|
| 2 | erw
|
| 3 | asdf
|
| 4 | eee
|
+------+------+
+------+------+
| a | b
|
+------+------+
| 1 | abc
|
| 2 | erw
|
| 3 | asdf
|
| 4 | eee
|
+------+------+
两个select 都是引到readonly上面去了,backend server上面变成了5,6,6
mysql> select * from proxytest;
+------+-------+
| a | b
|
+------+-------+
| 5 | hello
|
| 6 | 2343
|
| 6 | 2343
|
+------+-------+
可见mysql-proxy是单条语句为单位进行读写分离,读归readonly,
写归backend。backend和readonly这两个mysqld的数据同步使用复制来保证,如果复制没有延迟,这就是个完美的解决方案。但复制延迟是常态,所以这样子的读写分离风险很大。很可能写的数据还没到readonly,读不出来,影响下面的逻辑判断。