一、MySQL的扩展:
复制:每个node都有相同的数据集
从node请求主node的二进制日志,在本地进行重放实现
复制的作用:
数据分布:
负载均衡://读均衡,写操作不能负载均衡
数据备份://主node挂了,切换从为主 //冷备是最可靠的
高可用性能提升
可以写脚本实现故障转移。//mysql内部没有提供故障转移
MySQL升级测试:
【master】【slave】 //主从复制功能,主node必须启用二进制日志功能。
slave使用msyql协议请求master的二进制日志文件事件
master所有的写操作,除了在本地保存到数据库中,还会将写入[语句]保存到二进制日志
slave请求binary log的时候,可以指定位置,不指定的话
就从第一个文件的最开始,逐个发送给slave
从node收到master二进制日志后,保存到自己的中继日志中,记录读取到的位置[position]
master启动一个dump线程接受slave的请求,然后用dump线程响应客户端
slave留到中继日志中,然后在本地reply一次
二、复制相关线程:
主node:
主node的dump线程;为每个slave的I/O线程启动一个dump线程,用于向其发送binary log events
从node:
io thread:从node负责从master获取并保存到中级日志
sql thread: 读取并应用中级日志
从node需要保存binary log吗?
binary log:用于实现重放和恢复
但是一个slave可以其另外一个slave的master
//slave有自己的slave的话,该slave需要开启二进制日志
级联复制:
[master]--[slave]--[slave]
三、mysql复制的特点:
1.异步,主node并不需要等待从node返回写入结果
同步问题:一旦网络故障,master不能访问,将瘫痪
异步问题:通过slave未必能读到完整的数据
slave会落后于master的内容
好处:在master上操作失误,可以在slave上进行还原,slave切换为主
例如在master上误操作:drop tables
2.延迟:
master在二进制日志中写入的速度一定会慢于本地执行的速度
而slave获取二进制的速度也会慢于二进制日志的写入速度
本地执行>二进制日志>slave获取二进制日志
调度器/LB //七层调度,能够识别sql语句的写和读操作,并且能够实现负载均衡
/ |\
[] [] []
//调度器一般称为:r/w spliter :读写分离
从node不可避免的要落后于master,也可以把最新的请求,调度到master进行读
r/w spliter:检查状态
mysql的query cache:假如查询调度到同一个slave提高缓存命中率,但是损害LB效果
可以在[调度器/LB] + memcahed //
slave宕机:重新调度即可
master宕机:不能执行w操作。可以把一个slave提升为master
如何选取哪一个为主:
A:1,2,3
B:1,2,5
C:1,2,3,4
//选举哪一个呢?各有自己的
//恢复有很多问题,
在mysql 5.6之后,引入了gtid:全局事务id
在此之前tid都是本地的,无法判断哪一个slave完成的事务多
A要想成为master:从B获取5,从C获取4,然后自己成为master
//这种方案,不推荐,很难实现。需要结合gtid和oracle为mysql提供的大量的工具实现
其他方案:
corosync高可用mysql
[master][passive] [slave][slave]
\ /
[共享存储]
//passive节点和master共享vip,故障转移即可
SAN:存储区域网络
passive和master可使用共享存储
但是共享存储:存在单点故障
drbd:分布式磁盘快识别,两个块设备实现跨主机同步
MySQL的内存和io消耗量比较大
硬件性能也非常好
到一定阶段就再扩展,性能可能不会上升,反而会下降
四、如何实现节点间数据同步 //scale out
方案一:共享存储
【LB】
/ \
[] []
\ /
[ ] //共享存储,需要使用集群fs
//对数据施加锁,对于集群fs来说,他的扩展数量是有限的,到达4-8个,差不多到上线了
//该方案可看不可用
方案二:多个数据集
【LB】
/\
[][]
||
[][] //使用副本集,一个node rw,其他node只能读
//每一个node保存完整的数据副本,只有一个node接收w请求,其他节点都通过同步或者复制的机制事先复制。
双主模型:
A和B都即是主node也是对方的从node
[A][B]
[2][relay][file][2][relay][file]
//2:二进制日志
//A和B本地有数据文件、中继日志、二进制日志
通过serverid避免循环复制,根据serverid区分是自己传输给别人的。
A和B都能读和写
读请求被负载了,写请求虽然被LB了,但是实际还是需要A和B都写入
目的:冗余,不用做读写分离了,实现了HA
双主模型可能会导致数据不一致?
两个节点互为条件的,
tom 20岁
A:年龄>=20的工资翻倍
B:年龄大于20的,减去2岁,
那么最后怎么合并
MMM:双主模型解决方案
MHA:现在用的较多
percona:Galera-Cluster:在块级别实现复制 //较可靠的方案
mysql的主从复制:
1.异步复制
2.主从复制不一致比较常见
复制架构:
1.M/S
2.M/M
3.环状复制:每一个node都是上家的slave,又是下家的master
一主多从,一从再从:级联复制
一从只能有一个主
现在一从可以多主,可以从两个master复制不同的数据库
Mairadb 5.6 之后的版本,支持最后进行汇聚
主从
master需要接受w请求,并且启动n个线程,分发二进制日志给各slave
//master的压力依然有点大
如果master只需要复制一份二进制日志
级联可以实现
master->slave1-->[A,B] //slave1负责读和二进制日志分发
master->black hole引擎->[A,B] //black hole引擎所在node不存储数据,只负责分发二进制日志
二进制日志事件记录格式:
STATEMENT 基于语句的
ROW 基于行的,最好的方案,但是最占用空间
MIXED 混合模式,这种方案
演示的模型:
主从、主主、半同步复制(google)、复制过滤
半同步复制:
一主多从
master接受到请求后,至少等待一个从node同步完成,并告诉master数据已经存储ok,才会返回给client ok
//一个slave同步,其他异步:半同步模型
复制过滤:
主从复制架构中,主有10个库,但是从只想复制5个库
过滤器:可以在主node过略,也可以在slave实现
主:二进制日志记录的时候,只记录指定的库,因此从只能获取有限的二进制日志
从:浪费带宽,我只要5个,但是你给我发送10个
五、实现主从复制
192.168.100.67 master
192.168.100.68 slave
配置过程:
master:
1.启动二进制日志
2.为当前node设置一个全局唯一的id号
3.创建一个有复制 权限的用户账号
replication slave,replication client //权限
slave:
1.启动中继日志
2.位当前node设置一个全局唯一的id号
3.使用有复制权限的用户账号连接至master,并启动复制线程
master
vim my.cnf
[mysqld]
log-bin=mysql-bin //注意log_bin和log-bin都可以使用,建议统一
server-id=1
innodb_file_per_table=ON
skip_name_resolve=ON
systemctl start mariadb.service
mysql> show global variables like '%log%'
查看log_bin是否启用
mysql> show logs //查看二进制日志
mysql> show variables like '%server%'
mysql> grant replication slave,replication client on *.* to 'repluser'@'172.16.%.%' identified by 'replpass';
注意卡其3306端口的防火墙
slave:
relay_log=reley_log
relay_log_index=relay-log.index
server-id=7 //
innodb_file_per_table=ON
skip_name_resolve=ON
systemctl start mariadb.service
mysql> show gloabl variables like '%log%';
rely_log = rely_log //日志开启
mysql> show global variables like '%server%';
change master to master_host='192.168.100.67',master_user='repouser',master_password='repopass',maser_log_file='master-bin.00003',master_log_pos=245;
master_user= //
master_host= //主机
master_port= //端口
master_password=
master_connect_retry= //多长时间重连一次,假如不能连接的话
master_log_pos= //复制的二进制日志的位置
master_heartbeat_period= //多长时间进行一次心跳检测
ignore_server_ids= //忽略哪些server id 的
show slave status //查看自己的状态
help start //启动复制线程
start slave; //默认启动sql_thread和io_thread
show slave staus ; //stop slave关闭线程
master:
crete database mydb;
show master status //查看二进制文件到哪一步了
slave:
show slave status;
//查看复制到哪里了
本文转自MT_IT51CTO博客,原文链接:http://blog.51cto.com/hmtk520/1943716,如需转载请自行联系原作者