近期遇到一個詭異的 MySQL 問題:對同一張 MyISAM 表執行 SELECT * 返回 4 條記錄,而 SELECT uid 僅返回 3 條,少了一條 uid='uid_3' 的數據。經同事提醒使用 CHECK TABLE 後,發現索引文件(.MYI)與數據文件(.MYD)不一致,導致索引損壞。
mysql> SELECT * FROM table_myisam;
+----------+-------+-----------+------+
| datetime | uid | content | type |
+----------+-------+-----------+------+
| 1 | uid_1 | content_1 | 1 |
| 2 | uid_2 | content_2 | 1 |
| 4 | uid_4 | content_4 | 1 |
| 3 | uid_3 | content_3 | 1 |
+----------+-------+-----------+------+
4 rows in set (0.00 sec)
mysql> SELECT uid FROM table_myisam;
+-------+
| uid |
+-------+
| uid_1 |
| uid_2 |
| uid_4 |
+-------+
3 rows in set (0.00 sec)
執行 CHECK TABLE table_myisam 後輸出關鍵錯誤:
| qitai.table_myisam | check | error | Found 3 keys of 4 |
| qitai.table_myisam | check | error | Corrupt |
核心原因:MyISAM 表的索引文件損壞,導致索引條目(3 個)少於實際數據行(4 個)。
SELECT * 採用全表掃描,按數據文件鏈表順序讀取,不依賴索引,故能讀出全部 4 行。SELECT uid 需遍歷索引樹,因索引僅存 3 條記錄,故丟失 uid_3。mysql> REPAIR TABLE table_myisam;
+--------------------+--------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+--------------------+--------+----------+----------+
| qitai.table_myisam | repair | status | OK |
+--------------------+--------+----------+----------+
修復後再次 CHECK TABLE 顯示 status OK,雙查詢均返回 4 條記錄,問題徹底解決。
CHECK TABLE 巡檢。REPAIR TABLE 驗證步驟,確保備份可用性。