Chinaunix首页 | 论坛 | 博客
  • 博客访问: 631736
  • 博文数量: 244
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-27 09:53
个人简介

记录学习,记录成长

文章分类

全部博文(244)

我的朋友

分类: LINUX

2016-01-01 17:22:06

配置环境:
主服务器:192.168.85.144 node1.a.com
从服务器:192.168.85.145 node2.a.com
proxy服务器:192.168.85.128 proxy.a.com
已经搭建好了mysql复制环境(一主一从);

一.基本配置

1.下载mysql-proxy包
这里使用的是二进制包;
也可以直接安yum install,只需要配置好EPEL源即可;
下载地址:

或者


2.创建使用mysql-proxy的用户
[root@proxy ~]# useradd -r proxy
[root@proxy ~]# id proxy
uid=496(proxy) gid=493(proxy) groups=493(proxy)

3.解压并创建链接
[root@proxy ~]# tar xf mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit.tar.gz -C /usr/local/

[root@proxy ~]# cd /usr/local/

[root@proxy local]# ln -sv mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit mysql-proxy
`mysql-proxy' -> `mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit'

4.关于mysql-proxy用法
[root@proxy mysql-proxy]# /usr/local/mysql-proxy/bin/mysql-proxy --help-all

proxy-module代理模块:
  -P, --proxy-address=     #监听的mysql-proxy服务器的IP和端口,默认端口为4040;
  
  -r, --proxy-read-only-backend-addresses=  #后端只读服务器(从)的IP和地址;
  
  -b, --proxy-backend-addresses=       #后端可读可写服务器(主)的IP和地址,默认为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=                   #lua脚本文件路径(default: not set)
  
  --no-proxy                                      #不起用proxy模块(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                         #连接超时时长(default: 2.0 seconds)
  
  --proxy-read-timeout                            #读超时时长(default: 8 hours)
  
  --proxy-write-timeout                           #写超时时长(default: 8 hours)


Application Options:
  --defaults-file=                             #默认读取的配置文件;可以为/etc/mysql-proxy.conf或者/etc/my.cnf中定义[mysql-proxy]段,当使用配置文件时,可以写入proxy module中的选项,如proxy-address=192.168.85.128:4040等;
  
  --verbose-shutdown                                      Always log the exit code when shutting down
  
  --daemon                                        #以守护进程模式运行mysql-proxy;
  
  --user=                                   #mysql-proxy的使用者;
  
  --basedir=                       #指定使用的mysql-proxy配置文件的路径;
  
  --pid-file=                               #PID file in case we are started as daemon
  
  --plugin-dir=                             #加载的插件的目录路径(加载目录下的所有插件);
  
  --plugins=           #加载的指定插件名称;插件位于/usr/local/mysql-proxy/lib/mysql-proxy/plugins/下;
  
  --log-level=(error|warning|info|message|debug)  #日志级别;
  
  --log-file=                               #记录日志到文件中;
  
  --log-use-syslog                                #记录日志到系统日志文件中;
  
  --log-backtrace-on-crash                        #try to invoke debugger on crash
  
  --keepalive                                     #如果mysql-proxy服务器宕机,会尝试重启;
  
  --max-open-files                                #最大打开文件数(ulimit -n)
  
  --event-threads                                 #事件句柄打开的线程数(default: 1)
  
  --lua-path=<...>                                #set the LUA_PATH
  
  --lua-cpath=<...>                               #set the LUA_CPATH
  
5.启动mysql-proxy
[root@proxy mysql-proxy]# mysql-proxy --daemon --plugins=proxy --log-level=debug --log-file=/var/log/mysql-proxy.log --proxy-read-only-backend-addresses=192.168.85.145:3306 --proxy-backend-addresses=192.168.85.144:3306


