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)相關,後續會對這個子產品的代碼做分析