無法刪除孤立的 InnoDB 臨時表 - 缺少 .frm 文件
我第二次遇到了一個問題,我們的 MySQL 伺服器(MariaDB v10.1)突然拋出錯誤 - 無法刪除臨時表:’./database_name/#sql-4593_791’,錯誤:120。
遵循https://mariadb.com/resources/blog/get-rid-of-orphaned-innodb-temporary-tables-the-right-way/之類的指南不起作用,我仍然收到表不是的錯誤已知 (
ERROR 1051 (42S02): Unknown table 'database_name.#mysql50#sql-4593_1e9'
)這個問題與刪除孤立 InnoDB 臨時表的其他問題的不同之處在於,數據庫伺服器似乎已經從磁碟和記憶體中刪除了 .frm 文件(執行
lsof | grep sql-4593_1e9
僅顯示 .ibd 文件打開)這會是問題的根源嗎?如果是這樣,有沒有辦法重新創建一個幾乎無法訪問的未知結構表的 .frm 文件?
我可以在數據庫本身中唯一提到它的是執行:
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql%';
輸出以下內容:
+----------+-----------------------------+------+--------+---------+-------------+------------+---------------+ | TABLE_ID | NAME | FLAG | N_COLS | SPACE | FILE_FORMAT | ROW_FORMAT | ZIP_PAGE_SIZE | +----------+-----------------------------+------+--------+---------+-------------+------------+---------------+ | 1576128 | database_name/#sql-4593_1e9 | 1 | 118 | 1576114 | Antelope | Compact | 0 | | 1576129 | database_name/#sql-4593_78d | 1 | 118 | 1576115 | Antelope | Compact | 0 | | 1576130 | database_name/#sql-4593_791 | 1 | 118 | 1576116 | Antelope | Compact | 0 | +----------+-----------------------------+------+--------+---------+-------------+------------+---------------+
我不喜歡手動從磁碟中刪除數據庫文件,因為我不完全確定這不會導致問題。即使表空間 id 衝突的可能性幾乎為零。
您在磁碟上的內容與索引內部數據字典中的內容之間存在脫節。MySQL 8.0 改進了數據字典的處理方式,但 mariadb 到 10.4 還沒有實現它。
您不能直接刪除它,因為它不會在磁碟上找到,但 innodb 仍然可以看到它。對於舊版本的 MySQL 和 MariaDB,您會在網上找到一些關於如何同步數據字典和磁碟的指南。但是,這是我發現更有效和更安全的方式:
- 創建一個臨時數據庫並將所有“好”表、視圖等從原始表移動到新表(這非常快,因為它只是 a
rename table
,只要新數據庫在同一個分區上)- 刪除現在為空的數據庫(因此 innodb 索引將刪除其所有剩餘內容。如有必要,也將內容刪除到磁碟上。
- 重新創建舊數據庫,現在 InnoDB 內部字典和數據中完全為空
- 通過重命名將表移回
我已經使用過幾次,我認為這是同步部分刪除表的最簡單、最快和更安全的方法。
重要
#sql-4593_1e9
的是臨時表的格式,除非您認為它們確實是剩餘的,否則請不要刪除它們 - 可能有正在進行的事務需要在內部進行查詢。換句話說,除非它們出現在沒有任何連接的新伺服器上,否則我不會碰它。