查看日志:
[root@proxy mysql-proxy]# tail /var/log/mysql-proxy.log 
2015-12-31 10:11:27: (critical) plugin proxy 0.8.5 started
2015-12-31 10:11:27: (debug) max open file-descriptors = 1024
2015-12-31 10:11:27: (message) proxy listening on port :4040
2015-12-31 10:11:27: (message) added read/write backend: 192.168.85.144:3306
2015-12-31 10:11:27: (message) added read-only backend: 192.168.85.145:3306

6.主服务器上赋予权限给登录proxy服务器的账户
mysql> grant all on *.* to 'root'@'%' identified by 'redhat';

然后找一个mysql客户端登陆proxy服务器:
[root@node2 ~]# mysql -uroot -p -h 192.168.85.128 -P 4040
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.6.27-log MySQL Community Server (GPL)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
mysql> 

测试:
如果执行一个操作,proxy路由到了从服务器,那么只有从服务器上有;如果路由到了主服务器,那么主从服务器都会有;
proxy上创建一个数据库:
mysql> create database testdb;

主从服务器上显示:
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| performance_schema |
| test               |
| testdb             |
+--------------------+
当然,这只是一个偶然的情况,因为mysql-proxy本身并不能实现读写分离,而是要依靠lua脚本来完成,所以,还需配置脚本才能实现真正的读写分离;

7.使用脚本实现读写分离
先[root@proxy mysql-proxy]# killall mysql-proxy

lua脚本在/usr/local/mysql-proxy/share/doc/mysql-proxy/下,其中rw-splitting.lua脚本是用来实现读写分离的;

[root@proxy ~]# mysql-proxy --daemon --plugins=proxy --log-level=debug --log-file=/var/log/mysql-proxy.log --proxy-read-only-backend-addresses=192.168.85.145:3306 --proxy-backend-addresses=192.168.85.144:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua

8.使用脚本提供管理接口
8.1编辑admin.lua文件(内容见附录);

8.2重新启动mysql-proxy:
[root@proxy mysql-proxy]# mysql-proxy --daemon --plugins=proxy --log-level=debug --log-file=/var/log/mysql-proxy.log --proxy-read-only-backend-addresses=192.168.85.145:3306 --proxy-backend-addresses=192.168.85.144:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua --plugins=admin --admin-username=admini --admin-password=admini --admin-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua 

8.3查看日志
[root@proxy mysql-proxy]# tail /var/log/mysql-proxy.log 
2015-12-31 10:50:41: (critical) plugin proxy 0.8.5 started
2015-12-31 10:50:41: (critical) plugin admin 0.8.5 started
2015-12-31 10:50:41: (debug) max open file-descriptors = 1024
2015-12-31 10:50:41: (message) proxy listening on port :4040
2015-12-31 10:50:41: (message) added read/write backend: 192.168.85.144:3306
2015-12-31 10:50:41: (message) added read-only backend: 192.168.85.145:3306
2015-12-31 10:50:41: (message) admin-server listening on port :4041 #管理接口为4041

8.4通过管理接口连接
[root@node2 ~]# mysql -u admini -h192.168.85.128 -p -P 4041
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.99-agent-admin
mysql> 

8.5通过管理接口连接上后的mysql只有如下命令才有效
mysql> select * from backends;
+-------------+---------------------+---------+------+------+-------------------+
| backend_ndx | address             | state   | type | uuid | connected_clients |
+-------------+---------------------+---------+------+------+-------------------+
|           1 | 192.168.85.144:3306 | unknown | rw   | NULL |                 0 |
|           2 | 192.168.85.145:3306 | unknown | ro   | NULL |                 0 |
+-------------+---------------------+---------+------+------+-------------------+

8.6测试
8.6.1 写操作测试:
[root@node1 ~]# mysql -u root -p -h192.168.85.128 -P 4040 -e 'create database hellodb;'
Enter password: 

mysql> select * from backends;
+-------------+---------------------+---------+------+------+-------------------+
| backend_ndx | address             | state   | type | uuid | connected_clients |
+-------------+---------------------+---------+------+------+-------------------+
|           1 | 192.168.85.144:3306 | up      | rw   | NULL |                 0 |
|           2 | 192.168.85.145:3306 | unknown | ro   | NULL |                 0 |
+-------------+---------------------+---------+------+------+-------------------+
这说明了,刚刚的写操作一定是在主服务器上执行的;

