.MYD/.MYI/.frm 即可。innodb_file_per_table=1(獨立表空間),否則無法單表恢復。.frm(結構)與 .ibd(資料/索引)檔案。CREATE DATABASE recover_db;
USE recover_db;
CREATE TABLE `target_table` (`id` BIGINT(20)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
.frm 覆蓋新建的 .frm。my.cnf 加入 innodb_force_recovery=1(若失敗嘗試 2~6),啟動 MySQL。SHOW CREATE TABLE target_table; 取得完整建表 SQL。innodb_force_recovery,重新啟動。ALTER TABLE target_table DISCARD TABLESPACE; 丟棄新表的 .ibd,使 .frm 與 .ibd 分離。.ibd 複製到資料目錄下。ALTER TABLE target_table IMPORT TABLESPACE; 會報錯:
ERROR 1030 (HY000): Got error -1 from storage engine
InnoDB: Error: tablespace id in file './target_table.ibd' is 112,
but in the InnoDB data dictionary it is 1.
舊表 Tablespace ID=112,新表僅建立一次 ID=1。
DELIMITER //
CREATE PROCEDURE inc_tablespace()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= 111 DO
SET @s = CONCAT('CREATE TABLE tmp_', i, ' (id INT) ENGINE=InnoDB');
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET i = i + 1;
END WHILE;
END//
DELIMITER ;
CALL inc_tablespace();
DROP PROCEDURE inc_tablespace;
DISCARD TABLESPACE、複製原 .ibd、IMPORT TABLESPACE,此次應成功。innodb_force_recovery=1~6 直到可讀取,隨即 mysqldump 導出。for i in $(seq 0 111); do
mysql -uroot -P3306 -h127.0.0.1 -Drecover_db \
-e "CREATE TABLE shard_$i (id BIGINT(20) PRIMARY KEY) ENGINE=InnoDB";
done
for i in $(seq 0 111); do
mysql -uroot -P3306 -h127.0.0.1 -Drecover_db \
-e "ALTER TABLE shard_$i DISCARD TABLESPACE";
done
# 複製備份的 .ibd 至 recover_db 目錄(注意檔案權限 chown mysql:mysql)
for i in $(seq 0 111); do
mysql -uroot -P3306 -h127.0.0.1 -Drecover_db \
-e "ALTER TABLE shard_$i IMPORT TABLESPACE";
done