1、如何监控发生了主从延迟?mysql
在从库机器上,执行show slave status,查看Seconds_Behind_Master值,表明主从同步从库落后主库的时间,单位为秒,若同从同步无延迟,这个值为0。sql
Mysql主从延迟一个重要的缘由之一是:mysql是以单线程串行执行。数据库
主从复制数据时,在从服务器上的mysql,是一个线程在同步数据。服务器
串行的方式,它是指,执行一个后才继续执行下一个。若是一个卡住了,要等待时间,才会继续下一个。串行与并行是相反的。网络
2、同步延迟发生的场景并发
当主库的TPS并发较高时,产生的DDL(修改类的sql语句)数量,超过了slave机器sql线程所能承受的能力,那么延时就会产生了。函数
主库写binlog日志到文件的时候,是顺序写入到磁盘,顺序写入速度是很快,避免了磁盘随机寻址。post
从库的同步线程(Slave_IO_Running),将binlog在slave上执行的时候,其实是随机的,速度确定要慢点。性能
从库的同步线程(Slave_IO_Running)只有应该线程在操做,整个mysql实例就一个这样的线程,那么,若是mysql有n个库的数据须要同步,所有要这个线程来处理。人手不够啊(mysql-5.6.3)优化
3、解决思路
如何避免或解决主从延迟?能够用来解决的办法,有以下的:
从库优化Mysql参数。好比增大innodb_buffer_pool_size,让更多操做在Mysql内存中完成,减小磁盘操做。
从库使用高性能主机。包括cpu强悍、内存加大。避免使用虚拟云主机,使用物理主机,这样提高了i/o方面性。
从库使用SSD磁盘。机械硬盘是靠磁头旋转到指定位置来读数据、写数据。转来转去的,咱们叫作i/o。磁盘i/o存在速度瓶颈。固态硬盘是一个电子设备,电子设备不须要机械旋转,读写固态硬盘上任意位置的数据,速度都是同样的。
业务代码的妥协。将实时性要求高的某些操做,使用主库作读操做。好比我写了数据到主库了,须要立刻展现数据,不要到从库去读数据,由于从库可能还没同步过去呢。直接从主库读数据,保证是最新的数据展现。
附:mysql主从复制的三种格式数据
第一种是,statement格式。也就是记录下原来执行的sql语句。
这是最先的一种方式,后来发现也不是很完美,在复制的过程当中会存在一些问题。
举例:因为sql语句中使用了某些mysql函数,而这个mysql函数是特定版本才有的,其余版本是没有这个函数,放到slave端运行,假如slave的mysql版本不同,就可能执行出现问题。
使用了特定的功能,若是sql中使用了last_insert_id()函数,当一样的sql语句复制到slave端执行的时候,last_insert_id()所获得的结果是不一样的。
上面两种状况致使了:复制过程当中,slave端的结果没有彻底与master端一致了。
而基于row格式的就不会。因而发明了row格式的。
第二种,基于row格式的。会记录下每一行修改前和修改后的值。binlog中存储的就是被修改行的修改前和修改后的值,直接拿到结果便可。重作。
基于row的格式有个缺点:涉及到ddl操做,好比alter table,加一个字段,那么意味着整个表的行都要进行修改。那么binlog中记录的是整个表中行的数据,形成binlog中的数据量很大。
因而,又发明了基于statement格式和基于row格式的综合版,叫作mixed
第三种:mixed
遇到ddl表变动操做,则使用statement格式,遇到delete或update格式,则使用row格式。
三种格式的发展过程总结:
一直使用statement格式,到了5.1.5版本才支持row格式。后来存储过程的出现,又带来了新的问题。存储过程当中调用一些函数,在slave端运行结果会不一样。因此5.1.8版本开始支持mixed格式。上面全部策略的作法目标是,让master与slave的数据保持一致。从这个角度出发。