MYSQL数据库之主从复制及读写分离

Wesley13
• 阅读 481

MYSQL数据库之主从复制及读写分离

一、MySQL的主从复制
1、概述
   MySQL Replication俗称MySQL AB复制或主从复制,是MySQL官方推荐的数据同步技术。数据同步基本过程:从库会实时去读取主库的二进制日志文件,按照日志中记录对从座进行同样的操作,以达到数据同步效果。
2、MySQL Replication优点
通过增加从服务器来提高数据库平台的可靠性能。在主服务器上执行写入和更新,在从服务器上向外提供读功能,可以动态地调整从服务器的数量,从而调整数据库平台的高性能。
提高数据安全性,因为数据已复制到从服务器,主数据库数据异常时,可以将从服务器复制进程终止来达到保护数据完整性的特点。
在主服务器上生成实时数据,而在从服务器上分析这些数据,从而缓解主服务器的性能。
3、复制类型
1)异步复制
MysQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理。
这样就会有一个问题,主库如果down掉了,此时主上已经提交的事务可能并没有传到从座服务器上,如果此时,强行将从提升为主,可能会导致新主上的数据不完整。
默认情况下MySQL5.5/5.6/5.7和mariaDB10.0/10.1的复制功能是异步的。
2)全同步复制
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。
因为需要等待所有从库都行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响,返回客户端的响应速度也会被拖慢
3)半同步复制
MySQL5.5由Google贡献的补丁才开始支持半同步复制(semi Replication)模式,介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relaylog中才返回给客户端。
相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。
所以,半同步复制最好在低延时的网络中使用。当出现超时情况时,源主服务器会暂时切换到异步复制模式,直到至少有一台设置为半同步复制模式的从服务器及时收到信息为止。
半同步复制模式在主服 务器和从服务器同时启用,否则主服务器默认使用异步复制模式。
  半同步复制的潜在问题 :
客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了。此时可能的情况有两种:
 (1)事务还没发送到从库上
此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。
 (2)事务已经发送到从库上
此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。
  无数据丢失的半同步复制:
针对上述潜在问题,MySQL 5.7引入了一种新的半同步方案:Loss-Less半同步复制。
先同步到从库,同步成功主库在提交;
当然,之前的半同步方案同样支持,MySQL 5.7.2引入了一个新的参数进行控制r见lsemi_sync_master wait point。
rplsemi sync master_wait_point 有两种取值:
AFTER_SYNC:这个即新的半同步方案
AFTER_COMMIT:老的半同步方案
4、MySQL支持的复制方式
 (1)基于SQl语句的复制(statement-based replication,SBR):在主服务器上执行的sQL语句,在从服务器上执行同样的SQl语句,效率比较高。。
 (2)基于行的复制(row-based replication,RBR):主服务器把表的行变化作为事件写入到二进制日志中,主服务器把代表了行变化的事件复制到从服务中。
 (2)混合模式复制(mixed-based replication,MBR):先采用基于语句的复制,一旦发现基于语句无法精确复制时,再采用行。
5、复制方式的优缺点
1)RBR
优点:
 (1)任何情况都可以被复制,这对复制数据来说是最安全可靠的。
 (2)更少的行级锁表
 (3)和其他大多数数据库系统的复制技术一样多数情况下
 (4)从服务器上的表如果有主键的话,复制就会快很多
缺点:
 (1)Binlog文件较大。
 (2)复杂的回滚时binlog中会包含大量的数据
 (3)主服务器上执行多个UPDATE语句时,所有发生变化的记录都会写到binlog中,而且只写为一个操作事物,这会导致频繁发生binlog的并发写问题
 (4)不能通过查看日志来审计执行过的sql语句,不过可以通过使用mysqlbinlog
-base64-output=decode-rows--verbose 来查看数据的变动
2)SBR
优点:
 (1)历史悠久,技术成熟,binlog文件较小。
 (2)binlog中包含了所有数据库更改信息,可以据此来审核数据库的安全等情况
 (3)binlog.可以用于实时的还原,而不仅仅用于复制。
 (4)主从版本可以不一样,从服务器版本可以比主服务器版本高
