2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

时间:2022-09-23 20:46:03

 

MySQL主从服务器

实现方式: MySQL  REPLICATION

Replication可以实现将数据从一台数据库服务器(master)复制到一台或多台数据库服务器(slave)

默认情况下这种情况属于异步复制,无需维持长连接

通过配置,可以复制所有库或者几个库,甚至库中的一些表

它是MySQL内建的,自带

Replication的原理

主服务器master将数据库的改变写入二进制日志文件,从服务器slave同步这些二进制日志,并生成中继日志,从服务器根据中继日志,执行这些改变

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

DML:SQL操作语句,update,insert,delete

Relay log :中继日志

工程流程(见下图)

整体来说,分三步:

1). Master将改变记录到二进制日志(binary log)中.

(这些记录叫做二进制日志事件,binary log events);

2). Slave将Master的binary log events拷贝到它的中继日志(Relay log);

# 本过程由Slave的I/O线程来完成

3). Slave重做中继日志中的事件,修改Slave上的数据

# 本过程由Slave的SQL线程来完成

# 故,这里有个前提,就是在搭建环境时,Master和Slave数据一致

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

更详细的解释如下:

mysql主从复制中:

第一步:master记录二进制日志。在每个事务更新数据完成之前,master在二进制日志记录这些改变。MySQL将事务写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。
第二步:slave将master的binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经执行完master产生的所有文件,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。
第三步:SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重新执行其中的事件而更新slave的数据,使其与master中的数据一致。

此外,在master中也有一个工作线程和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程。复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。

Replication的作用

1. Fail Over 故障切换

2. Backup Server 备份服务,无法对SQL语句执行产生的故障恢复,有限备份

3. High Performance 高性能,可以多台Slave,实现读写分离

Replication常见方案:

1、One master and Muti salve  一主多备

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

一般用来做读写分离的,master写,其他slave读

这种架构最大问题I/O压力集中

在Master上<多台同步影响IO>

2、M-S-S

使用一台slave作为中继,分担Master的压力,slave中继需要开启bin-log,并配置log-slave-updates

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

Slave中继可使用Black-hole存储引擎,不会把数据存储到磁盘,只记录二进制日志

3、M-M  双主互备

很多人误以为这样可以做到MySQL负载均衡,实际什么没什么好处,每个服务器需要做同样的同步更新,破坏了事物的隔离性和数据的一致性

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

4、M-M-M

监控三台机器互相做对方的master

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

天生的缺陷:复制延迟,slave上同步要慢于master,如果大并发的情况那延迟更严重

Mysql在5.6已经自身可以实现fail over

5、One slave Muti master  一从对多主

好处:节省成本,将多个master数据自动化整合

缺陷:对库和表数据的修改较多

四:部署MySQL主从同步 <M-S>

环境准备:

主机名

IP

系统 / MySQL版本

角色

xiaogan64

192.168.31.64

CentOS6.8 / 5.5.53

Master

xiaogan63

192.168.31.63

CentOS6.8 / 5.5.53

slave

模式:C/S

端口:3306

配置主数据库服务器xiaogan64

创建需要同步的数据库:

mysql> create database Test;

mysql> use Test;

mysql> create table xiaogan(id int,name varchar(20));

service mysqld stop

配置my.cnf:

vim /etc/my.cnf

log-bin=mysql-bin-master  #启用二进制日志,开启log-bin 并设置为master

server-id=1   #本机数据库ID 标示 默认就是1,这里不用改

binlog-do-db=Test #可以被从服务器复制的库。二进制需要同步的数据库名

binlog-ignore-db=mysql  #不可以被从服务器复制的库

重启mysql:

service mysqld restart

授权:

mysql> grant replication slave on *.* to slave@192.168.31.64 identified by "123456";

查看状态信息:

mysql> show master status;

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

查看二进制日志:

ls /usr/local/mysql/data/

mysql> show binlog events\G

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

复制前要保证同步的数据库一致

mysqldump  -uroot -p123456  Test >Test.sql  

#也可以导出数据库

将导出的数据库传给从服务器

方法一:scp Test.sql  192.168.31.63:/root

方法二:使用nc命令

NetCat,它短小精悍、功能实用,被设计为一个简单、可靠的网络工具,可通过TCP或UDP协议传输读写数据。同时,它还是一个网络应用Debug分析器,因为它可以根据需要创建各种不同类型的网络连接。

