Author: dingqi.lxb
一个用户自建MySQL,出现备库复制中断的问题,报错为slave sql thread 错误,The total number of locks exceeds the lock table size。
这个报错在代码中的抛错逻辑为:
if UT_LIST_GET_LEN(buf_pool->free) + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 4
文字解释是:如果buffer pool中的空闲页面和LRU页面总和少于buffer pool 大小的1/4,则认为内存不够用,报错。
buffer pool 哪里去了 buffer pool是InnoDB内部管理内存的统一结构。默认每个page 16k。初始化后,每个page都是空闲状态,放在free中。 当读取数据等需要用到页面数据的操作时,将数据从磁盘读取到内存中,用的就是buffer pool的page。为了支持淘汰机制,InnoDB内部维护了一个淘汰链表,就是LRU list。装了数据的page被从free list移到LRU list。 但是,除了正常的读取数据,还有其他的逻辑需要从buffer pool中“抢”资源。比如本例中是因为undo page。 事务越大,需要的undo page越多,在整个事务未提交前,undo page是必须强占内存的。这就可能导致一种情况:事务过大,导致buffer pool全部被用光,无法提供正常服务。 因此InnoDB有了上面的保护机制。触发这个上限后报错后,事务会回滚,释放undo page。