并发插入场景中,InnoDB中的实际情况如下:

经过测试发现,可能存在因为线程调度问题造成auto_inc差值允许3~4个Page同时插入的情况,初始场景如上图。
- 阶段1:当前有3个线程分别乐观插入到3个不同的level 0 leaf page中,并持有3个leaf page x lock。同时,还有N个线程持有Level 1 page s lock,等待在level 0 leaf page x lock上,即等待当前3个线程完成插入后N个线程再进行插入。
- 阶段2:此时SMO线程进行悲观插入,SMO线程持有index sx lock和Level 2 page x lock,等待在持有Level 1 Page的x lock上,但当前Level 1 page上已经有N个乐观插入线程持有page s lock在等待。
- 阶段3:SMO线程需要等待之前的N个乐观插入线程完成后(最右边Page的乐观插入大概率会失败,因为这次SMO操作就是为了做最右边Page的SMO,那么乐观线程插入失败以后会转换成悲观线程进行插入),获得了Level 1 Page x lock,再等待Level 0 leaf page上的X lock完成加锁操作,然后进行SMO操作。
SMO线程需要等待N个线程完成乐观插入尝试后,才可以进行SMO操作,且并发度越高,乐观插入线程越多。但SMO线程等待的时间越长,SMO操作越不能尽早执行,从而会导致性能无法提升。
那么为什么限制了Innodb_thread_concurrency以后,可以获得更好的性能呢?
从上面的分析可以看出,在auto_inc场景中,并发插入的Page并不多,差不多只有3~4个Page允许同时插入。过多的线程会导致SMO线程必须等待这些乐观线程插入尝试完成以后才能进行插入,乐观插入线程越多,等待的时间就会越长。最理想的情况是此时最右边的Page上没有乐观插入在等待,那么SMO线程就可以不需要等待任何线程,实现了尽早执行SMO操作这个目标。而限制Innodb_thread_concurrency相当于限制了乐观插入线程的数量,因此实现了更好的性能。实际测试中Innodb_thread_concurrency = 8就可以实现几乎最好的性能。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