语法:

服务器端:nc发送数据的语法:  nc   -l  端口  < 要传输的文件

客户端:  nc接受数据的语法:  nc   远程nc服务器端IP  端口   >  文件名

开始传送:

[root@xiaogan64 ~]# nc -l 888 < test.sql

[root@xiaogan64 ~]# lsof -i :888

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

nc      3464 root    3u  IPv4  18662      0t0  TCP *:cddbp (LISTEN)

开始接收:

记得清空两台服务器的iptables,要不然端口不能通信

iptables –F

/etc/init.d/iptables save

nc 192.168.31.64 888 > test.sql

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

配置从数据库服务器xiaogAN63

两台数据库服务器mysql版本要一致

mysql> show variables like '%version%';

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

测试连接到主服务器是否成功

mysql -uslave -p123456 -h 192.168.31.64

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

只有复制的权限

导入数据库,和主数据库服务器保持一致

mysql> create database Test;

mysql -uroot -p123456 Test<Test.sql

修改从服务器配置文件:

从服务器没必要开启bin-log日志

service mysqld stop

vim /etc/my.cnf

server-id=2 

#从服务器ID号,不要和主ID相同 ,如果设置多个从服务器,每个从服务器必须有一个唯一的server-id值,必须与主服务器的以及其它从服务器的不相同。可以认为server-id值类似于IP地址:这些ID值能唯一识别复制服务器群集中的每个服务器实例。

mysql> change master to master_host='192.168.31.64',master_user='slave',master_password='123456'; # 注,是,号连接

mysql> start slave;

mysql> show slave status\G  查看状态

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

Slave_IO_Running :一个负责与主机的io通信

Slave_SQL_Running:负责自己的slave mysql进程

文本框是mysql5.1的配置

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

再到主服务器 xiaogan64 上查看状态:

mysql> show processlist \G

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

插入数据测试同步:

mysql> insert into Test.xiaogan values (11,'ganbugan');

从数据库上查看:

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

排错:

如果遇到主从不同步,看一下主从bin-log的位置,然后再同步。

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

从服务器 xiaogan63 上执行MySQL命令:

mysql> slave stop; #先停止slave服务

mysql> change master to master_log_file='mysqllog.000004' ,master_log_pos=106;

#根据上面主服务器的show master status的结果,进行从服务器的二进制数据库记录回归,达到同步的效果

mysql>slave start; #启动从服务器同步服务

mysql> show slave status\G; #用show slave status\G;看一下从服务器的同步情况

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

如果都是yes,那代表已经在同步

重启从服务器,再查看状态:

停止从服务器slave stop;

开启从服务器slave start;

排错思路:

1. 二进制日志没有开启

2. IPTABLES 没有放开端口

3. 对应的主机 IP地址写错了

SQL线程出错

1、主从服务器数据库结构不统一

出错后,数据少,可以手动解决创建插入,再更新slave状态。

:如果主上误删除了。那么从上也就误删除了。 #因此主上要定期做mysqldump备份。

五:部署MySQL主主双向主从复制  M-M

通过mysql主主:进行mysql 双向同步数据库Test的配置

mysql主:服务端:xiaogan63   IP:192.168.31.63

mysql主:服务端:xiaogan64   IP:192.168.31.64 

在上面主从的基础上进行配置

配置xiaogan63

它有两种身份:

身份1: xiaogan63的主。 身份2: xiaogan64的从。

vim /etc/my.cnf

log-bin=mysql-bin-slave

binlog-do-db=Test

binlog-ignore-db=mysql  #避免同步mysql用户 相关配置

service mysqld restart

授权:

mysql> grant replication slave on *.* to slave@'192.168.31.64' identified by '123456';

配置xiaogan64

vim /etc/my.cnf # 不用修改

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

5.1的配置

5.5上的配置:

[root@xiaogan64 ~]# mysql  -uroot -p123456

mysql> change master to master_host='192.168.31.64',master_user='slave',master_password='123456';

mysql> start slave;

mysql> show slave status\G

检查:

xiaogan64上查看slave状态

mysql> show slave status \G

xiaogan63上查看slave状态

mysql> show slave status \G

插入数据测试:

xiaogan63上插入数据,xiaogan64上查看

mysql> insert into T1 values(2,'天清');

xiaogan64上插入数据,xiaogan63上查看

