1.MYSQL的读写分离原理
   MySQL的主从复制和MySQL的读写分离两者有着紧密联系,首先部署主从复制,只有主从复制完了,才能在此基础上进行数据的读写分离。简单来说,读写分离就是只在主服务器上写,只在从服务器上读,基本的原理是:让主数据库处理事务性查询,而从数据库处理select查询,数据库复制被用来把事务性查询导致的改变更新同步到集群中的从数据库。读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提升了服务器安全。

 mysql_proxy是Mysql的一个开源项目,通过其自带的lua脚本进行sql判断。MySQLProxy实际上是在客户端请求与MySQLServer之间建立了一个连接池。所有客户端请求都是发向MySQLProxy,然后经由MySQLProxy进行相应的分析,判断出是读操作还是写操作,分发至对应的MySQLServer上。对于多节点Slave集群,也可以起做到负载均衡的效果。
   读写分离,无论连接的是哪一个,master或者slave,最后写入,都是写入到master

      

mysql 读写分离不一致 mysql的读写分离_数据库

 

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


3.为什么要读写分离呢?
   因为数据库的“写”(写10000条数据到oracle可能要3分钟)操作是比较耗时的。但是数据库的“读”(从oracle读10000条数据可能只要5秒钟)。所以读写分离,解决的是,数据库的写入,影响了查询的效率。


4.数据库的读写分离:

   MySQL的主从复制和MySQL的读写分离两者有着紧密联系,首先部署主从复制,只有主从复制完了,才能在此基础上进行数据的读写分离。
   因此,需要首先搭建一个简单的主从复制    一主两从   (搭建方法见主从复制的搭建)

 

环境的设置:

172.25.12.1  master
 172.25.12.2  slave
 172.25.12.3  mysql proxy
 172.25.254.9  client(用于测试)

 

在主从复制配置好的前提下,进行下面的操作。


(1)新建一个虚拟机作为调度器

mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz 
    tar zxf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local/ 
    cd /usr/local/ 
    ln -s mysql-proxy-0.8.5-linux-el6-x86-64bit/  mysql-proxy 
    cd mysql-proxy

    mkdir conf     ##创建配置文件存放的目录 
    mkdir logs      ##创建日志目录


(2)修改读写分离配置文件

vim /usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua

   

mysql 读写分离不一致 mysql的读写分离_lua_02

    min_idle_connections = 1   ##默认超过4个连接数时,才开始读写分离,改为1

    max_idle_connections = 2   ##默认8,改为2

      

mysql 读写分离不一致 mysql的读写分离_lua_03

      

mysql 读写分离不一致 mysql的读写分离_lua_04

vim mysql-proxy.conf 
     [mysql-proxy] 
     user=root   ##运行mysql-proxy用户 
     daemon=true   ##以守护进程方式运行 
     keepalive=true   ##崩溃时,尝试重启 
     log-level=debug   ##定义log日志级别,由高到低分别有(error|warning|info|message|debug) 
     log-file=/usr/local/mysql-proxy/log/mysql-proxy.log   ##日志位置 
     admin-username=repl   ##主从mysql共有的用户 
     admin-password=Wang+1212   ##用户的密码 
     proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua     读写分离配置脚本 
     proxy-read-only-backend-addresses=172.25.12.2:3306   ##指定后端从slave读取数据 
     proxy-backend-addresses=172.25.12.1:3306   ##指定后端从master写入数据 
    /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/mysql-proxy.conf  proxy-address=172.25.12.3:3306      ##开启服务
    chmod 660 /usr/local/mysql-proxy/conf/mysql-proxy.conf

      

mysql 读写分离不一致 mysql的读写分离_开发工具_05

 

(3)测试:
 在调度数据库上

ps ax    ##查看是否有相应的进程信息
     1177 ?        S      0:00 /usr/local/mysql-proxy/libexec/mysql-proxy --defaults-file=/usr/local/mysql-pro
     1178 ?        S      0:00 /usr/local/mysql-proxy/libexec/mysql-proxy --defaults-file=/usr/local/mysql-pro
     1179 pts/0    R+     0:00 ps ax

      

mysql 读写分离不一致 mysql的读写分离_数据库_06

