MySQL RDS:刪除以前的巨大表而不凍結數據庫?
我在 AWS RDS 中使用 MySQL 5.6。我想刪除一個曾經有 80 億行的表。
聽說刪除大表會凍結數據庫,我選擇使用循環刪除行。這花了幾天時間,但桌子現在是空的。RDS 在刪除期間使用了 95%(或更多)的 CPU,但它似乎並沒有減慢正常使用速度。
現在看來,我可以繼續放下空桌子,但我想我擔心無論什麼……東西……緩衝區?……日誌?……可能仍然存在並且可能導致問題。
這是任何環境(雲、VMWare、裸機)中的經典問題
你需要做的你已經在做:刪除表中的行,但你需要刪除所有的行。為什麼 ???
InnoDB 緩衝池中的數據和索引頁面(每個 16K)攜帶對它們來自的表的表空間 ID 引用。當您刪除 InnoDB 表時,是否會檢查數據和索引頁面以查看它們是否在 InnoDB 緩衝池中並且是最新的。這些頁面必須在 InnoDB 緩衝池中失效,如果它們在那裡。正如您已經推測的那樣,這可能需要時間。
刪除所有 80 億行後,刪除表應該更快。
您已經對此進行了盡職調查。
接下來做什麼 ???
建議 #1:截斷表格
TRUNCATE TABLE mygianttable;
建議#2:讓桌子成為黑洞
ALTER TABLE mygianttable ENGINE=BLACKHOLE; DROP TABLE mygianttable;
建議#3:用空的 InnoDB 緩衝池重新啟動 MySQL,並刪除表
- 轉到數據庫參數
- 將 innodb_buffer_pool_dump_at_shutdown 設置為 OFF
- 將 innodb_buffer_pool_load_at_startup 設置為 OFF
- 重啟 RDS 實例(從空緩衝池開始)
- 放下桌子
- 將 innodb_buffer_pool_dump_at_shutdown 設置為 OriginalValue
- 將 innodb_buffer_pool_load_at_startup 設置為 OriginalValue
試試看 !!!
確實,InnoDB 緩衝池可能仍然包含您要刪除的表的頁面。當您刪除一個表時,MySQL 在掃描與該表關聯的頁面時傾向於“鎖定”緩衝池。您的緩衝池越大,此掃描所需的時間就越長。RAM 很快,但不是無限快。
但是在您的查詢停止使用該表中的數據後,隨著時間的推移,與該表關聯的緩衝池中的頁面將被其他查詢活動替換為從其他表中請求頁面。這是一個漸進的過程。
我在過去的工作中所做的是,當我想刪除一個大表時,我
RENAME TABLE
將表移動到另一個模式,應用程序對此沒有權限。這可確保用於訪問此表的任何應用程序都無法找到它。然後等待一段時間,讓緩衝池逐漸逐出該表 ID 的頁面。
我們使用了 7 天的延遲,然後自動作業將每天檢查一次並刪除該“掛起的刪除”模式中的所有表。
到那時,我們假設緩衝池已經回收了該表的所有頁面,然後將其刪除會很快。
7天夠嗎?是不是太長了?這取決於很多因素,比如表有多大,該表有多少佔用緩衝池中的頁面,其他查詢導致空閒頁面被驅逐的速度等。沒有一個好的預測方法確切需要多長時間。