pxc/galera集群不支持myisam:因其仅支持row格式binlog,而myisam不支持row事件重放,且表级锁与多主并发模型冲突,易导致同步中断、数据不一致;修复须在主库将myisam表转为innodb。

MyISAM在Galera/PXC集群中根本无法同步写入
Galera(包括PXC)只支持基于行的复制(binlog_format=ROW),而MyISAM存储引擎**不支持ROW格式的binlog事件重放**。一旦主节点执行了对MyISAM表的DML(如UPDATE、DELETE),该操作会被记录为ROW event,但从节点在回放时会直接报错:Cannot execute statement: binlogging impossible since the storage engine of table ... does not support it。SQL线程随即中断,Slave_SQL_Running变为No,后续所有事件积压,节点数据就此脱节。
MyISAM表级锁与集群并发模型天然冲突
MyISAM使用表级锁,任意写操作都会阻塞全表读写。在PXC中,多个节点可同时写入,但Galera要求所有节点以相同顺序、相同结果执行事务。MyISAM的锁行为不可预测:同一语句在不同节点上可能因锁等待时间差异导致执行顺序偏移,甚至因崩溃恢复机制不同(MyISAM无crash-safe日志)造成数据页损坏或状态不一致。你看到wsrep_last_committed一致,只是事务ID序列没断,不代表实际数据被正确应用。
从库跳过MyISAM错误等于放弃一致性保障
- 不能用
SET GLOBAL sql_slave_skip_counter = 1跳过MyISAM相关错误——跳过的不是“一条语句”,而是整个事务上下文,后续依赖该表的其他操作(如JOIN、触发器模拟逻辑)会继续失败 - 也不能只在从库改引擎:
ALTER TABLE t ENGINE=InnoDB仅在本地生效,主库仍发MyISAM事件,从库下次同步又崩 - 更不能把
binlog_format切回STATEMENT——PXC强制要求ROW,且STATEMENT在含NOW()、UUID()等函数时本就会从库执行偏差
如何验证和修复已存在的MyISAM表
先确认问题范围:SELECT table_schema, table_name, engine FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema');
修复必须分两步:
- 在业务低峰期,于主库执行
ALTER TABLE db.t ENGINE=InnoDB, ALGORITHM=COPY(注意:MyISAM→InnoDB不支持INPLACE,必锁表) - 执行前务必检查表大小:
SELECT round((data_length + index_length) / 1024 / 1024 / 1024, 2) AS size_gb FROM information_schema.tables WHERE table_schema='db' AND table_name='t';;若>50GB,建议先在单个从库停SQL线程后转换并验证,再推主库
真正麻烦的从来不是命令本身,而是MyISAM表往往藏在历史遗留模块里,没人记得它为什么存在——等集群扩容、故障切换或数据校验时突然暴露,那时再处理,代价远超一次低峰期的在线转换。











