首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 刪除 #sql- 開頭臨時表完整方案:雙檔案存在與僅 .ibd 兩種情況

     編輯:MySQL 綜合教學

MySQL 異常中斷產生 #sql- 臨時表殘留,磁碟空間洩漏完整修復指南

執行 ALTER TABLE ... ADD INDEX 等 DDL 期間若 MySQL Crash/重啟,會在資料目錄殘留 #sql-XXXX_XXXX.ibd 和 #sql-XXXX_XXXX.frm 臨時表檔案,佔用大量空間且無法直接 rm 刪除 (資料字典仍記錄)。

情況一:.ibd 與 .frm 皆存在 (標準修復)

# 1. 確認檔案名 (例:#sql-928_76f7)
ls -la /var/lib/mysql/db_name/#sql-*

# 2. 使用特殊前綴 `#mysql50##` 忽略檔案名安全編碼 (MySQL 5.1+ 引入)
mysql> DROP TABLE `#mysql50##sql-928_76f7`;
Query OK, 0 rows affected (16.28 sec)

# 3. 空間即時釋放,驗證
df -h /var/lib/mysql

情況二:僅存在 .ibd 缺少 .frm (進階修復)

  1. 建立同結構臨時表:
    mysql> CREATE DATABASE tmp_repair;
    mysql> CREATE TABLE tmp_repair.tmp LIKE db_name.target_table;  -- 僅複製結構與索引
  2. 複製 .frm 並重命名:
    # Shell 執行
    cp /var/lib/mysql/tmp_repair/tmp.frm /var/lib/mysql/db_name/#sql-928_76f7.frm
  3. 確認雙檔案存在後標準刪除:
    mysql> DROP TABLE `#mysql50##sql-928_76f7`;
  4. 清理臨時庫:
    mysql> DROP DATABASE tmp_repair;

原理解析

  • #mysql50## 前綴告訴 InnoDB 忽略檔案名編碼,直接按字面匹配資料字典條目。
  • 臨時表命名規則:#sql-{thread_id}_{random}。
  • 直接 rm 會導致 InnoDB 資料字典孤兒條目,重啟報錯 Table ... doesn't exist in InnoDB internal data dictionary。

預防與監控

  • 大表 DDL 推薦使用 pt-online-schema-change (Percona Toolkit) 線上變更,避免長時間鎖表與 Crash 風險。
  • 監控資料目錄 #sql-* 檔案,發現立即處理。
  • 定期執行 CHECK TABLE 檢測孤兒表。

參考文檔

MySQL 官方手冊:InnoDB Data Dictionary Troubleshooting

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved