http://bugs.mysql.com/bug.php?id=66718
assert from drop table concurrent with ibuf merges
a.原因:
master线程发起的ibuf merge和用户线程的drop table操作可能存在竞争。
1.master线程请求文件page io,读入内存之前,会调用buf_page_init_for_read->fil_tablespace_deleted_or_being_deleted_in_mem
如果这时候该表尚未标记为删除,那么则认为可以继续读文件page。
2.用户线程调用fil_delete_tablespace
>设置space->stop_ibuf_merges = true
>确认space->n_pending_ibuf_merges == 0
设置space->is_being_deleted = true;
>确认space->chain->n_pending为0 并且 space->n_pending_flushes = 0
继续下面的逻辑
3.master线程继续调用函数fil_io -> fil_node_prepare_for_io会递增node->n_pending++
4.用户线程继续往下走,调用
fil_delete_tablespace->fil_space_free->fil_node_free
在这里会做断言:
ut_a(node->n_pending == 0);
不过在percona版本中,断言处就不太一样,而是:
ut_a(node->n_pending == 0 || space->is_being_deleted);
因为在free node之前,我们已经设置了space->is_being_deleted为true,因此不会触发断言错误。
b.总结:
根据bug描述及分析,这个bug不影响我们的线上mysql版本。
c.其他:
我们已经确保space->n_pending_ibuf_merges为0了,为什么还会有对该表的ibuf merge呢?
对n_pending_ibuf_merges计数器操作的函数:fil_inc_pending_ibuf_merges及fil_decr_pending_ibuf_merges
我们来看看,在何时会递增这个计数器。
ibuf_merge_or_delete_for_page //每次读入一个索引页时,都会去尝试merge这个索引页上在内存中缓存的操作,如果该page上没有ibuf,或者表正在被删除,则不修改计数器,否则对计数+1,当执行完相关流程后,再调用fil_decr_pending_ibuf_merges进行-1.
计数器只在函数ibuf_merge_or_delete_for_page中做了修改。
请求文件页操作在调用ibuf_merge_or_delete_for_page之前,由master线程发起(用户线程无法和ddl并发)
d.todo
除了这个bug。另外一个去年春节发生,年底才fix的bug,也需要去跟踪(http://bugs.mysql.com/bug.php?id=66819)
这些都和insert buffer(或者称为change buffer)相关,后续会对这个模块的代码做分析