溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

InnoDB Insert Buffer: unable to purge a record

發(fā)布時間:2020-08-13 04:46:41 來源:ITPUB博客 閱讀:144 作者:G8bao7 欄目:MySQL數(shù)據(jù)庫
轉(zhuǎn)載: http://mysqllover.com/?p=1264
參考: InnoDB Insert Buffer實現(xiàn)詳解 http://hedengcheng.com/?p=94

MySQL5.6.23: fix “UNABLE TO PURGE A RECORD”

本文簡述下之前我們線上頻繁碰到的“UNABLE TO PURGE A RECORD”的原因

###################################################

線上實例錯誤日志中偶爾出現(xiàn) “UNABLE TO PURGE A RECORD”,從官方bug系統(tǒng)來看,很多用戶都遇到了類似的問題。

當(dāng)change buffer模塊以如下序列來緩存索引操作時:

  1. 記錄被標(biāo)記刪除(IBUF_OP_DELETE_MARK)
  2. 隨后插入相同記錄–IBUF_OP_INSERT
  3. Purge線程需要物理刪除二級索引記錄,操作被buffer–IBUF_OP_DELETE

 

當(dāng)讀入物理頁時,需要進(jìn)行ibuf merge,當(dāng)執(zhí)行到IBUF_OP_DELETE時,發(fā)現(xiàn)記錄并沒有被標(biāo)記刪除,導(dǎo)致錯誤日志報錯。

 

顯然上述的操作序列是不合理的,正確的序列應(yīng)該是IBUF_OP_DELETE_MARK,IBUF_OP_DELETE,IBUF_OP_INSERT。

 

為了理清邏輯,我們簡單的理一下相關(guān)代碼

 

注意IBUF_OP_DELETE是由第一步的標(biāo)記刪除操作觸發(fā),Purge線程發(fā)起;在每個buffer pool的控制結(jié)構(gòu)體中,有一個成員buf_pool->watch[BUF_POOL_WATCH_SIZE],BUF_POOL_WATCH_SIZE的值為purge線程個數(shù),用于輔助Purge操作。

 

假定內(nèi)存中沒有對應(yīng)的Page,Purge線程會做如下幾件事兒:

  • 首先查詢buffer pool,看看page是否已經(jīng)讀入內(nèi)存;

如果不在內(nèi)存中,則將page no等信息存儲到watch數(shù)組中,并插入page hash(buf_pool_watch_set)。如果隨后page被讀入內(nèi)存,就會刪除watch標(biāo)記。

  • 判斷該二級索引記錄是否可以被Purge(row_purge_poss_sec,當(dāng)該二級索引記錄對應(yīng)的聚集索引記錄沒有delete mark并且其trx id比當(dāng)前的purge view還舊時,不可以做Purge操作)

 

  • 隨后,再插入IBUF_OP_DELETE類型的ibuf記錄時,還會double check下該page是否被設(shè)為sentinel (ibuf_insert_low,buf_pool_watch_occurred),如果未被設(shè)置,表明已經(jīng)page已經(jīng)讀入內(nèi)存,就可以直接去做purge,而無需緩存了。

 

  • 對于普通的操作類型,例如IBUF_OP_INSERT和IBUF_OP_DELETE_MARK,同樣也會double check page 是否讀入了內(nèi)存。在函數(shù)ibuf_insert中會調(diào)用buf_page_hash_get進(jìn)行檢查, 如果page被讀入內(nèi)存,則不緩存操作,如果請求的Page被設(shè)為sentinel,則從buf_page_hash_get返回NULL,因此隨后判定需要緩存操作。這也正是問題的所在:
  1. 標(biāo)記刪除記錄,寫入IBUF_OP_DELETE_MARK
  2. Purge線程設(shè)置page對應(yīng)的sentinel,完成合法性檢查,準(zhǔn)備調(diào)用ibuf_insert
  3. 插入相同記錄,寫入IBUF_OP_INSERT
  4. Purge線程寫入IBUF_OP_DELETE

解決

如果記錄所在的page被設(shè)置了一個sentinel,那么對該page的并發(fā)插入操作就不應(yīng)該緩存到change buffer中,而是直接去嘗試讀取物理頁。

https://github.com/mysql/mysql-server/commit/ec369cb4f363161dfbbbd662b20763b54808b7d1

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI