MySQL有壞快后drop表就crash了的解決方案
MySQL 內(nèi)部的處理機(jī)制和磁盤壞塊導(dǎo)致的異常行為。
為什么直接 DROP 會(huì)導(dǎo)致 MySQL 自動(dòng)重啟?
原因:文件系統(tǒng)或磁盤壞塊導(dǎo)致的崩潰
DROP TABLE 會(huì)觸發(fā)物理文件刪除:
- DROP 會(huì)直接嘗試刪除
.ibd(獨(dú)立表空間)或表在共享表空間中的元數(shù)據(jù)和數(shù)據(jù)頁(yè)。 - 如果這個(gè)物理文件所在磁盤存在壞塊(bad sector),系統(tǒng)級(jí)
unlink()操作(刪除文件)可能觸發(fā)內(nèi)核級(jí) I/O 錯(cuò)誤。
InnoDB 崩潰保護(hù)機(jī)制觸發(fā):
- InnoDB 遇到不能處理的 I/O 錯(cuò)誤時(shí)(如文件系統(tǒng)異常),為了保護(hù)數(shù)據(jù)完整性,會(huì)觸發(fā) crash recovery,即讓 MySQL 實(shí)例自動(dòng)崩潰、重啟,以避免進(jìn)一步破壞數(shù)據(jù)頁(yè)或 redo log。
為什么先 TRUNCATE 再 DROP 可以?
TRUNCATE 是邏輯操作,不會(huì)立即刪除物理文件,而是清空數(shù)據(jù)并重置表的結(jié)構(gòu)。
TRUNCATE 做了什么?
- InnoDB 通過撤銷表空間的數(shù)據(jù)元信息,將表置空;
- 這個(gè)過程可能并不會(huì)立即訪問壞塊處的
.ibd文件內(nèi)容或不觸發(fā) I/O 操作。
隨后 DROP 才真正刪除表結(jié)構(gòu)和 .ibd 文件;
- 此時(shí)因?yàn)?TRUNCATE 操作可能“清理”了一些元數(shù)據(jù)或觸發(fā)了延遲刪除,使得系統(tǒng)避開了立即接觸壞塊,從而成功執(zhí)行 DROP。
如何處理該類問題?
方法一:“溫和繞過法”
執(zhí)行:
TRUNCATE TABLE your_table; DROP TABLE your_table;
- 讓文件內(nèi)容清空后再 DROP,降低觸發(fā)底層 I/O 錯(cuò)誤的概率。
方法二:修改表空間定義,繞過壞塊
如果你使用的是 innodb_file_per_table=1,可以嘗試:
先 RENAME 表到一個(gè)臨時(shí)名字
RENAME TABLE your_table TO temp_table;
避免 DROP 時(shí)直接訪問原路徑,可嘗試刪除 .ibd 文件前先 detach(需要慎用)
方法三:使用操作系統(tǒng)級(jí)工具手動(dòng)處理壞塊
如果問題持續(xù),可使用:
smartctl/badblocks檢查磁盤健康;- 嘗試用
dd命令強(qiáng)制讀取并隔離壞塊(高危操作); - 考慮在掛載磁盤時(shí)使用
errors=continue之類選項(xiàng)(不推薦生產(chǎn)使用);
方法四:使用 ibd 文件方式強(qiáng)制剝離表
如果你能接受丟棄該表:
- 停止 MySQL;
- 手動(dòng)刪除表對(duì)應(yīng)的
.ibd文件; - 啟動(dòng) MySQL;
DROP TABLE your_table;(不會(huì)報(bào)錯(cuò)因?yàn)槲募巡淮嬖冢?/li>
強(qiáng)刪文件前請(qǐng)確保該表無(wú)數(shù)據(jù)可恢復(fù)需求!否則可能影響 InnoDB 一致性!
附加建議
檢查 error.log 中是否出現(xiàn)如下信息:
InnoDB: Operating system error number 5 in a file operation. InnoDB: The error means MySQL doesn't have the access rights to the directory.
或
InnoDB: IO error 5 writing page ...
這些都能進(jìn)一步驗(yàn)證是 I/O 層問題導(dǎo)致重啟。
結(jié)論總結(jié)
| 操作 | 是否訪問磁盤壞塊 | 是否高危 | 是否推薦 |
|---|---|---|---|
| DROP | 是(高概率) | ?高危 | ?若磁盤有壞塊 |
| TRUNCATE | 通常不會(huì) | ?較安全 | ?推薦先做 |
| TRUNCATE + DROP | ?可能成功規(guī)避 | ?中等風(fēng)險(xiǎn) | ?推薦 |
| 手動(dòng)刪除 .ibd | ?系統(tǒng)級(jí)操作 | ??高危 | ?需慎用 |
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- MySQL表數(shù)據(jù)文件損壞導(dǎo)致數(shù)據(jù)庫(kù)無(wú)法啟動(dòng)的原因與解決方案
- 解決MySQL數(shù)據(jù)庫(kù)意外崩潰導(dǎo)致表數(shù)據(jù)文件損壞無(wú)法啟動(dòng)的問題
- Mysql存儲(chǔ)引擎MyISAM的常見問題(表?yè)p壞、無(wú)法訪問、磁盤空間不足)
- shell腳本自動(dòng)修復(fù)mysql損壞的表
- MySQL數(shù)據(jù)庫(kù)INNODB表?yè)p壞修復(fù)處理過程分享
- 一次非法關(guān)機(jī)導(dǎo)致mysql數(shù)據(jù)表?yè)p壞的實(shí)例解決
- MYSQL數(shù)據(jù)表?yè)p壞的原因分析和修復(fù)方法小結(jié)(推薦)
- MySQL數(shù)據(jù)表?yè)p壞的正確修復(fù)方案
- Mysql 壞表修復(fù)的幾種解決方案
相關(guān)文章
MySQL高并發(fā)生成唯一訂單號(hào)的方法實(shí)現(xiàn)
這篇文章主要介紹了MySQL高并發(fā)生成唯一訂單號(hào)的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
關(guān)于MySQL的存儲(chǔ)函數(shù)(自定義函數(shù))的定義和使用方法詳解
本文主要講解了關(guān)于MySQL的存儲(chǔ)函數(shù)(自定義函數(shù))的定義和使用方法詳解與存儲(chǔ)函數(shù)與存儲(chǔ)過程的區(qū)別2018-03-03