缺点:
 (1)不是所有的UPDATE 语句都能被复制,尤其是包含不确定操作的时候。
 (2)复制需要进行全表扫描(WHERE语句中没有使用到索引)的UPDATE时,需要比RBR请求更多的行级锁
 (3)对于一些复杂的语句,在从服务器上的耗资源情况会更严重
 (4)如下函数的语句不能被正确地复制:load file(),uuid(),uuid short();user();found_rows();sysdate();get lock();is_free_lock();is_used_lock();master_pos wait();rand();release_lock();sleep();version();
 (5)在日志中出现如下警告信息的不能正确地复制:[Warning]Statement is not safe to log in statement format.或者在客户端中出现show warnings
 (6)Insert卻elect 语句会执行大量的行级锁表
6、主从复制的原理
 (1)首先主开启二进制日志,为从授权;从开启中继日志
 (2)从库开启一个IO线程,与主的IO线程连接,时刻监视主的二进制日志有无改动
 (3)如果有变动,复制主的二进制日志,写入从的中继日志,
 (4)从会开启一个sql线程,将中继日志中的内容写入从库
7、复制过程的限制
 (1)MySQL5.6之前的版本复制操作在Slave上执行是串行化的,Master上的并行更新会导致数据复制延迟。
 (2)所有MYSQL 服务器的版本都要高于3.2,还有一个基本的原则就是从服务器的数据库版本可以高于主服务器数据库的版本,但是不可以低于主服务器的数据库版本。
二、MySQL的读写分离
1、概念
通过主从复制(Master-Slave)的方式来同步数据,再通过读写分离来提升数据的高并发负载能力这样的方案来进行部署。
读写分离就是只在主服务器上写,只在从服务器上读、基本的原理是让主数据库处理事务性查询,而从数据库处理select 查询,数据库复制被用来把事务性查询导致的改变更新同步到集群中的从数据库。
2、分离方案
1)基于程序代码内部实现
在代码中根据select,insert进行路由分类,这类方法也是目前生产环境应用最广泛的,优点是性能好,因为在程序代码中实现,不需要曾加额外的设备作为硬件开支,缺点是需要开发人员来实现,运维人员无从下手。
2)基于中间代理
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,代表性程序:
(1)mysql-proxy 为mysgl开发早期开源项目,通过其自带的lua脚本进行sQL判断,虽然是mysql的官方产品,但是mysql官方不建议将其应用到生产环境。
(2)Amoeba(变形虫)由陈思儒开发,曾就职与阿里巴巴,该程序由java语言进行开发,阿里巴巴将其应用于生成环境,它不支持事物和存储过程。
三、主从复制及读写分离实验
数据库内执行     xshell内执行   配置文件的修改
1、五台虚拟机
192.168.200.111     MySQL主
192.168.200.112     MySQL从
192.168.200.113     MySQL从
192.168.200.114     amoeba
192.168.200.115     测试机
2、安装Mariadb
111、112、113:
 yum -y install mariadb mariadb-server
115:
 yum -y install mariadb
3、修改MySQL的配置文件
111:
 vim /etc/my.cnf
 [mysqld]
 server-id=1           #服务描述标号,三台虚拟机不能相同
 log-bin=mysql-binlog     #开启二进制日志
 log-slave-updates=true    #允许从复制
 systemctl restart mariadb
112、113:
 vim /etc/my.cnf
 [mysqld]
 server-id=2                  #服务描述标号,三台虚拟机不能相同
 relay-log=relay-log-bin          #开启中继日志
 relay-log-index=slave-relay-bin.index #索引文件
 systemctl restart mariadb
4、备份主库原有数据
如果主库之前有数据,为了保持数据的一致性,先备份主的数据,同步到从上。
111:
 mysqldump -uroot -p123123 --all-databases > /root/allbackup.sql
 scp /root/allbackup.sql root@192.168.200.112:/root/
 scp /root/allbackup.sql root@192.168.200.113:/root/
