天天看點

bug#66718 Assert from DROP TABLE concurrent with ibuf merges

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