mysql测试环境问题定位

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yinbucheng/article/details/89913817

问题:

mysql测试环境出现insert阻塞很长时间

猜想:

出现insert很长主要有两个方面

1.插入被其他锁阻塞了(这里能导致阻塞的只有在可重复读隔离级别下的间隙锁导致的)

2.mysql在某一段时间内进行刷脏页

验证:

因为锁阻塞需要业务人去优化自己的代码比如更新使用索引防止伪锁表,这里我采用将隔离级别修改为读提交,在读提交下面是没有间隙锁的,所有一般不好出现阻塞插入。除非用户进行修改表结构这里的锁的MDL

验证刷脏页时需要先解释几个概念: wal,redo log, write position , checkpoint  ,lsn

wal(write ahead log)也就是修改提供数据先写日志,这里写日志是写redo log,mysql的更新插入一般都是很快的,原因就是将原来的随机写转变为顺序写。也就是提交事务后数据没有真正的将磁盘中的数据修改而是记录再redo log中

redo log 就为提高mysql的写性能将随机写转变为顺序写

write position: 它是redo log中当前写数据位点

checkpoint :它用来记录redo log中被刷入到正在数据位置空间的位置

lsn (log sequence number):日志记录的序号

其关系如下图:

绿色部分表示顺序写入的数据(这里包括更新,插入记录)

白色部分表示空闲的空间,这里空闲来源来总情况一种是本来就是空闲的,还一种是checkpoint前移,会将绿色部分变为白色部分。

我们测试环境问题就出现在checkpoint前移导致的。这里checkpoint前移不是简单的指针移动而是会涉及到刷脏页。它会将前移部分中redo log写入到数据所在磁盘上(其实redo log存放只是物理记录日志也就某一页上面所进行的操作,我只是简化说明)

什么时候会出现checkpoint移动了,一种是系统io压力不大有空闲资源  第二种是redo log 已经满了,无法再提供顺序写功能了,对应就是write pos 快要追上checkpoint 了如下图所示

我们也可以通过show engine innodb status \G;查看

第一行中表示,日志在内存中的lsn

第二行中表示,日志在redo 的lsn

最后一行表示,日志在进行checkpoint 的lsn

但last checkpoint at - log flushed up to > log file size就会出现刷脏页

这里是mysql日志打印的信息,我分析慢日志发现insert慢是都是在这些日志输出时间段基本一致。而日志上面已经告诉我们系统进行刷脏页并且系统io压力很大其中红色部分告诉我刷脏页消耗的时间。到这里基本可以确定插入有时慢是系统进行刷脏页。而导致刷脏页原因是redo log 快要满了。

解决上面问题:

1.增加redo log file 大小 (对于压测是没有效果的只能让刷脏页的频率低点,对线上环境可能有用因为比如线上白天数据库压力大但时没有超过redo log file 大小 晚上库基本没压力时系统会悄悄进行刷脏页这样就可以完美避免上面问题)

2.增加page cleaner 线程数量

猜你喜欢

转载自blog.csdn.net/yinbucheng/article/details/89913817