VPS 遷移、磁碟故障、誤操作導致 MySQL 數據目錄 (/var/lib/mysql) 需直接拷貝恢復。本文記錄實戰遇到的三大經典問題及精準解決方案,核心結論:**多備份、備份驗證、邏輯備份 (mysqldump) 優於物理拷貝**。
/var/lib/mysql 目錄。mysql> USE mydb;
mysql> SHOW TABLES;
Empty set (0.00 sec)
mysql> SELECT * FROM users;
ERROR 1146 (42S02): Table 'mydb.users' doesn't exist
排查:ls -l /var/lib/mysql/mydb/ 顯示 .frm/.ibd 文件存在,屬主為 root:root。
根因:MySQL 進程用戶為 mysql,data 目錄屬主為 root,**無權限讀取表文件**,InnoDB 忽略不可讀表,顯示為空。
解決:
chown -R mysql:mysql /var/lib/mysql
# 或精確
chown -R mysql /var/lib/mysql
systemctl restart mysqld
驗證:SHOW TABLES 正常顯示,表可查詢。
mysql> CHECK TABLE users;
+-----------+-------+----------+--------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-----------+-------+----------+--------------------------------------------------+
| mydb.users| check | warning | Table is marked as crashed and last repair failed|
| mydb.users| check | warning | 1 client is using or hasn't closed the table properly |
| mydb.users| check | error | Wrong bytesec: 0-0-0 at linkstart: 32453660 |
+-----------+-------+----------+--------------------------------------------------+
排查:ls -l /var/lib/mysql/mydb/users.* 發現 .MYD/.MYI (MyISAM) 或 .ibd (InnoDB) 屬主仍為 root (上一步僅改了目錄屬主,部分文件因權限保留未遞歸生效,或新建文件繼承錯誤)。
解決:
chown -R mysql:mysql /var/lib/mysql
# 確保遞歸生效
find /var/lib/mysql -not -user mysql -exec chown mysql:mysql {} \;
systemctl restart mysqld
# 再次修復
mysql> REPAIR TABLE users;
+-----------+--------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+-----------+--------+----------+----------+
| mydb.users| repair | status | OK |
+-----------+--------+----------+----------+
mysql> CHECK TABLE bbb;
+-----------+-------+----------+----------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-----------+-------+----------+----------------------------------------+
| mydb.bbb | check | error | Incorrect information in file: './mydb/bbb.frm' |
+-----------+-------+----------+----------------------------------------+
根因:.frm 文件存儲**表結構定義** (欄位、索引、引擎、字元集),損壞導致無法解析表結構。數據文件 (.ibd/.MYD) 可能完好。
解決思路:用**同結構表的 .frm 覆蓋損壞 .frm**。
# 1. 確認同庫/同結構表 (如 ccc 表結構與 bbb 完全一致)
ls -l /var/lib/mysql/mydb/ccc.frm
# 2. 備份損壞文件
mv /var/lib/mysql/mydb/bbb.frm /var/lib/mysql/mydb/bbb.frm.bak
# 3. 複製同結構 .frm 並重命名
cp /var/lib/mysql/mydb/ccc.frm /var/lib/mysql/mydb/bbb.frm
# 4. 重啟驗證 (或 FLUSH TABLES)
systemctl restart mysqld
mysql> CHECK TABLE bbb; -- OK
mysql> SELECT * FROM bbb LIMIT 1; -- 數據可讀
前提條件**:必須有**結構完全相同**的表 (同庫或異庫) 可用。若無,需從備份還原 .frm 或根據業務記憶重建表結構 (CREATE TABLE ... LIKE ...)。
chown -R mysql:mysql /var/lib/mysql。MySQL 數據恢復三部曲:**權限統一 → 表修復 → 結構修復**。但根本出路在於**建立分層備份體系 (邏輯+物理)、自動化驗證、演練恢復 SOP**,而非臨時抱佛腳修復損壞文件。