Mysql 主从复制原理
Mysql 主从复制原理
随着网站业务的不断发展,用户量的不断增加,数据量不断地增长,数据库的访问量也相应的增长,到了一定的时间,网站首先出现的瓶颈就是在数据库层 (这里没有将缓存加入进来),这时候就需要对数据库进行适当的拆分,比如说分库或分表等,如果数据库在分库,分表后还是出现瓶颈,这时就好考虑数据库读写 分离,尤其在读多写少的时候。
mysql中读写分离的方案就是主从复制,master服务器将更新的记录到binary log中,mysql中这个叫二进制日志事件(binary log events), slaver服务器将master中的binary log events 复制到自己的中继日志(relay log)中,slave服务器将监听中继日志,将中继日志的改变记录到数据库中。下图描述了复制的过程:
其中,mysql支持大概3种类型的复制类型:
1.基于语句的复制,(也叫做逻辑复制,logical replication),优点是基于语句的复制的二进制日志可以很好的进行压缩,而且日志的数据量也较小,缺点是基于语句的复制必须是串行化。
2.基于记录的复制(Row-Based Replication),在二进制日志中记录下实际数据的改变,优点就是可以对任何语句都能正确工作,一些语句的效率更高,缺点就是二进制日志会很大,不能使用mysqlbinlog来查看二进制日志.
3.混合类型的复制,默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制.
复制能解决的一些问题:
1.数据分布 (Data distribution )
2.可以实现负载均衡(load balancing),通常所说的读写分离
3.可以实现数据的备份(Backups),但是不能当真正意义上数据备份来用
4.高可用性和容错行(比如双主模型中的互为主从能实现高可用)
但是,主从复制也带来其他一系列其他问题,典型的就是主从不同步,导致主从不同步的原因是 :服务器一般都是多核多线程,导致主节点可以同时执行多条读写操作,而记录二进制日志则必须按顺序有先后的记录,从节点在一条一条复制过去,生成中继日 志,再执行语句,这里就会出现复制延迟。其他问题就是写入无法扩展,锁表率上升等。
复制的体系结构有以下一些基本原则:
(1) 每个slave只能有一个master;
(2) 每个slave只能有一个唯一的服务器ID;
(3) 每个master可以有很多slave;
(4) 如果你设置log_slave_updates,slave可以是其它slave的master,从而扩散master的更新
Mysql复制常见的几种模式:
1.一主多从
由一个master和一个slave组成复制系统是最简单的情况。Slave之间并不相互通信,只能与master进行通信。主要用于读压力比较大的应用的数据库端廉价扩展解决方案。
2.主主复制
Master-Master复制的两台服务器,既是master,又是另一台服务器的slave。这样,任何一方所做的变更,都会通过复制应用到另 外一方的数据库中。在这种复制架构中,各自上运行的不是同一db,比如左边的是db1,右边的是db2,db1的从在右边反之db2的从在左边,两者互为 主从,再辅助一些监控的服务还可以实现一定程度上的高可以用。
3.主动-被动模式(HA)
这种模式由master-master结构变化而来的,它避免了M-M的缺点,实际上,这是一种具有容错和高可用性的系统。它的不同点在于其中只有一个节点在提供读写服务,另外一个节点时刻准备着,当主节点一旦故障马上接替服务。比如通过corosync+pacemaker+drbd+mysql就可以提供这样一组高可用服务,主备模式下再跟着slave服务器,也可以实现读写分离.
主从复制中容易出现的问题:
1.限制从服务器只读,保证主从数据一致。
show global variables like ‘%read%‘
更改slave的全局服务器变量read_only为on
set global read_only on
从节点上授权只读 set global read_only = 1;如果永久有效更改mysql的my.ini 或my.cnf,在[mysql] 中设置read_only = 1
2.保证主从复制时的事务安全
如果mysql比较繁忙它会把二进制日志缓存在内存中,不繁忙时才会把他写到磁盘中,前提就是mysql对二进制日志事件数据会缓冲。在 master上设置如下参数 set global sync_binlog = 1 事物一提交,就必须同步二进制日志,这样会降低性能,但是数据非常重要的情况下。