當 MySQL/InnoDB 緩衝池大小較小並且執行大型事務導致緩衝池溢出時會發生什麼?
假設我們有一個執行 50,000 次插入的事務,它弄髒了大約 600 MB 的數據庫。如果緩衝池大小為 128 MB,則在事務執行時緩衝池中將存在臟頁,需要將這些臟頁逐出以騰出空間。我的問題是,MySQL/InnoDB 對這些臟的未送出頁面做了什麼?
5天前我剛遇到一個問題:InnoDB錯誤和MyISAM數據庫崩潰?
在實時聊天會話中對問題進行故障排除時,我發現臨時 InnoDB 表中的髒頁佔用了 InnoDB 緩衝池。文件 ibtmp 為 482MB,其中 75% 的緩衝池是臟的,因為innodb_max_dirty_pages_pct為 75。緩衝池只有 128M。那麼,會發生什麼?
當緩衝池太小時(這是我遇到的一個幾乎空的數據庫)時,緩衝池必須非常頻繁地刷新。
如果你執行
SHOW GLOBAL STATUS LIKE 'innodb_buffer_pool%';
,你會看到類似這樣的東西:mysql> SHOW GLOBAL STATUS LIKE 'innodb_buffer_pool%'; +---------------------------------------+--------------------------------------------------+ | Variable_name | Value | +---------------------------------------+--------------------------------------------------+ | Innodb_buffer_pool_dump_status | Dumping of buffer pool not started | | Innodb_buffer_pool_load_status | Buffer pool(s) load completed at 190925 9:50:58 | | Innodb_buffer_pool_resize_status | | | Innodb_buffer_pool_pages_data | 247 | | Innodb_buffer_pool_bytes_data | 4046848 | | Innodb_buffer_pool_pages_dirty | 0 | | Innodb_buffer_pool_bytes_dirty | 0 | | Innodb_buffer_pool_pages_flushed | 36 | | Innodb_buffer_pool_pages_free | 7945 | | Innodb_buffer_pool_pages_misc | 0 | | Innodb_buffer_pool_pages_total | 8192 | | Innodb_buffer_pool_read_ahead_rnd | 0 | | Innodb_buffer_pool_read_ahead | 0 | | Innodb_buffer_pool_read_ahead_evicted | 0 | | Innodb_buffer_pool_read_requests | 1090 | | Innodb_buffer_pool_reads | 214 | | Innodb_buffer_pool_wait_free | 0 | | Innodb_buffer_pool_write_requests | 325 | +---------------------------------------+--------------------------------------------------+ 18 rows in set (0.01 sec) mysql>
您可以
Innodb_buffer_pool_pages_dirty
使用mysql> SHOW GLOBAL STATUS LIKE 'innodb_buffer_pool_pages_dirty%'; +--------------------------------+-------+ | Variable_name | Value | +--------------------------------+-------+ | Innodb_buffer_pool_pages_dirty | 0 | +--------------------------------+-------+ 1 row in set (0.00 sec) mysql>
這個數字可能會隨著頁面被刷新和頁面進入而波動,但這肯定會阻礙 InnoDB。您的解決方案只是增加緩衝池的大小。
我之前談到過其他不良影響(請參閱我的文章,當 InnoDB 日誌空間太小時會發生什麼情況)
我想我見過這樣的案例
- buffer_pool 設置得非常低(遠小於 128M)
- 交易很複雜,不僅僅是“大”。
- 錯誤表明 buffer_pool 空間不足(或類似情況)。您正在檢查錯誤,是嗎?
“大”不是問題——InnoDB 被設計用來處理任意多的行
ROLLBACK
,等等。但它必須更加努力——在完成查詢之前刷新臟頁,在表中儲存撤消的東西,而不僅僅是撤消日誌等“複雜”可能是一個問題——假設它需要在幾個表及其索引的幾個 BTree 中鎖定很多塊。
我認為我沒有看到 128M 遇到麻煩(除了速度很慢)。我認為以前的預設值(8M)確實造成了麻煩。那是在 MyISAM 為王的時代,而 InnoDB 是新的羽翼未豐。
把它想像成一頓 5 道菜的大餐。廚房可以一次準備一道菜。但是,如果您要求同時傳遞所有 5 個呢?