“table 'xxx' is read only”是myisam表修复失败后残留的只读标记,并非表损坏本身;需先停服、用myisamchk --force清除标记,再-r修复,同时排查磁盘只读、权限不足或空间不足等底层问题。

“Table 'xxx' is read only”不是表损坏的直接报错,而是修复过程中的副作用
看到这个错误时,别急着修表——它大概率是 REPAIR TABLE 或 mysqlcheck -r 执行失败后残留的状态,尤其常见于 MyISAM 表。InnoDB 表根本不会出现这个提示,因为它的“只读”由 innodb_force_recovery 控制,且表现为无法写入而非报该字符串。真正触发它的,是 MySQL 在检测到表文件异常(如 .MYI 校验失败)后,自动将表标记为只读以阻止进一步写入,但又没完成修复流程。
确认是否真为 MyISAM 引擎且已进入只读状态
先验证两件事,避免在 InnoDB 上浪费时间:
- 执行
SHOW CREATE TABLE `xxx`;,检查输出中是否含ENGINE=MyISAM - 运行
SHOW TABLE STATUS LIKE 'xxx';,观察Comment列是否为Table is marked as crashed或read only - 查错误日志:
grep -i "read only" /var/log/mysql/error.log,确认是否有类似Table 'xxx' is read only due to failed repair的记录
解除只读并尝试真正修复的实操步骤
MyISAM 表一旦被标为只读,REPAIR TABLE 会直接拒绝执行。必须先重置状态再修:
- 停掉 MySQL:
systemctl stop mysql(关键!在线状态下无法清除只读标记) - 进入数据目录:
cd /var/lib/mysql/your_db_name/ - 用
myisamchk强制清除只读标记:myisamchk --silent --force xxx.MYI(注意不是-r,此时只是清理状态) - 再执行安全修复:
myisamchk -r -q xxx.MYI(-q表示快速,-r是常规修复) - 启动 MySQL:
systemctl start mysql,然后进 MySQL 执行CHECK TABLE xxx;验证
如果 myisamchk -r 仍失败,说明数据页已损,需换 myisamchk --safe-recover xxx.MYI——它会逐行扫描 .MYD 提取可读数据,但可能丢失部分行。
容易被忽略的磁盘与权限陷阱
很多修复卡在“只读”状态,其实和表本身无关,而是底层环境问题:
-
/var/lib/mysql所在分区被挂载为ro(只读):运行mount | grep mysql确认,若输出含ro,需重新挂载为rw - MySQL 进程对
.MYI文件无写权限:检查ls -l xxx.MYI,确保属主是mysql:mysql且权限至少为644 - 磁盘空间不足:
df -h /var/lib/mysql,修复过程需要 ≥ 表大小 1.5 倍的空闲空间,否则myisamchk会静默失败并留只读标记
修复完别忘了立刻备份三个文件:xxx.frm、xxx.MYD、xxx.MYI——MyISAM 没事务,下次出问题时这三份就是救命底牌。