mysql> insert into T1 values(3,'黑客');

注意:这种M-M架构没有什么好处,他往往给我们产生一种实现了负载均衡的错觉

六:部署M-S-S模型

环境:

xiaogan63   master      mysql5.5.53 192.168.31.63

xiaogan64 slave中继   mysql5.5.53     192.168.31.64

xiaogan65   slave mysql5.5.53     192.168.31.65

部署master---->xiaogan63:

授权用户:

mysql> grant replication slave on *.* to 'repl'@192.168.31.64 identified by '123456';

[root@xiaogan63 ~]# vim /etc/my.cnf   #修改配置

sync-binlog=1

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

service mysqld restart

导出Master完整备份,  mysqldump .sql

XtraBackup工具下载地址

https://www.percona.com/downloads/XtraBackup/LATEST/

提供mysql运行时备份

源码安装方法:

https://www.percona.com/doc/percona-xtrabackup/LATEST/installation/compiling_xtrabackup.html

YUM源安装方法:

https://www.percona.com/doc/percona-xtrabackup/LATEST/installation/yum_repo.html

第一步:安装percona的repo源 # Install the Percona repository

yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm -y

第二步: 检查yum源是否已生效: 执行 yum list | grep percona 即可

yum list | grep ^percona-xtrabackup

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

第三步:安装xtrabackup

yum -y install xtrabackup-24

依赖关系:

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

[root@xiaogan63 ~]# innobackupex --user=root --password=123456 /opt/backup

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

[root@xiaogan63 ~]# innobackupex --user-memory=500M --apply-log /opt/backup/2016-10-22_23-49-01/ # 这个目录是上一条命令创建的

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

将备份拷贝至slave中继,和slave

[root@xiaogan63 ~]# scp -r /opt/backup/ 192.168.31.64:/opt/

[root@xiaogan63 ~]# scp -r /opt/backup/ 192.168.31.65:/opt/

部署slave中继------> xiaogan64

修改主配置文件也要开启bin-log:

log-bin=mysql-bin-slave1

log-slave-updates=1  

#把它从relay-log中读取出来的二进制日志以及本机上执行的操作记录自己的二进制日志里面,这样才能使第三台slave通过中继slave读取到相应数据变化

binlog_format=row

server-id       = 2

拷贝master导出的数据到data下:

[root@xiaogan64 ~]# service mysqld stop

[root@xiaogan64 ~]# rm -rf /data/*

[root@xiaogan64 ~]# mv /opt/backup/2016-10-22_23-49-010/* /data/

[root@xiaogan64 ~]# chown -R mysql:mysql /data/

授权:

mysql> change master to master_host='192.168.31.63',master_user='repl',master_password='123456';

mysql> start slave;

# 由于数据库中的data全部是由63上考过来的,所以需要删除原本的xiaogan数据库,不然会报错,知识Slave_SQL_Running 无法创建数据库

# 登录 64的数据库后,删除xiaogan数据库

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

再授权一个用户给slave:

mysql> grant replication slave on *.* to 'repl'@192.168.31.65 identified by '123456';

部署slave------>xiaogan65

导入数据:

[root@xiaogan65 ~]# service mysqld stop

[root@xiaogan65 ~]# rm -rf /data/*

[root@xiaogan65 ~]# mv /opt/backup/2016-10-22_23-49-010/* /data

[root@xiaogan65 ~]# chown -R mysql:mysql /data

修改配置:

log-bin=mysql-bin-slave2

binlog_format=row

server-id       = 3

重启服务:

[root@xiaogan65 ~]# service mysqld start

指定slave中继作为主:

mysql> change master to master_host='192.168.31.64',master_user='repl',master_password='123456';

mysql> start slave;

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

从master上插入数据测试:

mysql> create table mermber(id int(4) unsigned not null auto_increment,name varcTestr(20),primary key(id));

mysql> insert into mermber values(1,'天屠'),(2,'孤叶');

然后分别在slave中继,与slave上查看

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

排错:

错误1:

此方法可能失效,自行验证

mysql> show slave status\G

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

由结果可以看到:

Read_Master_Log_Pos: 288

Exec_Master_Log_Pos: 107

Last_SQL_Errno: 1146

Last_SQL_Error: Error executing row event: 'Table 'Test.student' doesn't exist'

因为只对Test记录了binlog,当在mydb库操作其它数据库的表,但该表在slave上又不存在时就出错了。