112、113:
 mysqldump -uroot -p123123 < /root/allbackup.sql
5、配置主从复制
111:
 mysql                                  #进入数据库
 grant replication slave on *.* to 'myslave'@'192.168.200.11_' identified by '123123'; #为从授权
 grant all on *.* to 'admin'@'192.168.200.11_' identified by '123123';  #为amoeba授权
 flush privileges;                           #刷新授权表
 show master status;                       #查看日志及偏移量
+---------------------+----------+--------------+------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------------+----------+--------------+------------------+
| mysql-binlog.000001  |      479 |           |        |
+---------------------+----------+--------------+------------------+
112、113: 
 mysql
 stop slave;                       #停止从的功能
 CHANGE MASTER TO
 MASTER_HOST='192.168.200.111',            #主的地址
  MASTER_USER='myslave',                 #主授权的用户名
  MASTER_PASSWORD='123123',              #主授权的密码
  MASTER_LOG_FILE='mysql-binlog.000001',      #主的日志
  MASTER_LOG_POS=479;                    #主的日志的偏移量
 start slave;                          #开启从的功能
 show slave status\G                     #查看从的服务
             Slave_IO_Running: Yes    #代表连接成功
            Slave_SQL_Running: Yes     #代表连接成功
 grant all on *.* to 'admin'@'192.168.200.11_' identified by '123123';  #为amoeba授权
 flush privileges;                           #刷新授权表   _单个字符,%表示多个字符
6、安装amoeba
114:
由于amoeba由Java开发,需要先安装jdk,建议安装1.5/1.6
 tar xf jdk-7u65-linux-x64.gz
 mv jdk1.7.0_65/ /usr/local/java
 vi /etc/profile
 export JAVA_HOME=/usr/local/java
 export PATH=$PATH:$JAVA_HOME/bin
 source /etc/profile
 tar xf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba
 chmod -R 755 /usr/local/amoeba/
 /usr/local/amoeba/bin/amoeba
amoeba start|stop                                          #正常
 The stack size specified is too small, Specify at least 228k            #错误
 Error: Could not create the Java Virtual Machine.
如果出现上面红色的报错,修改amoeba的启动文件
 /usr/local/amoeba/bin/amoeba
 58 DEFAULT_OPTS="-server -Xms256m -Xmx256m -Xss256k"
amoeba启动文件正常,然后修改配置文件
 cp /usr/local/amoeba/conf/amoeba.xml /usr/local/amoeba/conf/amoeba.xml.bak  #备份
 vim /usr/local/amoeba/conf/amoeba.xml
 30 amoeba           #用户名,客户端使用
 32 123123      #密码
115 master      #默认找master
118 master        #写入
119 slaves         #读取
 cp /usr/local/amoeba/conf/dbServers.xml /usr/local/amoeba/conf/dbServers.xml.bak  #备份
 vim /usr/local/amoeba/conf/dbServers.xml
 19
 20 3306
 22
 26 admin
 28
 29 123123
 45        
 46                
 48                         192.168.200.111
 49                

 50        

 52        
 53                
 55                         192.168.200.112
 56                

 57        

 58         
 59                  
 61                           192.168.200.113
 62                  

 63          

 65        
 66                
 68                         1
 71                         slave1,slave2
 72                

 73        

 /usr/local/amoeba/bin/amoeba start &     #启动amoeba
 netstat -lnpt | grep :8066                #出现8066端口即为成功
tcp6  0   0 :::8066            :::*           LISTEN      20196/java
7、测试
115:
 mysql -uadmin -p123123 -h192.168.200.114 -P8066
 create database asd;
 create table user(id int,name char(20));
111、112、113:
 show databases;
112、113:
 stop slave;
111:
 use asd;
 insert into user values (1,'a');
112:
 use asd;
 insert into user values (2,'b');
113:
 use asd;
 insert into user values (3,'c');
115:
 select * from asd.user;
查看结果为2b、3c轮替,读写分离成功

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这