第43问(锁用得太多, 为什么要调整 Buffer Pool)
文章图片
问
当我们使用一个事务操作很多数据时, MySQL 有时会报错: The total number of locks exceeds the lock table size
根据官方文档, 我们需要调大 buffer pool 的大小:
文章图片
本期实验, 我们来探索一下锁用得多与 buffer pool 大小的关系
实验
我们用老方法建一个数据库, 并将 buffer pool 大小调整到了最小值5M, 方便我们复现问题
文章图片
现在来模拟一个用锁特别多的事务:
文章图片
我们还是用老方法让表翻倍, 来不停地占用锁.
看一下效果:
文章图片
我们可以通过 information_schema.INNODB_TRX 来查看事务使用了多少锁, 解释一下上图中标记的这几个状态:
- trx_tables_locked: 该事务锁了几张表
- trx_rows_locked: 该事务锁了多少数据行
- trx_lock_structs: 该事务一共用到了多少个锁结构.一个锁结构用于锁住多个表或多个行
- trx_lock_memory_bytes: 该事务的锁结构一共用了多少内存
文章图片
解释一下 Buffer pool 的这两个状态:
- total 是 Buffer pool 的总页数
- misc 是 Buffer pool 中非数据页的页数
文章图片
与最初的状态相比, 该事务使用的锁的内存增长了 (1269968 - 24784 = ) 1245184 字节 = 1216 k, 而 buffer pool 非数据页多使用了 (84-8 = ) 76页, 每页16k, 总共 1216 k
也就是说, 该事务的锁内存均分自 buffer pool .
我们继续造数据, 造到报错为止, 不停查看状态:
文章图片
文章图片
可以看到, 发生报错时, 事务会回滚. 回滚前, 该事务的锁占用的内存大小是 3842256 字节, 也就是 ( 3842256 / 1024 / 16 = ) 234.5 页, 此时 buffer pool 使用率大概是 ( 234.5 / 320 = ) 73%
我们的实验到此结束, 通过此实验我们知道:
- 如果事务用到了很多锁, 那么锁结构使用的内存是从 Buffer pool 中分配的
- Buffer pool 使用率比较高时, 就会报错: The total number of locks exceeds the lock table size
文章图片
我们可以看到这个理论阈值是75%, 当 Buffer pool 中 非数据页的大小超过了75%, 我们就会再无法分配更多的锁.
(实验中测定的73%与这个理论阈值相差不大)
关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!小贴士
当 Buffer pool 的大小不足时, Buffer pool 可以回收数据页 (干净页可直接回收, 脏页可刷脏后回收), 而不能直接回收 非数据页.
MySQL 设定这个75%的阈值, 也是为了让 Buffer pool 中留一部分空间给数据页, 毕竟 Buffer pool 的最大作用是给数据页做缓存.
【第43问(锁用得太多, 为什么要调整 Buffer Pool)】
文章图片
推荐阅读
- 热闹中的孤独
- 第6.2章(设置属性)
- parallels|parallels desktop 解决网络初始化失败问题
- 2018-02-06第三天|2018-02-06第三天 不能再了,反思到位就差改变
- 第三节|第三节 快乐和幸福(12)
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- android第三方框架(五)ButterKnife
- 开学第一天(下)
- 野营记-第五章|野营记-第五章 讨伐梦魇兽
- 进必趋|进必趋 退必迟,问起对 视勿移