8.6.2 读操作测试:
[root@node1 ~]# mysql -u root -p -h192.168.85.128 -P 4040 -e 'show tables from test;'
Enter password: 

mysql> select * from backends;
+-------------+---------------------+-------+------+------+-------------------+
| backend_ndx | address             | state | type | uuid | connected_clients |
+-------------+---------------------+-------+------+------+-------------------+
|           1 | 192.168.85.144:3306 | up    | rw   | NULL |                 0 |
|           2 | 192.168.85.145:3306 | up    | ro   | NULL |                 0 |
+-------------+---------------------+-------+------+------+-------------------+
如果执行命令后从状态仍未unknown这不代表出错了,多尝试几次,毕竟,主是可读可写的,可能读操作被路由到了主而不是从;

二.简化配置
1.每一次配置proxy都要写那么一大段毕竟是很辛苦的,而且易出错,所以可以采用配置文件的方式来简化配置
[root@proxy ~]# cat /etc/mysql-proxy.cnf 
[mysql-proxy]
plugins=proxy 
log-level=debug 
log-file=/var/log/mysql-proxy.log 
proxy-read-only-backend-addresses=192.168.85.145:3306 
proxy-backend-addresses=192.168.85.144:3306 
proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua 
plugins=admin 
admin-username=admini 
admin-password=admini 
admin-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua 
proxy-address=192.168.85.128:4040

[root@proxy ~]# chmod 660 /etc/mysql-proxy.cnf   #权限要设置为660

先关闭proxy:
[root@proxy ~]# killall mysql-proxy

查看日志:
[root@proxy ~]# mysql-proxy --daemon --defaults-file=/etc/mysql-proxy.cnf 

[root@proxy ~]# tail /var/log/mysql-proxy.log 
2015-12-31 11:15:47: (message) Initiating shutdown, requested from signal handler
2015-12-31 11:15:48: (message) shutting down normally, exit code is: 0
2015-12-31 11:15:58: (critical) plugin admin 0.8.5 started
2015-12-31 11:15:58: (debug) max open file-descriptors = 1024
2015-12-31 11:15:58: (message) admin-server listening on port :4041

好吧,这里有些问题,4040端口没打开;而且尝试了多次,都有问题!先记录一下,如果解决了再来更新;
问题地址:http://blog.chinaunix.net/uid-30212356-id-5589069.html

2.为mysql-proxy服务提供启动脚本
[root@proxy ~]# vim /etc/rc.d/init.d/mysql-proxy
[root@proxy ~]# chmod +x /etc/rc.d/init.d/mysql-proxy
[root@proxy ~]# chkconfig --add mysql-proxy

为服务脚本提供配置文件:
[root@proxy ~]# cat /etc/sysconfig/mysql-proxy
ADMIN_USER="admini"
ADMIN_PASSWORD="admini"
ADMIN_ADDRESS=""
ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"
PROXY_ADDRESS="192.168.85.128:4040"
PROXY_USER="proxy"
PROXY_OPTIONS="--daemon --log-level=debug --log-file=/var/log/mysql-proxy.log --plugins=proxy --proxy-read-only-backend-addresses=192.168.85.145:3306 --proxy-backend-addresses=192.168.85.144:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua --plugins=admin"

[root@proxy  ]# service mysql-proxy start
Starting /usr/local/mysql-proxy/bin/mysql-proxy: [  OK  ]

