mysql备库处理binlog日志是单线程的,无论主库有多少个database或者主库的tps有多高,备库当前的恢复模式都是单进程恢复。这样解决了并发的问题,但是也是备库很容易在主库高tsp的情况下,造成延迟。
一些情况下,备库的延迟可以通过预热来加快sql的执行速度。预热就是将需要更新的数据提取进行select,将数据缓存到内存,减少恢复进程执行时的IO消耗。 但当更新的数据很随机,数据量远远大于buffer pool大小时就不适用了。
数据库的tps上不去,负载过高,同时备库延迟,很多情况下是由于磁盘IO的压力导致的,如果重点考虑的方向是如何在不改变硬件配置的情况下降低io压力,提高整体性能。
以具体案例分析之,要初始化2亿数据,将临时表中的数据根据id更新表中的新字段,数据是128个分表中的全部数据,数据单行长度500字节。应用多进程进行初始化,当主库tps从正常业务量的100上升到200之后,备库开始出现延迟,在更新操作持续5个小时候,延迟超过了1w秒,而且主库负载从正常的1上升至6。可以看到,该初始化方案是无法满足业务需求的,一是更新周期太长,需要25天左右,二是备库延迟太长时间,无法提供正常的业务访问。
从mysql innodb表的结构上考虑,因为是索引组织表,那木根据主键顺序的去操作数据,在获取第一条数据时,会将整个块(mysql innodb的数据库大小设置成了16k)拿到内存,这么再操作随后的几条记录(16K/500~~32条)都可以直接走内存获取,而不需要扫描物理块,这将大大提高主库的tps,备库以同样的理由降低而来磁盘消耗,而减少与主库的延迟。
在上面的案例中,将数据初始化按照主键顺序操作后,初始化的tsp从100上升到300,同时主库压力只从1上升到2.5,备库也没有出现延迟。
在mysql中根据主键顺序去操作数据 跟再oracle中根据rowid排序后去操作数据的原理是类似的,都是通过在磁盘上的数据存储方式,降低了磁盘消耗,提升效率
--EOF--
This work is licensed under a CC A-S 4.0 International License.