MySQL的主从同步是一个非常成熟的架构。压力;②从主服务器备份,避免备份时影响主服务器的服务;③当主服务器出现问题时,可以切换到从服务器。这些好处相信大家已经非常熟悉了,在项目的部署中也采用了这种方案。但是MySQL的主从同步一直存在从库延迟的问题,那么为什么会出现这样的问题。如何解决这个问题呢?MySQL数据库主从同步延时原理。MySQL数据库主从同步延迟是怎么产生的?MySQL数据库主从同步延时解决方案。1、MySQL数据库主从同步延时原理。答:说到MySQL数据库的主从同步延时原理,就不得不从mysql数据库的主从复制原理说起。mysql的主从复制是单线程操作。主库为所有的DDL和DML生成binlog,binlog是顺序写入的,所以效率非常高。从库的Slave_IO_Running线程从主库取日志,效率很高。接下来,问题就来了。从库的Slave_SQL_Running线程在从库上实现主库的DDL和DML操作。DML和DDL的IO操作是随机的,不是顺序的,成本要高很多。它还可能导致对从站上的其他查询的锁争用。由于Slave_SQL_Running也是单线程的,所以一个DDL卡主需要执行10分钟。那么后面所有的DDL都会等这个DDL执行完再继续执行,这样就造成了延迟。有朋友会问:“主库上同一个DDL也要执行10分钟,为什么从库会延迟呢?”答案是master可以并发,但是Slave_SQL_Running线程不能。2、MySQL数据库主从同步延迟是怎么产生的?答:当主库TPS并发高时,产生的DDL量超过了从库一个sql线程所能承受的范围,所以会出现延迟,当然也有可能会出现大查询语句锁等待奴隶。3、MySQL数据库主从同步延迟解决方案答:减少从同步延迟最简单的解决方案就是优化架构,尽量让主库的DDL执行得尽可能快。另外写了主库,它有更高的数据安全性,比如sync_binlog=1,innodb_flush_log_at_trx_commit=1等设置,但是slave不需要那么高的数据安全性,可以说sync_binlog设置为0或者binlog被关闭。innodb_flushlog也可以设置为0来提高SQL的执行效率。另一种是使用比主库更好的硬件设备作为从库。mysql-5.6.3已经支持多线程主从复制。原理和丁奇差不多。丁奇以表来做多线程,而Oracle以数据库(schema)为单位来做多线程。不同的库可以使用不同的复制线程。基于局域网的master/slave机制可以满足一般情况下“实时”备份的要求。如果延迟比较大,首先确认以下几个因素:网络延迟masterloadslaveload一般的做法是使用多个slave来分担读请求,然后从这些slave中抽出一个专门的server做备份。无需任何其他操作,就可以相对最大程度地达到“实时”的要求。slave_net_timeout的单位是秒。默认设置为3600秒。参数含义:当slave无法从master数据库读取日志数据时,等待多久重新建立连接并获取数据。master-connect-retry的单位是秒。默认设置为60秒。参数含义:重新建立主从连接时,如果连接建立失败,需要多长时间才会重试。通常配置以上两个参数可以减少网络问题导致的主从数据同步延迟。判断主从延迟,通常有两种方法:1.Seconds_Behind_Mastervs2.mk-heartbeat。下面具体说明这两个函数在实现上的区别。可以通过监控showslavestatusG命令输出的Seconds_Behind_Master参数的值来判断是否存在主从延时。它的值有几种类型:NULL——表示io_thread或sql_thread中有一个失败,即线程的Running状态是No,不是Yes。0——值为零,这是我们极度渴望看到的,说明主从复制是好的,可以认为lag不存在。正值——表示主从已经延迟,数字越大,从库越落后于主库。负值——几乎很少见,只是听一些资深DBA说见过。其实这是一个BUG值。该参数不支持负值,即不应该出现。Seconds_Behind_Master就是这样一个差值,通过比较sql_thread执行的事件的时间戳和io_thread复制的事件的时间戳(简称ts)。我们都知道relay-log和主库的bin-log的内容是完全一样的。当记录sql语句时,会记录当时的ts,所以参考值来自于binlog。其实master-slave不需要和NTPSynchronization一样,也就是说不需要保证主从时钟的一致性。你还会发现,其实对比是发生在io_thread和sql_thread之间,而io_thread确实和主库相关,所以问题就出现了。当主库I/O负载大或网络阻塞时,io_thread无法及时复制binlog(不中断,也在复制),而sql_thread可以跟上io_thread的脚本。这时候Seconds_Behind_Master的值为0,也就是我们认为没有延迟,其实不然,你懂的。这就是为什么大家批评使用这个参数来监控数据库中的延迟是否不准确,但是这个值并不总是不准确的。如果io_thread和master网络都很好,那么这个值也很重要。的价值。(比如:母子媳关系,母子是亲戚,儿媳妇和儿子也是亲戚,不一定媳妇和妈妈很亲近。开玩笑的:-)之前提到的参数Seconds_Behind_Master会有一个负值,我们已经知道这个值就是io_thread的最近新ts和sql_thread的ts执行的差值。前者永远大于后者。唯一的可能是某个事件的ts有错误,比上一个小,那么当这种情况发生时,负值就成为可能。方法2.mk-heartbeat是Maatkit***工具包中的一个工具,被认为是一种可以准确判断复制延迟的方法。mk-heartbeat的实现也是通过timestmp的对比来实现的。首先需要保证主从服务器必须一致,并与同一台NTP服务器同步时钟。需要在主库上创建一个心跳表,其中至少包含id和ts两个字段,id为server_id,ts为当前时间戳now(),该结构体也会被复制到从库,并且table建好之后,会以后台进程方式在主库上执行一行update操作命令,定时向table中插入数据。默认周期为1秒。同时,从库也会在后台执行一个监控命令,与主库保持一致的循环进行比较。复制出来的ts值和主库上相同的ts值相差0,表示没有延迟,差值越大表示延迟秒数越多。我们都知道replication是异步的,ts并不愿意完全一致,所以工具允许有半秒的间隔,这里面的区别可以忽略不计,因为没有延迟。这个工具巧妙地借用了时间戳,通过实际复制来查看延迟,点赞!
