mysql中error 1034/1035表明索引损坏:myisam可用repair table quick/extended/use_frm修复,innodb不支持该命令,需通过innodb_force_recovery导出或备份恢复,并注意tmpdir空间、analyze table更新统计信息及全文索引需手动重建。

mysqlCHECK 报 error 1034 或 error 1035 怎么办
这两个错误明确指向索引结构损坏:1034 是“记录与索引不匹配”,1035 是“键文件和数据文件不一致”。别急着删表重建,CHECK TABLE 只是诊断,真正修复靠 REPAIR TABLE,但必须满足前提——存储引擎得支持原地修复。
MyISAM 表可直接修;InnoDB 表不支持 REPAIR TABLE,报错 Storage engine for the table doesn't support repair 是正常现象,强行执行无效。此时应检查 innodb_force_recovery 级别或从备份恢复。
- 运行
CHECK TABLE t1;确认具体错误类型和损坏程度 - MyISAM 表立即跟
REPAIR TABLE t1;(默认使用 QUICK 模式) - InnoDB 表跳过
REPAIR TABLE,改查SHOW ENGINE INNODB STATUS中的 LATEST FOREIGN KEY ERROR 或 CORRUPTION 部分 - 若启用了
innodb_file_per_table=ON,可尝试拷出.ibd文件用innodb_force_recovery=1~6启动后导出数据
REPAIR TABLE 的三种模式怎么选
REPAIR TABLE 默认用 QUICK,只修复索引文件(.MYI),快但不处理数据行损坏;真出问题常得切到 EXTENDED 或 USE_FRM,但代价是锁表时间长、IO 压力大。
-
REPAIR TABLE t1 QUICK;:仅重build索引,适用于error 1034且CHECK显示 “OK” 但查询结果乱序 -
REPAIR TABLE t1 EXTENDED;:逐行校验并重建整个表,适合数据页逻辑错乱,但 MyISAM 表会变慢几倍 -
REPAIR TABLE t1 USE_FRM;:完全丢弃 .MYI,按 .FRM 结构重新生成索引——仅当 .MYI 彻底毁坏且无备份时用,风险高,可能丢失部分索引定义
注意:USE_FRM 不读取原索引数据,所有索引项都重排,如果表有 UNIQUE 约束但数据已重复,修复会失败并报 duplicate entry。
修复失败后看到 Can't create new tempfile 或磁盘满
MyISAM 修复过程会生成临时文件(t1.TMD),默认放在 MySQL 的 tmpdir 目录。如果该目录空间不足或权限不对,修复直接中断,错误里常带 Errcode: 28(no space left)或 Errcode: 13(permission denied)。
- 先查
SELECT @@tmpdir;,确认路径实际可用空间 ≥ 表大小的 2 倍 - 临时换位置:启动 mysqld 时加
--tmpdir=/bigdisk/tmp,或运行前设系统环境变量export TMPDIR=/bigdisk/tmp - 别在 root 分区跑修复,尤其
/tmp通常是内存盘(tmpfs),容量小还易爆 - 修复中若被 kill 或断电,残留的
*.TMD文件要手动清理,否则下次修复可能因文件名冲突失败
修复完为什么查询还是慢或结果不对
修复成功不代表逻辑正确。MyISAM 的 REPAIR 可能跳过无法解析的数据块,留下空洞或截断行;InnoDB 即便用 force_recovery 导出,也可能漏掉未刷盘的事务数据。
- 修复后立刻执行
ANALYZE TABLE t1;更新统计信息,否则优化器仍用旧的索引分布估算,导致执行计划劣化 - 对比修复前后
SELECT COUNT(*)和关键字段COUNT(DISTINCT),检查是否丢数据 - 如果有全文索引(
FULLTEXT),REPAIR不重建它,需手动ALTER TABLE t1 DROP INDEX ft_idx; ALTER TABLE t1 ADD FULLTEXT(ft_col); - 线上表修复务必在低峰期做,且提前关掉应用写入——
REPAIR期间表不可写,但读请求会被阻塞直到修复结束
真正棘手的是那种“修复成功但业务逻辑异常”的情况:比如时间字段全变成 0000-00-00,或 JSON 字段解析失败。这种往往不是索引损坏,而是数据页物理损坏已蔓延到行数据区,REPAIR 无能为力,只能靠备份回滚。