查看日志:
[root@proxy ~]# tail /var/log/mysql-proxy.log 
2015-12-31 11:49:54: (critical) plugin proxy 0.8.5 started
2015-12-31 11:49:54: (critical) plugin admin 0.8.5 started
2015-12-31 11:49:54: (debug) max open file-descriptors = 1024
2015-12-31 11:49:54: (message) proxy listening on port 192.168.85.128:4040
2015-12-31 11:49:54: (message) added read/write backend: 192.168.85.144:3306
2015-12-31 11:49:54: (message) added read-only backend: 192.168.85.145:3306
2015-12-31 11:49:54: (message) admin-server listening on port :4041
2015-12-31 11:49:54: (debug) now running as user: proxy (496/493)

测试:
1.初始状态
mysql> select * from backends;
+-------------+---------------------+---------+------+------+-------------------+
| backend_ndx | address             | state   | type | uuid | connected_clients |
+-------------+---------------------+---------+------+------+-------------------+
|           1 | 192.168.85.144:3306 | unknown | rw   | NULL |                 0 |
|           2 | 192.168.85.145:3306 | unknown | ro   | NULL |                 0 |
+-------------+---------------------+---------+------+------+-------------------+


执行写操作:
[root@node1 ~]# mysql -u root -p -h192.168.85.128 -P 4040 -e 'create database hellodb2;'
Enter password: 

mysql> select * from backends;
+-------------+---------------------+---------+------+------+-------------------+
| backend_ndx | address             | state   | type | uuid | connected_clients |
+-------------+---------------------+---------+------+------+-------------------+
|           1 | 192.168.85.144:3306 | up      | rw   | NULL |                 0 |
|           2 | 192.168.85.145:3306 | unknown | ro   | NULL |                 0 |
+-------------+---------------------+---------+------+------+-------------------+

执行读操作:
mysql> select * from backends;
+-------------+---------------------+-------+------+------+-------------------+
| backend_ndx | address             | state | type | uuid | connected_clients |
+-------------+---------------------+-------+------+------+-------------------+
|           1 | 192.168.85.144:3306 | up    | rw   | NULL |                 0 |
|           2 | 192.168.85.145:3306 | up    | ro   | NULL |                 0 |
+-------------+---------------------+-------+------+------+-------------------+

三.附录
1.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


2.服务启动脚本内容

#!/bin/bash
#
# mysql-proxy This script starts and stops the mysql-proxy daemon
#
# chkconfig: - 78 30
# processname: mysql-proxy
# description: mysql-proxy is a proxy daemon for mysql


# Source function library.
. /etc/rc.d/init.d/functions


prog="/usr/local/mysql-proxy/bin/mysql-proxy"


# Source networking configuration.
if [ -f /etc/sysconfig/network ]; then
    . /etc/sysconfig/network
fi


# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0


# Set default mysql-proxy configuration.
ADMIN_USER="admini"
ADMIN_PASSWD="admini"
ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"
PROXY_OPTIONS="--daemon"
PROXY_PID=/var/run/mysql-proxy.pid
PROXY_USER="proxy"


# Source mysql-proxy configuration.
if [ -f /etc/sysconfig/mysql-proxy ]; then
    . /etc/sysconfig/mysql-proxy
fi


RETVAL=0


start() {
    echo -n $"Starting $prog: "
    daemon $prog $PROXY_OPTIONS --pid-file=$PROXY_PID --proxy-address="$PROXY_ADDRESS" --user=$PROXY_USER --admin-username="$ADMIN_USER" --admin-lua-script="$ADMIN_LUA_SCRIPT" --admin-password="$ADMIN_PASSWORD"
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        touch /var/lock/subsys/mysql-proxy
    fi
}


stop() {
    echo -n $"Stopping $prog: "
    killproc -p $PROXY_PID -d 3 $prog
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        rm -f /var/lock/subsys/mysql-proxy
        rm -f $PROXY_PID
    fi
}
# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    condrestart|try-restart)
        if status -p $PROXY_PIDFILE $prog >&/dev/null; then
            stop
            start
        fi
        ;;
    status)
        status -p $PROXY_PID $prog
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|reload|status|condrestart|try-restart}"
        RETVAL=1
        ;;
esac


exit $RETVAL


阅读(822) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~