MySQL Proxy 实现数据库读写分离,当然现在基于Mysql Proxy 二次开发很多,360的atlas,我们公司也在用atlas atlas地址 https://github.com/Qihoo360/Atlas/wiki/Atlas%E7%9A%84%E5%AE%89%E8%A3%85
我这里做Mysql Proxy实现代理下载地址http://dev.mysql.com/downloads/mysql-proxy/ 这里有相对应的格式的包,根据自己需求下载
我这里用的是mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit.tar.gz 二进制格式的包
首先安装lua,lua是mysql proxy能实现读写分离的脚本
[root@proxy ~]# rpm -q lua lua-5.1.4-4.1.el6.x86_64
解压安装
tar xf mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit.tar.gz cd mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit mv mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit /usr/local/mysql-proxy useradd -r mysql-proxy
输出mysql-proxy环境变量
vim /etc/profile.d/mysql-proxy.sh export PATH=$PATH:/usr/local/mysql-proxy/bin . /etc/profile.d/mysql-proxy.sh
帮助
[root@proxy ~]# mysql-proxy --help-all Usage: mysql-proxy [OPTION...] - MySQL Proxy Help Options: -?, --help Show help options --help-all Show all help options --help-proxy Show options for the proxy-module proxy-module -P, --proxy-address=<host:port> listening address:port of the proxy-server (default: :4040) -r, --proxy-read-only-backend-addresses=<host:port> address:port of the remote slave-server (default: not set) -b, --proxy-backend-addresses=<host:port> address:port of the remote backend-servers (default: 127.0.0.1:3306) --proxy-skip-profiling disables profiling of queries (default: enabled) --proxy-fix-bug-25371 fix bug #25371 (mysqld > 5.1.12) for older libmysql versions -s, --proxy-lua-script=<file> filename of the lua script (default: not set) --no-proxy don't start the proxy-module (default: enabled) --proxy-pool-no-change-user don't use CHANGE_USER to reset the connection coming from the pool (default: enabled) --proxy-connect-timeout connect timeout in seconds (default: 2.0 seconds) --proxy-read-timeout read timeout in seconds (default: 8 hours) --proxy-write-timeout write timeout in seconds (default: 8 hours) Application Options: -V, --version Show version --defaults-file=<file> configuration file --verbose-shutdown Always log the exit code when shutting down --daemon Start in daemon-mode --user=<user> Run mysql-proxy as user --basedir=<absolute path> Base directory to prepend to relative paths in the config --pid-file=<file> PID file in case we are started as daemon --plugin-dir=<path> path to the plugins --plugins=<name> plugins to load --log-level=(error|warning|info|message|debug) log all messages of level ... or higher --log-file=<file> log all messages in a file --log-use-syslog log all messages to syslog --log-backtrace-on-crash try to invoke debugger on crash --keepalive try to restart the proxy if it crashed --max-open-files maximum number of open files (ulimit -n) --event-threads number of event-handling threads (default: 1) --lua-path=<...> set the LUA_PATH --lua-cpath=<...> set the LUA_CPATH
启动
[root@proxy ~]# mysql-proxy --daemon --log-level=debug --log-file=/var/log/mysql-proxy.log --plugins=proxy -b 192.168.1.99:3306 -r 192.168.1.107:3306 --proxy-lua-script="/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua" -r 为读服务器 -b为写服务器 --proxy-lua-script指定读写分离脚本 [root@proxy ~]# cat /var/log/mysql-proxy.log 查看日志 2014-09-22 19:00:41: (critical) plugin proxy 0.8.4 started 2014-09-22 19:00:41: (debug) max open file-descriptors = 1024 2014-09-22 19:00:41: (message) proxy listening on port :4040 可见mysql-proxy监听4040端口 2014-09-22 19:00:41: (message) added read/write backend: 192.168.1.99:3306 2014-09-22 19:00:41: (message) added read-only backend: 192.168.1.107:3306
[root@proxy ~]# netstat -antlp |grep :4040 tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 3628/mysql-proxy
测试mysql-proxy
创建一个管理接口
、复制如下内容建立admin.lua文件,将其保存至/usr/local/mysql-proxy/share/doc/mysql-proxy/目录中。
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
启动mysql-proxy
[root@proxy mysql-proxy]# mysql-proxy --daemon --log-level=debug --log-file=/var/log/mysql-proxy.log --plugins=proxy -b 192.168.1.99:3306 -r 192.168.1.107:3306 --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"
[root@proxy mysql-proxy]# netstat -antlp |grep mysql-proxy tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 6015/mysql-proxy tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 6015/mysql-proxy tcp 0 0 192.168.1.117:59721 192.168.1.99:3306 ESTABLISHED 6015/mysql-proxy
连接4041端口测试
[root@kcw ~]# mysql -uadmin -padmin -h192.168.1.114 --port=4041 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.99-agent-admin Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SELECT * FROM backends; +-------------+--------------------+---------+------+------+-------------------+ | backend_ndx | address | state | type | uuid | connected_clients | +-------------+--------------------+---------+------+------+-------------------+ | 1 | 192.168.1.99:3306 | up | rw | NULL | 0 | | 2 | 192.168.1.107:3306 | unknown | ro | NULL | 0 | +-------------+--------------------+---------+------+------+-------------------+ 2 rows in set (0.01 sec)
连接mysql-proxy服务器4040端口执行写操作和读操作会读写分离
mysql -uroot -predhat -h192.168.1.114 --port=4040
连上去以后执行create database tdb;就会在写服务器上
show databases;就会在读服务器上
执行以个查操作会在99 写操作会在107上