Mysql 的主从复制和 MySQL 的读写分离两者联系紧密,先要部署主从复制,然后在此基础上进行数据的读写分离。
(1)STATEMENT∶基于语句的复制。在服务器上执行SQL语句,在从服务器上执行同样的语句,mysgl默认采用基于语句的复制,执行效率高。
#虽然效率较高但是高并发情况下可能精确度不够
(2)ROW∶基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍
#虽然拥有很高的精确度,但是读写效率较低
(3)MIXED∶混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制
#结合前两种类型的优点,比较实用
(1)Master节点将数据的改变记录成二进制日志(Binary log),当Master上的数据发送改变时,则将其改变写入二进制日志中。
(2)Slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求Master的二进制事件。
(3)同时Master节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至Slave节点本地的中继日志(Relay log)中,Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,即解析成sql语句逐一执行,使得其数据和Master节点的保持一致,最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒。
也就是说:
注:
中继日志通常位于OS缓存中,所以中继日志的开销很小。
复制过程有一个很重要的限制,即复制在Slave上是串行化的,也就是说Master上的并行更新操作不能在Slave上并行操作。
(1)master服务器高并发,形成大量事务
(2)网络波动,延迟
(3)主从硬件设备差异过大导致(如cpu主频、内存io、硬盘io)
(4)本来就不是同步复制、而是异步复制
解决方案:
(1)从库优化Mysql参数。比如增大innodb_buffer_pool_size,该参数定义了In弄DB存储引擎的表数据和索引数据的最大内存缓冲区大小,让更多操作在Mysql内存中完成,减少磁盘操作。
(2)从库使用高性能主机。包括cpu强悍、内存加大。避免使用虚拟云主机,使用物理主机,这样提升了i/o方面性。
(3)从库使用SSD磁盘(固态硬盘)
(4)网络优化,避免跨机房实现同步(减小网络延迟)
基本的原理就是让主数据库处理事务性增、改、删操作(TNSEBT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。