netstat -antlpe    ##查看端口是否开启 3306
     Active Internet connections (servers and established)
     roto Recv-Q Send-Q Local Address               Foreign Address             
     tcp        0      0 ::ffff:172.25.254.1:3306    ::ffff:172.25.254.2:32934   ESTABLISHED 1478/mysqld         
     tcp        0      0 ::ffff:172.25.254.1:3306    ::ffff:172.25.254.3:56734   ESTABLISHED 1478/mysqld

     
(4)在调度数据库上:创建可远程登陆的用户,用于远程登陆的测试    mysql> grant insert,update on westos.* to wf

@'%' identified by 'Wang+1212';
         ##创建一个可远程登陆的wf用户,对于westos这个库,拥有插入和更新的权限,并设置密码
    mysql> create database westos;
    mysql> use westos;
    mysql> create table wf (
     -> username varchar(20) not null,
     -> password varchar(25) not null);
    mysql> insert into wf values ('wf','111');
    mysql> select * from wf;


(5)远程登录数据库看是否可以查看
 

yum install -y mysql 
    mysql -h 172.25.254.1 -P westos -u wf 
    mysql-proxy      ##启动后会启动两个端口4040和4041,4040用于SQL转发,4041用于管理mysql-proxy。如有多个mysql-slave可以依次在后面添加


      

mysql 读写分离不一致 mysql的读写分离_数据库_07

mysql> show databases;
    mysql> SELECT * FROM wf;
     ERROR 1142 (42000): SELECT command denied to user 'wf'@'172.25.254.9' for table 'wf'  ##因为wf这个用户没有看的权限 mysql> insert into westos values ('redhat','123');  ##插入成功之后,在slave和master上也插入成功
 mysql> stop slave;  ##此时关闭了slave,就不能进行主从复制了。
 mysql> instert into westos values ('linux','234');  ##再次插入一组数据
 mysql> select * from westos;  ##查看发现没有插入的数据(如果有,说明进入到了master里,再重新登录几遍,因为前面设置了master是读写,slave是只读操作,所以登录到slave才能看到效果)
 mysql -h 172.25.12.3 -u repl -p Wang+1212  ##重新登录一次
 mysql> select * from westos;  ##依旧看不到信息
 mysql> start slave;  ##在slave端打开slave
 mysql> select * from westos;  ##再次看,就可以看到插入的信息。说明slave端是只读的

(6)下载 lsof 工具
   lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。lsof插件可以看到客户端连接的是哪一个mysql主机。

(7)测试:
 在调度器和数据库服务器查看打开的连接
   在master上:yum install lsof -y 

lsof -i :3306
 COMMAND    PID COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
 mysqld  1478 mysql   33u  IPv6   9597      0t0  TCP wf1:mysql->wf2:32934 (ESTABLISHED)
 mysqld  1478 mysql   34u  IPv6   9527      0t0  TCP *:mysql (LISTEN)
 mysqld  1478 mysql   50u  IPv6  10719      0t0  TCP wf1:mysql->wf3:56736 (ESTABLISHED)
 USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

     

mysql 读写分离不一致 mysql的读写分离_mysql_08

 

 

 在slave上:yum install -y lsof

lsof -i :3306
 COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
 mysqld  1477 mysql   34u  IPv6   9525      0t0  TCP *:mysql (LISTEN)
 mysqld  1477 mysql   60u  IPv4   9613      0t0  TCP wf2:32934->wf1:mysql (ESTABLISHED)

   

mysql 读写分离不一致 mysql的读写分离_mysql 读写分离不一致_09

 

 测试:

   当连接数超过最大连接数的时候,会出现读写分离的情况,但是无论,连接的是哪一个服务器,如果写入的话,最终还是会写入到master里面。

      

mysql 读写分离不一致 mysql的读写分离_mysql 读写分离不一致_10

 

5.数据库日志的查看

(1)可在主数据库上查看日志文件
 

cd /var/lib/mysql 
    mysqlbinlog mysql-bin.000001



(2)查看数据库的二进制文件

(3)查看数据库的一些参数

mysql> show variables like ‘%sync%’; 频率 
    mysql> show variables like ‘%binlog%’; 日志文件 
    mysql> show variables like ‘%log%’;



(4)数据库的编码查询

mysqlbinlog binlog.000003 
  mysqlbinlog binlog.000003 –base64-output=DECODE-ROWS 
  mysqlbinlog binlog.000003 –base64-output=DECODE-ROWS -v 
  mysqlbinlog binlog.000003 –base64-output=DECODE-ROWS -vv 
  mysqlbinlog binlog.000003 –base64-output=DECODE-ROWS -vvv