关于锁:第43问锁用得太多-为什么要调整-Buffer-Pool

42次阅读

共计 1197 个字符,预计需要花费 3 分钟才能阅读完成。

当咱们应用一个事务操作很多数据时, 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 的状态:

解释一下 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%

咱们的试验到此结束, 通过此试验咱们晓得:

  1. 如果事务用到了很多锁, 那么锁构造应用的内存是从 Buffer pool 中调配的
  2. Buffer pool 使用率比拟高时, 就会报错: The total number of locks exceeds the lock table size

对于 Buffer pool 应用到多少, 会进行报错, 咱们参考如下 MySQL 源码:

咱们能够看到这个实践阈值是 75%, 当 Buffer pool 中 非数据页的大小超过了 75%, 咱们就会再无奈调配更多的锁.
(试验中测定的 73% 与这个实践阈值相差不大)

小贴士

当 Buffer pool 的大小有余时, Buffer pool 能够回收数据页 (洁净页可间接回收, 脏页可刷脏后回收), 而不能间接回收 非数据页.

MySQL 设定这个 75% 的阈值, 也是为了让 Buffer pool 中留一部分空间给数据页, 毕竟 Buffer pool 的最大作用是给数据页做缓存.


对于 MySQL 的技术内容,你们还有什么想晓得的吗?连忙留言通知小编吧!

正文完
 0