mysql-proxy代理:
1.安装lua.
1.1安装依赖包:
yum -y install gcc make ncurses-devel readline-devel
1.2下载软件并安装:
wget http://www.lua.org/ftp/lua-5.2.3.tar.gz
tar -zxvf lua-5.2.3.tar.gz
cd lua-5.2.3
make linux
make install
1.3常见的异常及解决办法:
[root@idc131 lua]# make linux
cd src && make linux
make[1]: Entering directory `/usr/local/lua-5.2.3/src'
make all SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline "
make[2]: Entering directory `/usr/local/lua-5.2.3/src'
gcc -o lua lua.o liblua.a -lm -Wl,-E -ldl -lreadline
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libreadline.so: undefined reference to `PC'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libreadline.so: undefined reference to `tgetflag'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libreadline.so: undefined reference to `tgetent'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libreadline.so: undefined reference to `UP'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libreadline.so: undefined reference to `tputs'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libreadline.so: undefined reference to `tgoto'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libreadline.so: undefined reference to `tgetnum'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libreadline.so: undefined reference to `BC'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libreadline.so: undefined reference to `tgetstr'
collect2: ld 返回 1
make[2]: *** [lua] 错误 1
make[2]: Leaving directory `/usr/local/lua-5.2.3/src'
make[1]: *** [linux] 错误 2
make[1]: Leaving directory `/usr/local/lua-5.2.3/src'
make: *** [linux] 错误 2
原因:
由于lua编译依赖readline库,而其依赖ncurses库,但没有指定,所以出现“未定义的符合引用”错误。
需要修改${LUA_DIR}/src/Makefile中linux编译target,在SYSLIBS变量中追加‘-lncurses’选项即可。
解决办法:
将src/Makefile中的106行由:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
修改为:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -lncurses"
2.安装mysql-proxy
1.到www.mysql.com上下载mysql-proxy.
2.解压并安装:
cd /usr/local
tar -zxvf /tmp/mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit.tar.gz
ln -s mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit mysql-proxy
echo "export $PATH=$PATH:/usr/local/mysql-proxy/bin" >/etc/profile.d/mysql-proxy.sh
chmod a+x /etc/profile.d/mysql-proxy.sh
source /etc/profile.d/mysql-proxy.sh
chown -R /usr/local/mysql-proxy /usr/local/mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit
3.创建一个数据库用户:
mysql> grant select,insert,update,delete,drop on mydb.* to mytest@mymaster identified by "mytest";
Query OK, 0 rows affected (0.15 sec)
mysql> grant select,insert,update,delete,drop on mydb.* to mytest@myslave identified by "mytest";
Query OK, 0 rows affected (0.15 sec)
4.启用读写分离的debug功能
将/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua文件中
if not proxy.global.config.rwsplit then
proxy.global.config.rwsplit = {
min_idle_connections = 4,
max_idle_connections = 8,
is_debug = false
}
end
修改为:
if not proxy.global.config.rwsplit then
proxy.global.config.rwsplit = {
min_idle_connections = 4,
max_idle_connections = 8,
is_debug = true
}
end
4.启动mysql-proxy进程:
mysql-proxy --proxy-backend-addresses=mymaster:3306 \
--proxy-read-only-backend-addresses=mysalve:3306 \
--log-file=/var/log/mysql-proxy.log \
--log-level=debug \
--plugins=proxy \
--proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua \
--plugins=admin \
--admin-username=admin \
--admin-password=admin \
--admin-lua-script='/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua' \
--daemon
查看日志:
[root@idc131 plugins]# tail -100f /var/log/mysql-proxy.log
2014-08-16 17:42:12: (critical) plugin proxy 0.8.4 started
2014-08-16 17:42:12: (debug) max open file-descriptors = 65536
2014-08-16 17:42:12: (message) proxy listening on port :4040
2014-08-16 17:42:12: (message) added read/write backend: mymaster:3306
2014-08-16 17:42:12: (message) added read-only backend: mysalve:3306
检查监听的端口:
[root@idc131 ~]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 27028/mysql-proxy
tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 27028/mysql-proxy
在slave进行连接测试:
mysql -umytest -hmymaster -P4040 -pmytest -e "select count(*) from mydb.mytab6;"
[connect_server] mysalve:19445
[1].connected_clients = 0
[1].pool.cur_idle = 5
[1].pool.max_idle = 8
[1].pool.min_idle = 4
[1].type = 1
[1].state = 1
[2].connected_clients = 0
[2].pool.cur_idle = 5
[2].pool.max_idle = 8
[2].pool.min_idle = 4
[2].type = 2
[2].state = 1
[1] taking master as default
using pooled connection from: 1
[read_query] mysalve:19445
current backend = 0
client default db =
client username = mytest
query = select @@version_comment limit 1
sending to backend : mysalve:3306
is_slave : true
server default db:
server username : mytest
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] mysalve:19445
current backend = 0
client default db =
client username = mytest
query = select count(*) from mydb.mytab6
sending to backend : mysalve:3306
is_slave : true
server default db:
server username : mytest
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] mysalve:19445
current backend = 0
client default db =
client username = mytest
(QUIT) current backend = 0
[disconnect_client] mysalve:19445
执行创建表操作:
mysql -umytest -hmymaster -P4040 -pmytest -e "create table mydb.mytab7 select * from mydb.mytab6;"
[connect_server] mysalve:19456
[1].connected_clients = 0
[1].pool.cur_idle = 5
[1].pool.max_idle = 8
[1].pool.min_idle = 4
[1].type = 1
[1].state = 1
[2].connected_clients = 0
[2].pool.cur_idle = 5
[2].pool.max_idle = 8
[2].pool.min_idle = 4
[2].type = 2
[2].state = 1
[1] taking master as default
using pooled connection from: 1
[read_query] mysalve:19456
current backend = 0
client default db =
client username = mytest
query = select @@version_comment limit 1
sending to backend : mysalve:3306
is_slave : true
server default db:
server username : mytest
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] mysalve:19456
current backend = 0
client default db =
client username = mytest
query = create table mydb.mytab7 select * from mydb.mytab6
sending to backend : mymaster:3306
is_slave : false
server default db:
server username : mytest
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] mysalve:19456
current backend = 0
client default db =
client username = mytest
(QUIT) current backend = 0
[disconnect_client] mysalve:19456
执行插入操作:
[connect_server] mysalve:19480
[1].connected_clients = 0
[1].pool.cur_idle = 5
[1].pool.max_idle = 8
[1].pool.min_idle = 4
[1].type = 1
[1].state = 1
[2].connected_clients = 0
[2].pool.cur_idle = 5
[2].pool.max_idle = 8
[2].pool.min_idle = 4
[2].type = 2
[2].state = 1
[1] taking master as default
using pooled connection from: 1
[read_query] mysalve:19480
current backend = 0
client default db =
client username = mytest
query = select @@version_comment limit 1
sending to backend : mysalve:3306
is_slave : true
server default db:
server username : mytest
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] mysalve:19480
current backend = 0
client default db =
client username = mytest
query = insert into mydb.mytab7 select * from mydb.mytab6
sending to backend : mymaster:3306
is_slave : false
server default db:
server username : mytest
in_trans : false
in_calc_found : false
COM_QUERY : true
[read_query] mysalve:19480
current backend = 0
client default db =
client username = mytest
(QUIT) current backend = 0
[disconnect_client] mysalve:19480
5.建立mysql-proxf的配置文件:
[root@idc131 bin]# cat /etc/mysql-proxy.cnf
[mysql-proxy]
user=mysql
plugins=admin
admin-address=localhost:4041
admin-username=admin
admin-password=admin
admin-lua-script='/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua'
plugins=proxy
proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
proxy-backend-addresses=mymaster:3306
proxy-read-only-backend-addresses=mysalve:3306
log-level=debug
log-file=/var/log/mysql-proxy.log
daemon=true
keepalive=true
pid-file=/var/log/mysql-proxy.pid
使用mysql-proxy --defaults-file=/etc/mysql-proxy.cnf启动.
使用如下内容创建/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua文件:
function set_error(errmsg)
proxy.response = {
type = proxy.MYSQLD_PACKET_ERR,
errmsg = errmsg or "error"
}
end
function read_query(packet)
if packet:byte() ~= proxy.COM_QUERY then
set_error("[admin] we only handle text-based queries (COM_QUERY)")
return proxy.PROXY_SEND_RESULT
end
local query = packet:sub(2)
local rows = { }
local fields = { }
if query:lower() == "select * from backends" then
fields = {
{ name = "backend_ndx",
type = proxy.MYSQL_TYPE_LONG },
{ name = "address",
type = proxy.MYSQL_TYPE_STRING },
{ name = "state",
type = proxy.MYSQL_TYPE_STRING },
{ name = "type",
type = proxy.MYSQL_TYPE_STRING },
{ name = "uuid",
type = proxy.MYSQL_TYPE_STRING },
{ name = "connected_clients",
type = proxy.MYSQL_TYPE_LONG },
}
for i = 1, #proxy.global.backends do
local states = {
"unknown",
"up",
"down"
}
local types = {
"unknown",
"rw",
"ro"
}
local b = proxy.global.backends[i]
rows[#rows + 1] = {
i,
b.dst.name, -- configured backend address
states[b.state + 1], -- the C-id is pushed down starting at 0
types[b.type + 1], -- the C-id is pushed down starting at 0
b.uuid, -- the MySQL Server's UUID if it is managed
b.connected_clients -- currently connected clients
}
end
elseif query:lower() == "select * from help" then
fields = {
{ name = "command",
type = proxy.MYSQL_TYPE_STRING },
{ name = "description",
type = proxy.MYSQL_TYPE_STRING },
}
rows[#rows + 1] = { "SELECT * FROM help", "shows this help" }
rows[#rows + 1] = { "SELECT * FROM backends", "lists the backends and their state" }
else
set_error("use 'SELECT * FROM help' to see the supported commands")
return proxy.PROXY_SEND_RESULT
end
proxy.response = {
type = proxy.MYSQLD_PACKET_OK,
resultset = {
fields = fields,
rows = rows
}
}
return proxy.PROXY_SEND_RESULT
end