-- 一條 SQL 刪 3 個月前數據,可能涉及百萬行 DELETE FROM messages WHERE dt < DATE_SUB(NOW(), INTERVAL 3 MONTH);
#!/bin/bash
# 刪除腳本:每次 1 萬行,間隔 0.5 秒
rows_affected=1
while [ $rows_affected -gt 0 ]; do
rows_affected=$(mysql -h localhost -u root -p'xxx' db_name -N -e \
"DELETE FROM messages WHERE dt < DATE_SUB(NOW(), INTERVAL 3 MONTH) LIMIT 10000")
sleep 0.5
done
| 參數 | 建議值 | 影響 |
|---|---|---|
| 單批次行數 | 5000-20000 | 太小→循環開銷大;太大→鎖表時間長 |
| 間隔睡眠 | 0.1-1 秒 | 釋放鎖、讓業務插隊、緩解主從壓力 |
| WHERE 條件 | 固定時間點/主鍵範圍 | 避免函數導致索引失效,確保每批掃描範圍遞減 |
-- 先查出需刪除的 ID 範圍 SELECT MIN(id), MAX(id) FROM messages WHERE dt < '2024-01-01'; -- 假設 10000 ~ 5000000 -- 分批按主鍵刪除(利用聚簇索引順序讀取,極快) DELETE FROM messages WHERE id BETWEEN 10000 AND 20000 AND dt < '2024-01-01' LIMIT 10000; -- 循環遞增 id 範圍...
pt-online-schema-change 內部即採用分塊拷貝 + 觸發器同步Innodb_row_lock_time_avg、Seconds_Behind_Master、Threads_running**大查詢切分 = 小批次 + 間隔睡眠 + 固定範圍**。將「一次性核彈」拆解為「持續精準打擊」,線上業務零感知,主從同步平穩,運維從容不迫。建議封裝為通用工具 batch_delete.sh,納入運維標準庫。