myisam表在mha切换后必然报“table is marked as crashed”,因其崩溃恢复机制缺失,且mha的apply_diff_relay_logs、权限同步、备份均对其失效,修复需repair table锁表停服,唯一可靠方案是转innodb或隔离myisam实例。

MyISAM表在MHA切换后大概率报 Table is marked as crashed
MySQL异常退出时,MyISAM的.MYD和.MYI文件极易出现写入不完整——主库宕机前未刷盘的日志、中断的索引重建、半截的INSERT都可能残留损坏状态。MHA切换后,原从库提升为主库,首次写入就会触发校验失败,直接报Got error 127 from storage engine或Table is marked as crashed。这不是偶发错误,而是MyISAM崩溃恢复机制缺失导致的必然结果。修复必须执行REPAIR TABLE,该操作会全表加锁、阻塞所有读写,等于二次停服。
MHA的apply_diff_relay_logs对MyISAM完全失效
MHA靠解析relay log补全候选主库与其他从库之间的binlog差异,但这个机制只对InnoDB有效。MyISAM表的DDL(如ALTER TABLE)和DML在ROW格式binlog中无法被正确重放;STATEMENT格式下又因函数不确定性(如NOW())导致主从值不一致。更糟的是,一旦MyISAM表在复制链路中出错,SQL Thread会卡死在ERROR 1032或ERROR 1594,而MHA默认不监控SQL Thread状态,切换后业务已连上新主,却查不到数据或返回空结果。
权限同步脚本mysqldump --no-data mysql会漏掉MyISAM系统表
很多团队用mysqldump --no-data --skip-extended-insert mysql导出权限,再在新主上SET sql_log_bin=0导入。但MySQL 5.7+的mysql库中部分表(如columns_priv、procs_priv)仍可能是MyISAM引擎。这些表的变更不会被binlog记录,dump时也常因权限不足跳过——导致新主上SHOW GRANTS FOR 'app'@'%'返回空,应用连接直接被拒。你得手动检查SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'mysql' AND ENGINE = 'MyISAM',逐个确认。
备份与高可用彻底脱节:--single-transaction静默退化成全局锁
线上备份脚本若用了mysqldump --single-transaction,遇到MyISAM表时MySQL会自动降级为--lock-all-tables,整个实例进入只读状态。MHA切换窗口期本就紧张,此时备份又卡住写入,新主刚切完就面临堆积的写请求洪峰,极易触发连接数爆满或Lock wait timeout exceeded。Percona XtraBackup更严重——它对MyISAM强制全库加锁,且无法跳过。真正能落地的方案只有两个:ALTER TABLE tbl_name ENGINE=InnoDB全部转走,或者把MyISAM表彻底隔离到独立实例、不参与MHA集群。