到master上查看事件记录

mysql> show binlog events in 'mysql-bin-master.000002' from 107\G

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

由上面的结果可知,我们需要跳过两个事务173,288

然后到salve中继操作:

mysql> slave stop;

mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 2;   跳过一个事务

mysql> slave start;

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

这个搞定

或者:

它提供了一个session粒度的选项,通过关闭这个选项可以不让主库将打开这个选项或关闭连接前的SQL语句写入binlog。

set sql_log_bin=off;

mysql>alter table aaa add column xxx int default 1 after yyy;

模拟故障:

由于历史遗留问题,MySQL主从库的表结构不一致,主库的某个表tableA比从库表tableA少了一个字段

当尝试在主库上更改表结构时,这行alter语句会随着binlog同步到从库,如果从库执行这行语句时出错,主从同步线程就会自动停止,那样只能人为手动处理错误,然后再启动slave上的主从同步线程。场景大概是下面这个样子:

先在从库添加这个字段:

mysql> alter table student add age int default 0 after name;

再在主库添加这个字段:

mysql> alter table student add age int default 0 after name;修改主库上的表结构,添加一个字段

从库会同步主库的,但是从库已经纯在了这个字段

查看slave状态

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

解决方法1:

跳过错误的事物

从库上执行:

mysql> stop slave;

set global sql_slave_skip_counter=1;

mysql> start slave;

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

很多slave数据库的时候这样改太麻烦了

解决方法2:

slave比较少的时候还可以,但是当从库有几十台时,逐台去处理既费时又容易出错,怎样在主库这一侧一劳永逸地避免呢?

那很简单,我们不要让主库将alter语句记录到binlog中就行

我们直接这主库中关闭binlog记录

mysql> set sql_log_bin=off;

然后我们再执行alter语句

mysql> alter table student add age int default 0 after name;

再开启bin-log

mysql> set sql_log_bin=on;

错误2:

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

这种要求对齐binlog

先到作为它的主上查看binlog

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

Slave上不对应

Slave上操作:

mysql> stop slave;

mysql> cTestnge master to master_host='192.168.31.64',master_user='repl',master_password='123456',master_log_file='mysql-bin-slave1.000002',master_log_pos=415;

mysql> start slave;

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

Ok,恢复正常

# 拷贝完成数据后,重启报错

[root@xiaogan65 data]# service mysqld restart  重启报错

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

[root@xiaogan65 data]# rm ibdata1 ib_logfile0 ib_logfile1

rm: remove regular file `ibdata1'? y

rm: remove regular file `ib_logfile0'? y

