MySQL为什么会卡一下
InnoDB在处理更新操作时,它并不会直接把数据直接写入磁盘,而是先在内存找到对应的数据页做修改,之后把修改写入redo log,然后这一次更新操作就算完成了。(这里也存在数据页不在内存的情况,那么它会直接将数据修改的操作写入change buffer,然后记录redo log)。
这些被修改过的数据页,或者说内存中的数据页与磁盘中的数据页不一样的,就叫做脏页。而MySQL卡的那一下,就是把脏页写回内存时发生的。
写回脏页的时机
1、redo log满了
redo log是一个循环队列,当它写满时,系统会停止当前的操作,把redo log中记录的一部分操作所对应的脏页写回内存,然后在redo log中腾出足够的地方。

2、内存满了
在这种情况下,内存里无法加载更多的内存页,需要淘汰掉一部分内存页,而淘汰掉的内存页如果有脏页,就会把他们写入磁盘。
3、MySQL空闲时
4、MySQL正常关闭的情况。
情况1和2对性能的影响
情况1是需要避免的,因为发生这种情况后,整个系统就无法处理新的请求。
情况2是一种常态,InnoDB用缓冲池(buffer pool)管理内存,缓冲池中的内存页有三种状态:
- 第一种是,还没有使用的;
- 第二种是,使用了并且是干净页;
- 第三种是,使用了并且是脏页。
而当要读入的数据页没有在内存的时候,就必须到缓冲池中申请一个数据页。这时候只能把最久不使用的数据页从内存中淘汰掉:如果要淘汰的是一个干净页,就直接释放出来复用;但如果是脏页呢,就必须将脏页先刷到磁盘,变成干净页后才能复用。
如果一个查询要淘汰的数据页太多,那么就会很明显的影响性能。
参考
《MySQL45讲》