mysql 大表drop和truncate 技術風險點

Mgic_LU發表於2024-12-10

1、用這個drop 語句舉例: drop table T;在之前的老版本中,但如果表T比較大,佔用的各種快取較多,這個SQL在對錶進行刪除的時候,需要依次清理掉buffer pool中的page,時間久回比較久;清理的動作會影響到線上的業務;在老版本的核心中的大致邏輯如下:掃描lru連結串列,如果page屬於T表,就從lru連結串列,hash表, flush list中刪除,回收buffer pool中的block 並標記到free list中,期間會長時間持有buffer pool mutex;清理完成之後free/LRU/flush list Mutex;這種模式稱為直接drop模式;而MySQL 5.5.23以後就採用了lazy drop table的模式(包括社群版的5.6、5.7、 8.0版本以及當前所有polardb-mysql版本):lazy方式: 在移除flush list時,會有一個條件判斷,如果已經處理了超過一定數量的page(預設是1024個page),會強制釋放當前持有的buffer pool mutex和flush list mutex,並且讓出CPU,過一會兒再重新拿回鎖繼續清理flush list;對於LRU list,則不做處理,因為當這個表被刪除後,這些資料頁最終會在LRU演算法排程下被回收。----------------------------------------------------------------
2、對於truncate table操作:在社群版8.0之前的版本中,還是沿用直接drop模式的模式:遍歷lru連結串列,hash表, flush list,並從這些連結串列中清理page,回收buffer pool中的block 並標記到free list中,期間會長時間持有buffer pool mutex;清理完成之後free/LRU/flush list Mutex;在社群版5.6、5.7的mysql版本中,truncate 無法採用類似lazy drop table的核心原因如下:是因為truncate table 需要複用 space id, 這導致必須把buffer pool中的老的表中的頁全部刪除,而drop table因為新舊錶的頁可用透過space id區分,只需要把flush list中的髒頁刪除就可以了;在8.0版本之後,truncate就替換為了用drop+create的方式,這樣解決了truncate 可能會導致大buffer pool夯的問題。注意:在polardb-mysql中,是在5.7.1.0.2版本中,修復了此問題,採用了drop + create的方式來替換原來的truncate邏輯。3、相關版本說明:(1)、社群版mysql相關的bug fix說明:https://bugs.mysql.com/bug.php?id=68184(2)、社群版MySQL8.0針對該問題說明:On a system with a large InnoDB buffer pool and innodb_adaptive_hash_index enabled, TRUNCATE TABLE operations could cause a temporary drop in system performance due to an LRU scan that occurred when removing an InnoDB table's adaptive hash index entries. To address this problem, TRUNCATE TABLE now invokes the same code as DROP TABLE and CREATE TABLE. The problem was addressed for DROP TABLE in MySQL 5.5.23.翻譯:當InnoDB buffer pool比較大和innodb_adaptive_hash_index啟用時,TRUNCATE TABLE操作可能由於發生了LRU掃描,刪除InnoDB表的自適應雜湊索引項時,導致系統效能暫時下降。為了解決這個問題,TRUNCATE TABLE現在呼叫與DROP TABLE相同的程式碼刪除表。因為在MySQL 5.5.23後,DROP TABLE解決了這個問題

相關文章