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