[Warning] InnoDB: Difficult to Find Free Blocks in the Buffer Pool


MySQL錯誤日志給出警告信息:

[Warning] InnoDB: Difficult to find free blocks in the buffer pool (336 search iterations)! 0 failed attempts to flush a page! Consider increasing the buffer pool size. It is also possible that in your Unix version fsync is very slow, or completely frozen inside the OS kernel. Then upgrading to a newer version of your operating system may help. Look at the number of fsyncs in diagnostic info below. Pending flushes (fsync) log: 0; buffer pool: 0. 1621989850 OS file reads, 1914021664 OS file writes, 110701569 OS fsyncs. Starting InnoDB Monitor to print further diagnostics to the standard output.

2019-10-26T15:02:03.962059Z 4520929 [Warning] InnoDB: Difficult to find free blocks in the buffer pool (337 search iterations)! 0 failed attempts to flush a page! Consider increasing the buffer pool size. It is also possible that in your Unix version fsync is very slow, or completely frozen inside the OS kernel. Then upgrading to a newer version of your operating system may help. Look at the number of fsyncs in diagnostic info below. Pending flushes (fsync) log: 0; buffer pool: 0. 1621989850 OS file reads, 1914021664 OS file writes, 110701569 OS fsyncs. Starting InnoDB Monitor to print further diagnostics to the standard output.

當InnoDB中的線程不斷地請求空閑塊,但無法從buffer pool中獲得空閑塊的時候,就會出現上面的警告消息。實際中,並不是這么簡單,可能還有其他事情發生,懂得如何構建buffer pool中的塊,就可以輕松的明白。

 

buffer pool主要由三個列表組成:

1.free list:空閑列表,線程可以從磁盤讀入數據到列表中的頁

2.lru list:最近最少使用列表

3.flush list:臟的或被修改的頁的列表

 

正如我們所知,每個請求都是有InnoDB中的線程來處理。如果所需的頁在buffer pool中不可用,則必須從磁盤中讀取它並將其放入其中,為此需要從空閑列表(free list)中分配一個空閑塊。空閑塊只能從空閑列表中獲取,所以需要空閑塊的線程會經歷以下的迭代過程:

·從free list中尋找一個空閑的塊,如果有可用就分配它。如果不是,繼續。

·掃描lru列表,如果找到干凈(clean)的塊,就將塊移動到free list中,並分配。如果沒有,繼續。

·從lru列表的尾部刷新臟頁,將其移動到free list,並分配。

這里是簡化的步驟,只是為了便於理解,實際並不是這么簡單,但類似。在任何時刻,如果塊被移動到free list,就可以被任何線程使用,就可能使得當前的線程無法獲取到塊。當前線程就會每間隔10ms執行一次請求。

 

那什么時候會將警告信息寫入日志呢?

 當一個線程執行超過20迭代,就會將警告信息寫入日志。下面是對應的源碼塊:

if (n_iterations > 20 & & srv_buf_pool_old_size == srv_buf_pool_size) {< strong > <= == == == Here it is < / strong >
ib::
    warn(ER_IB_MSG_134) \
    << "Difficult to find free blocks in the buffer pool" \
       " (" \
    << n_iterations << " search iterations)! " << flush_failures \
    << " failed attempts to" \
       " flush a page! Consider increasing the buffer pool" \
       " size. It is also possible that in your Unix version" \
       " fsync is very slow, or completely frozen inside" \
       " the OS kernel. Then upgrading to a newer version" \
       " of your operating system may help. Look at the" \
       " number of fsyncs in diagnostic info below." \
       " Pending flushes (fsync) log: "

  

遇到這種警告,可能是由很多原因造成的,以下的一些清單可以用來確認原因。盡管它已經多次使IO子系統飽和,但它不可能對每個實例和工作負載都相同的。

·IO子系統慢,不能滿足需要及時將頁刷新到磁盤

·page cleaner線程數量不夠

·buffer pool本身太小,從而導致free list和lru list都小

 

常用的解決方法有:

1.增加buffer pool

2.調優、升級IO子系統

3.優化sql,避免全表/全索引掃描


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM