2.一、环境设定mysql
主机名 | IP |
master | 192.168.182.129 |
slave | 192.168.182.130 |
mysql-proxy | 192.168.182.131 |
2.二、实现主从同步git
2.2.一、原理:github
1)主从同步过程当中主服务器有一个工做线程I/O dump thread,从服务器有两个工做线程I/O thread和SQL thread。sql
2)主库把外界接收的SQL请求记录到本身的binlog日志中,从库的I/O thread去请求主库的binlog日志,并将binlog日志写到中继日志中,而后从库重作中继日志的SQL语句。主库经过I/O dump thread给从库I/O thread传送binlog日志。数据库
3)异步复制是MySQL默认的复制方式,主库写入binlog日志后便可成功返回客户端,无须等待binlog日志传递给从库的过程,可是一旦主库宕机,就有可能出现丢失数据的状况。apache
4)复制原理vim
4.1 )异步复制后端
异步复制是MySQL默认的复制方式,主库写入binlog日志后便可成功返回客户端,无须等待binlog日志传递给从库的过程,可是一旦主库宕机,就有可能出现丢失数据的状况。安全
4.2) 半同步复制服务器
MySQL默认的复制方式是异步复制,可是当主库宕机,在高可用架构坐准备切换,就会形成新的主库丢失数据的现象。
MySQL5.5版本以后引入了半同步复制,可是主从服务器必须同时安装半同步复制插件。在该功能下,确保从库接收完成主库传递过来的binlog内容已经写入到本身的relay log后才会通知主库上面的等待线程。若是等待超时(超时参数:rpl_semi_sync_master_timeout),则关闭半同步复制,并自动转换为异步复制模式,直到至少有一台从库通知主库已经接收到binlog信息为止。
半同步复制提高了主从之间数据的一致性,让复制更加安全可靠,在5.7 版本中又增长了rpl_semi_sync_master_wait_point参数,用来控制半同步模式下主库返回给session事务成功以前的事务提交方式。
该参数有两个值:
1)AFTER_COMMIT:5.6版本的默认值,主库将每一个事务写入binlog,并传递给从库,刷新到中继日志中,同时主库提交事务。以后主库开始等待从库的反馈,只有收到从库的回复以后,master才将commit OK的结果反馈给客户端。
2)AFTER_SYNC:5.7版本新增,也是默认的半同步复制方式。主库将每一个事务写入binlog并传递给从库,刷新到中继日志中,主库开始等待从库的反馈,接收到从库的回复以后,再提交事务而且返回commit OK结果给客户端。
注意:能够经过rpl_semi_sync_master_wait_for_slave_count参数来控制主库接收多少个从库写事务成功反馈,才返回成功给客户端。生产环境中使用半同步复制方式,当从库出现故障,等待超时的时间又很长,致使主库没法接收从库信息而没法正常写入时,可经过该参数剔除故障从库。另外rpl_semi_sync_master_timeout单位是毫秒,它表示若是主库等待从库回复消息的时间超过该值,就自动切换为异步复制模式,建议调整为很大,禁止向异步复制切换来保证数据复制的安全性。MySQL 5.7默认的半同步复制方式是after_sync模式。
在AFTER_SYNC模式下,即便主库宕机,全部在主库上已经提交的事务都能保证已经同步到从库的中继日志中,不会丢任何数据。
原理图:
2.2.二、主从配置:
注意:这里使用的是mysql5.6版本,若是其它版本的话,配置可能会有点不同,例如:"log_bin" 对应 "log-bin",只是把"_"换成了"-"了,区别不大,注意一下就行
#=======================master配置(my.cnf)=====================
# 设置优先级,主必须小于从 server-id=1 # bin log文件前缀 log_bin=mysql-bin # 对应要同步的数据库 binlog_do_db=tuling binlog_do_db=zabbix # 不须要同步的数据库 binlog_ignore_db=information_schema binlog_ignore_db=mysql binlog_ignore_db=performance_schema binlog_ignore_db=test
#=======================slave配置(my.cnf)=====================
# 实例ID,不能喝集群忠的其它mysql实例相同,惟一性 server-id=2 # 对应要同步的数据库,若是没有向其它数据库同步的要求的话,能够不写 # log_bin=mysql-bin # 须要同步的数据库 replicate_do_db=tuling replicate_do_db=zabbix # 设定须要复制的表 # replicate_do_table=tuling.tab1 # 设定须要忽略的复制表 # replicate_ignore_table=tuling.tab2 # 增长通配符的两个配置 # replicate_wild_do_table=tuling.% 只复制哪一个库的哪一个表 # replicate_wild_ignore_table=tuling.% 忽略哪一个库的哪一个表 # replicate_do_table 跟 replicate_wild_do_table 同样,只不过replicate_wild_do_table能够加通配符 # replicate_ignore_table 跟 replicate_wild_ignore_table 同样,只不过replicate_wild_ignore_table能够加通配符 # 不须要同步的数据库 replicate_ignore_db=information_schema replicate_ignore_db=mysql replicate_ignore_db=performance_schema replicate_ignore_db=test
# 在master上建立一个同步权限的帐户 用来同步数据 grant replication slave on *.* to 'master'@'%' identified by '123456'; show master status\G; # 配置从库 stop slave reset slave; change master to master_host='192.168.182.129',master_user='master',master_password='123456',master_port=3306,master_log_file='mysql-bin.000018',master_log_pos=326; start slave; show slave status\G; # 当Slave_IO_Running和Slave_SQL_Running线程都为yes是主从复制配置成功!
2.三、错误及解决办法
问题: 从数据库没法同步
Slave_SQL_Running 值为 NO,或 Seconds_Bebind_Master 值为 Null
缘由:
1. 程序有可能在 slave 上进行了写操做
2. 也有多是 slave 机器重启后,事务回滚形成的
解决方法一:
msyql> stop slave; msyql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1; msyql> start slave;
解决方法二:
msyql> stop slave;
#查看主服务器上当前的 bin-log 日志名和偏移量
msyql> show master status;
#获取到以下内容:
+------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000005 | 286 | | | +------------------+----------+--------------+------------------+
#而后到从服务器上执行手动同步
msyql> change master to ->master_host="192.168.10.1", ->master_user="user", ->master_password="123456", ->master_post=3306, ->master_log_file="mysql-bin.000005", ->master_log_pos=286;
msyql> start slave;
Atlas 是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了不少功能特性。
下载Atlas会有两个版本,其中有个分表的版本,可是这个须要其余的依赖,我这边不须要分表这种需求,因此安装普通的版本
Atlas (普通) : Atlas-2.2.1.el6.x86_64.rpm Atlas (分表) : Atlas-sharding_1.0.1-el6.x86_64.rpm
首先进入Linux的Home目录下,下载非分表的安装包
[root@localhost ~]# cd /home/ [root@localhost home]# wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
下载好了以后,进行安装
[root@localhost home]# rpm -ivh Atlas-2.2.1.el6.x86_64.rpm Preparing... ########################################### [100%] 1:Atlas ########################################### [100%]
安装好了,它会默认在”/usr/local/mysql-proxy”下给你生成4个文件夹,以及须要配置的文件,以下:
[root@localhost home]# ll /usr/local/mysql-proxy/ total 16 drwxr-xr-x. 2 root root 4096 Dec 28 10:47 bin drwxr-xr-x. 2 root root 4096 Dec 28 10:47 conf drwxr-xr-x. 3 root root 4096 Dec 28 10:47 lib drwxr-xr-x. 2 root root 4096 Dec 17 2014 log
bin目录下放的都是可执行文件 1. “encrypt”是用来生成MySQL密码加密的,在配置的时候会用到 2. “mysql-proxy”是MySQL本身的读写分离代理 3. “mysql-proxyd”是360弄出来的,后面有个“d”,服务的启动、重启、中止。都是用他来执行的 conf目录下放的是配置文件 1. “test.cnf”只有一个文件,用来配置代理的,可使用vim来编辑 lib目录下放的是一些包,以及Atlas的依赖 log目录下放的是日志,如报错等错误信息的记录
进入bin目录,使用encrypt来对数据库的密码进行加密,个人MySQL数据的用户名是root,密码是root,我须要对密码进行加密
[root@localhost bin]# ./encrypt root DAJnl8cVzy8=
配置Atlas,使用vim进行编辑
[root@localhost conf]# cd /usr/local/mysql-proxy/conf/ [root@localhost conf]# vim test.cnf
进入后,能够在Atlas进行配置,360写的中文注释都很详细,根据注释来配置信息,其中比较重要,须要说明的配置以下:
这是用来登陆到Atlas的管理员的帐号与密码,与之对应的是“#Atlas监听的管理接口IP和端口”,也就是说须要设置管理员登陆的端口,才能进入管理员界面,默认端口是2345,也能够指定IP登陆,指定IP后,其余的IP没法访问管理员的命令界面。方便测试,我这里没有指定IP和端口登陆。
#管理接口的用户名 admin-username = user #管理接口的密码 admin-password = pwd
这是用来配置主数据的地址与从数据库的地址,这里配置的主数据库是135,从数据库是134
#Atlas后端链接的MySQL主库的IP和端口,可设置多项,用逗号分隔 proxy-backend-addresses = 192.168.182.129:3306 #Atlas后端链接的MySQL从库的IP和端口,@后面的数字表明权重,用来做负载均衡,若省略则默认为1,可设置多项,用逗号分隔 proxy-read-only-backend-addresses = 192.168.182.130:3306@1
这个是用来配置MySQL的帐户与密码的,个人MySQL的用户是root,密码是root,刚刚使用Atlas提供的工具生成了对应的加密密码
#用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,下行的user1和user2为示例,将其替换为你的MySQL的用户名和加密密码! pwds = root:DAJnl8cVzy8=
这是设置工做接口与管理接口的,若是ip设置的”0.0.0.0”就是说任意IP均可以访问这个接口,固然也能够指定IP和端口,方便测试我这边没有指定,工做接口的用户名密码与MySQL的帐户对应的,管理员的用户密码与上面配置的管理员的用户密码对应。
#Atlas监听的工做接口IP和端口 proxy-address = 0.0.0.0:1234 #Atlas监听的管理接口IP和端口 admin-address = 0.0.0.0:2345
启动Atlas
[root@localhost bin]# ./mysql-proxyd test start OK: MySQL-Proxy of test is started
测试一下Atlas服务器的MySQL状态,要确认它是关闭状态,而且使用mysql命令,进不去数据库
[root@localhost bin]# /etc/init.d/mysqld status mysqld is stopped [root@localhost bin]# mysql ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
确认系统中自带的MySQL进不去了,使用以下命令,进入Atlas的管理模式“mysql -h127.0.0.1 -P2345 -uuser -ppwd ”,能进去说明Atlas正常运行着呢,由于它会把本身当成一个MySQL数据库,因此在不须要数据库环境的状况下,也能够进入到MySQL数据库模式。
[root@localhost bin]# mysql -h127.0.0.1 -P2345 -uuser -ppwd 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>
能够访问“help”表,来看MySQL管理员模式都能作些什么。可使用SQL语句来访问
mysql> select * from help; +----------------------------+---------------------------------------------------------+ | command | description | +----------------------------+---------------------------------------------------------+ | SELECT * FROM help | shows this help | | SELECT * FROM backends | lists the backends and their state | | SET OFFLINE $backend_id | offline backend server, $backend_id is backend_ndx's id | | SET ONLINE $backend_id | online backend server, ... | | ADD MASTER $backend | example: "add master 127.0.0.1:3306", ... | | ADD SLAVE $backend | example: "add slave 127.0.0.1:3306", ... | | REMOVE BACKEND $backend_id | example: "remove backend 1", ... | | SELECT * FROM clients | lists the clients | | ADD CLIENT $client | example: "add client 192.168.1.2", ... | | REMOVE CLIENT $client | example: "remove client 192.168.1.2", ... | | SELECT * FROM pwds | lists the pwds | | ADD PWD $pwd | example: "add pwd user:raw_password", ... | | ADD ENPWD $pwd | example: "add enpwd user:encrypted_password", ... | | REMOVE PWD $pwd | example: "remove pwd user", ... | | SAVE CONFIG | save the backends to config file | | SELECT VERSION | display the version of Atlas | +----------------------------+---------------------------------------------------------+ 16 rows in set (0.00 sec) mysql>
也可使用工做接口来访问,使用命令“mysql -h127.0.0.1 -P1234 -uroot -proot”
[root@localhost bin]# mysql -h127.0.0.1 -P1234 -uroot -proot Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.81-log 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>
若是工做接口能够进入了,就能够在Windows平台下,使用Navicat来链接数据库,填写对应的host,Port,用户名,密码就能够
这里测试读写分离须要使用到Jmeter了,它是Java写第一套开源的压力测试工具,由于这个比较方便。他有专门测试MySQL的模块,须要使用MySQL的JDBC驱动jar包,配置很简单,东西很好很强大很好用。
Jmeter下载地址:http://jmeter.apache.org/download_jmeter.cgi
MySQL的JDBC :http://dev.mysql.com/downloads/connector/j/
下载下来后,分别都解压开来,打开Jmeter ( 在bin路面下的jmeter.bat ) ,在测试计划中,致使JDBC的jar包
配置JDBC的驱动
分别作查询与插入语句
配置好了之后,就先运行查询操做,而后分别监控主数据库与从数据库所在机器的流量,来肯定是否读写,使用在主备Linux命令行输入“sar -n DEV 1 10000”命令来监控读写
先来测试写,目前数据库里面一条信息都没有,开启配置好了的Jmeter,进行写入数据测试
sar命令查看网卡流量 sar这个工具RHEL5自带有,默认也安装。 一个强大的工具(好像这些工具都蛮强的),参数不少,有时间man一下。 -n参数颇有用,他有6个不一样的开关:DEV | EDEV | NFS | NFSD | SOCK | ALL 。DEV显示网络接口信息,EDEV显示关于网络错误的统计数据,NFS统计活动的NFS客户端的信息,NFSD统计NFS服务器的信息,SOCK显示套 接字信息,ALL显示全部5个开关。它们能够单独或者一块儿使用。咱们如今要用的就是-n DEV了。 输入命令:sar –n DEV 1 4
命令后面 1 4 意思是:每一秒钟取一次值,取四次。
主数据库 ( 192.168.182.129 )
从数据库 ( 192.168.182.130)
批量插入数据语句
delimiter // DROP PROCEDURE IF EXISTS proc_batch_insert; CREATE PROCEDURE proc_batch_insert() BEGIN DECLARE pre_name BIGINT; DECLARE ageVal INT; DECLARE i INT; SET pre_name=187635267; SET ageVal=100; SET i=1; WHILE i <= 1000000 DO INSERT INTO tt(descpro) VALUES(NOW()); SET pre_name=pre_name+100; SET i=i+1; END WHILE; END // delimiter ; call proc_batch_insert();
能够看到测试插入数据的操做时,主(192.168.182.129)数据库的网卡有些指标流量很大,而从数据库的流量很小,是应为主数据是主要负责写入的,而从(192.168.182.130)数据库主要是负责同步的。
参数说明: IFACE:LAN接口 rxpck/s:每秒钟接收的数据包 txpck/s:每秒钟发送的数据包 rxbyt/s:每秒钟接收的字节数 txbyt/s:每秒钟发送的字节数 rxcmp/s:每秒钟接收的压缩数据包 txcmp/s:每秒钟发送的压缩数据包 rxmcst/s:每秒钟接收的多播数据包 rxerr/s:每秒钟接收的坏数据包 txerr/s:每秒钟发送的坏数据包 coll/s:每秒冲突数 rxdrop/s:由于缓冲充满,每秒钟丢弃的已接收数据包数 txdrop/s:由于缓冲充满,每秒钟丢弃的已发送数据包数 txcarr/s:发送数据包时,每秒载波错误数 rxfram/s:每秒接收数据包的帧对齐错误数 rxfifo/s:接收的数据包每秒FIFO过速的错误数 txfifo/s:发送的数据包每秒FIFO过速的错误数
查看数据库,发现已经插入了100w条数据了
进行读取数据的测试,只须要执行查询就好,执行“select *from tt;”来查询数据表
主数据库 ( 192.168.182.129 )
从数据库 ( 192.168.182.130 )
能够看到130数据库的流量很是大,129没有什么流量,这下就能够肯定了数据是从数据库读取的。已经实现了读写分离。