表损坏的根因画像
织梦站点出现“表损坏”报错,根因通常不是单一问题,而是多种诱因叠加:服务器异常断电导致 MyISAM 索引未刷盘、磁盘空间满写入被截断、并发写入下 MySQL 进程被 OOM kill、运维直接 kill -9 关库、磁盘存在坏道、被植入恶意 SQL 后表结构被破坏。解决报错前需要先判断“是哪张表、什么引擎、报什么错”,再对症下药。
典型报错与对应方案
报错一:Table is marked as crashed
Table './dedecms/dede_archives' is marked as crashed
and last (automatic?) repair failed
多见于 MyISAM 表,索引文件 .MYI 损坏。处理:
REPAIR TABLE dede_archives QUICK;
-- QUICK 失败时改用 EXTENDED
REPAIR TABLE dede_archives EXTENDED;
报错二:Got error ... from MyISAM table
Got error 127 from table handler
Got error 134 from storage engine
错误码 127 表示表文件指针异常,134 表示记录被删除后索引未更新。处理:
-- 134 通常 REPAIR 即可
REPAIR TABLE dede_addonarticle;
-- 127 严重时需 myisamchk 离线修复
myisamchk -r /var/lib/mysql/dedecms/dede_addonarticle.MYI
报错三:Incorrect key file
Incorrect key file for table './dedecms/dede_arctiny.MYI';
try to repair it
索引文件不完整或磁盘满。先检查磁盘:
df -h
# 若 use% 接近 100%,先清理日志、临时文件
# 再执行修复
REPAIR TABLE dede_arctiny USE_FRM;
USE_FRM 选项会重建 .MYI 索引文件,但若 .frm 与 .MYD 不匹配可能丢数据,仅在常规 REPAIR 失败后使用,并务必先备份。报错四:InnoDB: Database page corruption
InnoDB 报页损坏通常伴随 MySQL 无法启动。处理见下一节。
InnoDB 页损坏恢复流程
- 停止 MySQL:
systemctl stop mysqld - 备份整个数据目录:
cp -r /var/lib/mysql /backup/mysql_bak - 编辑
/etc/my.cnf,[mysqld]段加:innodb_force_recovery=1 - 启动 MySQL,若仍失败则把值递增到 2、3、4、5、6
- 能启动后立即导出全部表:
mysqldump --single-transaction -A > all.sql - 删除
ibdata1、ib_logfile*、受损库目录 - 恢复
innodb_force_recovery=0,重启 MySQL - 建库后导入:
mysql < all.sql
场景化处置表
| 场景 | 首选命令 | 兜底方案 |
|---|---|---|
| MyISAM 索引损坏 | REPAIR QUICK | myisamchk -r |
| 磁盘满导致损坏 | 清理 + REPAIR | USE_FRM 重建索引 |
| 重复键冲突 | 查找重复行删除 | REPAIR EXTENDED |
| InnoDB 页损坏 | force_recovery 导出 | 重建表空间 |
| .frm 丢失 | 从备份恢复 .frm | 用同结构表 .frm 替换 |
注意事项
- 修复前完整备份是底线,任何修复命令都可能造成数据变化。
- USE_FRM 与 EXTENDED 不可作为常规手段,仅在紧急时使用。
- 同一张表反复损坏,优先排查磁盘坏道:
smartctl -a /dev/sda - 不要在生产直接
rm数据文件,需停服后操作。 - 修复完成后立即执行一次完整备份覆盖原备份。
建议与展望
表损坏报错是“症状”而非“病因”。建议把织梦核心表逐步迁移到 InnoDB,借助事务保障数据一致性;同时部署磁盘健康监控、UPS 与内存巡检,从硬件层降低损坏概率。把每种报错的处置流程固化为运维手册,遇错按表查询即可快速恢复,让织梦数据库在故障面前拥有可预期、可重现的修复能力。