rm: remove regular file `ib_logfile1'? y

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

[root@xiaogan65 data]# kill -9 9021

[root@xiaogan65 data]# kill -9 9312

[root@xiaogan65 data]# service mysqld restart

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

MySQL读写分离的概述

Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过。但在实际的生产环境中,由单台Mysql作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面。

因此,一般来说都是通过 主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy/Amoeba)来提升数据库的并发负载能力 这样的方案来进行部署与实施的。

读写分离工作原理:

基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

数据内部交换过程:

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

为什么要读写分离:

面对越来越大的访问压力,单台的服务器的性能成为瓶颈,需要分担负载

1、 主从只负责各自的写和读,极大程度的缓解X锁和S锁争用

2、 从库可配置myisam引擎,提升查询性能以及节约系统开销

3、 增加冗余,提高可用性

实现读写分离的方式:

一般有两种方式实现

应用程序层实现,网站的程序实现

应用程序层实现指的是在应用程序内部及连接器中实现读写分离

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

优点:

A:应用程序内部实现读写分离,安装既可以使用

B:减少一定部署难度

C:访问压力在一定级别以下,性能很好

缺点:

A:架构一旦调整,代码要跟着变

B:难以实现高级应用,如自动分库,分表

C:无法适用大型应用场景

中间件层实现

中间件层实现是指在外部中间件程序实现读写分离

常见的中间件程序:

Mysql-proxy amoeba Atlas(360) Cobar(Alibaba) TDDL(Taobao)

优点:

A:架构设计更灵活

B:可以在程序上实现一些高级控制,如:透明化水平拆分,failover,监控

C:可以依靠些技术手段提高mysql性能,

D:对业务代码的影响小,同时也安全

缺点:

需要一定的开发运维团队的支持

MySQL-Proxy概述

MySQL Proxy是一个处于你的client端和MySQL server端之间的简单程序,它可以监测、分析或改变它们的通信。它使用灵活,没有限制,常见的用途包括:负载平衡,故障、查询分析,查询过滤和修改等等。

MySQL Proxy就是这么一个中间层代理,简单的说,MySQL Proxy就是一个连接池,负责将前台应用的连接请求转发给后台的数据库,并且通过使用lua脚本,可以实现复杂的连接控制和过滤,从而实现读写分离和负载平衡。对于应用来说,MySQL Proxy是完全透明的,应用则只需要连接到MySQL Proxy的监听端口即可。当然,这样proxy机器可能成为单点失效,但完全可以使用多个proxy机器做为冗余,在应用服务器的连接池配置中配置到多个proxy的连接参数即可。

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

MySQL Proxy更强大的一项功能是实现“读写分离”,基本原理是让主数据库处理事务性查询,让从库处理SELECT查询。数据库复制被用来把事务性查询导致的变更同步到集群中的从库。   

下载: mysql-proxy

http://dev.mysql.com/downloads/mysql-proxy/

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

端口:  mysql-proxy 默认端口:4040

部署mysql-proxy实现读写分离

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

实验环境:

mysql-proxy服务端: xiaogan65             IP:192.168.31.65

mysql服务器(主,负责写)服务端:xiaogan63    IP:192.168.31.63

mysql服务器(从,负责读)客户端:xiaogan64    IP:192.168.31.64

部署mysql-proxy服务端xiaogan65:

安装前需要系统支持LUA语言环境:

[root@xiaogan65 ~]# yum install lua

安装mysql-proxy:

推荐采用已经编译好的二进制版本,因为采用源码包进行编译时,最新版的MySQL-Proxy对automake,glib以及libevent的版本都有很高的要求,而这些软件包都是系统的基础套件,不建议强行进行更新。
并且这些已经编译好的二进制版本在解压后都在统一的目录内,因此建议选择以下版本:

[root@xiaogan65 ~]# wget http://cdn.mysql.com/archives/mysql-proxy/mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz

[root@xiaogan65 ~]# tar -xf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local/

[root@xiaogan65 local]# mv mysql-proxy-0.8.5-linux-el6-x86-64bit/ mysql-proxy

修改系统环境变量:

[root@xiaogan65 local]# vim /etc/profile

export PATH=/usr/local/mysql-proxy/bin/:/usr/local/mysql/bin:$PATH

[root@xiaogan65 local]# source !$

mysql-proxy 脚本配置文件位置:

[root@xiaogan65 ~]# cd /usr/local/mysql-proxy

[root@xiaogan65 ~]# ls share/doc/mysql-proxy/

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

修改配置文件实现读写分离:

[root@xiaogan65 ~]# cd /usr/local//mysql-proxy/share/doc

[root@xiaogan65 doc]# vim mysql-proxy/rw-splitting.lua

修改

40                 min_idle_connections = 4,

41                 max_idle_connections = 8,

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

#修改默认连接,进行快速测试,默认最小4个以上的客户端连接才会实现读写分离,最大链接数为8。

:为了验证试验效果将他改成1 .就是当有一个链接的时候,就实现读写分离的功能。为了清晰的看到读写分离的效果,需要暂时关闭MySQL主从复制功能。

xiaogan63上创建数据库和表,用于实现写操作:

[root@xiaogan63 ~]# mysql -uroot -p123456

mysql> create database db;

mysql> use db;

mysql> create table test(id int);

mysql> insert into test values(6363);

mysql> grant all on db.* to user1@'%'  identified by '123456';

xiaogan64上创建数据库和表,用于实现读操作:

[root@xiaogan64 ~]# mysql -uroot -p123456

mysql> create database db;

mysql> use db;

mysql> create table test(id int);

mysql> insert into test values(6464);

mysql> grant all on db.* to user1@'%'  identified by '123456';

启动服务mysql-proxy服务

[root@xiaogan65 ~]# mysql-proxy --proxy-read-only-backend-addresses=192.168.31.64:3306 --proxy-backend-addresses=192.168.31.63:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua &

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

参数说明:

--proxy-read-only-backend-addresses=192.168.31.64:3306

# 定义后端只读服务器

--proxy-backend-addresses=192.168.31.63:3306  

#定义后端mysql主服务器地址,指定mysql写主服务器的端口

--proxy-lua-script=/usr/local/mysql-proxy/sTestre/doc/mysql-proxy/rw-splitting.lua & 

#指定lua脚本,在这里,使用的是rw-splitting脚本,用于读写分离

当有多个只读服务器时,可以写多个以下参数:

--proxy-read-only-backend-addresses=192.168.31.64:3306  # 定义后端只读服务器

--proxy-read-only-backend-addresses=192.168.31.62:3306  # 定义后端只读服务器

#--proxy-address=192.168.31.65:3307 指定mysql proxy的监听端口,默认为:4040

完整的参数可以运行以下命令查看:

[root@xiaogan65 ~]# mysql-proxy --help-all

查看proxy是否启动:

[root@xiaogan65 ~]# lsof -i :4040

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

测试读写分离

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

测试写操作:

[root@xiaogan65 ~]# mysql -uuser1 -p123456 -P4040 -h192.168.31.65

mysql> use db;

mysql> insert into test values(636363);  回车,没有报错

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

##看不到64数据,可以看到刚写入的数据,说明写操作成功。 因为是第一个客端连接,还没有启动读写分离,所以select读时,没有看到“6464”数据,而是看到主上“6363“数据。

接下来,多打开几个客户端测试一下读。注:第一个链接,一定是走backend 主mysql服务器的。

测试读操作:

[root@xiaogan63 ~]# mysql -uuser1 -p123456 -P4040 -h 192.168.31.65

[root@xiaogan64 ~]# mysql -uuser1 -p123456 -P4040 -h 192.168.31.65

我们再用65登陆,查看

[root@xiaogan65 ~]# mysql -uuser1 -p123456 -P4040 -h 192.168.31.65

这说明读写分离测试成功。 但是数据还没有保持同步。 保持数据同步,可以通过mysql主从来实现。

扩展: 查看客户端连接状态:

mysql> show processlist;

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

部署mysql主从并实现读写分离

在之前的基础上配置主从

配置xiaogan63为master

[root@xiaogan63 ~]# vim /etc/my.cnf

log-bin=mysql-bin-master

binlog_format=row

server-id       = 1

再修改库授权:

[root@xiaogan63 ~]# mysql -uroot -p123456

mysql> grant all on *.* to slave@'%' identified by '123456';

mysql> use db;

mysql> drop table test;

[root@xiaogan63 ~]# service mysqld restart

配置xiaogan64为slave

[root@xiaogan64 ~]# vim /etc/my.cnf

server-id       = 2

[root@xiaogan64 ~]# service mysqld restart

[root@xiaogan64 ~]# mysql -uroot -p123456

mysql> change master to master_host='192.168.31.63',master_user='slave',master_password='123456';

mysql> use db;

mysql> drop table test;

mysql> start slave;

mysql> show slave status\G

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

主从同步测试:

1:Mysql主数据库xiaogan63插入数据:

mysql> use db;

mysql> create table admin(id int);

mysql> insert into admin values(63);

2:Mysql从数据库xiaogan64查看同步的数据:

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

同步后,测试使用mysql-proxy 能否读到同样的数据。

在xiaogan65上测试

[root@xiaogan65 ~]# mysql -uslave -p123456 -P4040 -h192.168.31.65

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

#可以查看到admin中的63记录,说明mysql+proxy+主从读写分离成功。

插入数据测试:

mysql> use db;

mysql> insert into admin values(64);

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

在xiaogan63,xiaogan64上查看都有

当我们slave挂掉后咋样呢

模拟故障:

[root@xiaogan64 ~]# service mysqld stop

在xiaogan65上测试读写

mysql> insert into admin values(65);

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

xiaogan63上查看连接状态,确认关闭slave后,读写都是访问xiaogan63

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

总结:当停止掉 slave 数据库,proxy 的查询就会转移到 master 上,当把 slave 启动后,proxy 依然在读 master,当有新的链接进来的时候才会重新去读取 slave 的数据。有时可能需要重启下 mysql-proxy。

如果主数据库挂了:

主从也没了,在xiaogan65上只能查看数据

[root@xiaogan65 ~]# mysql -uuser1 -p123456 -P4040 -h192.168.31.65

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离

2-18,19 搭建MySQL主从服务器并并通过mysql-proxy实现读写分离