myisam表在row格式复制下必然报错,因引擎不支持行事件重放;statement格式虽暂通但导致非确定性函数引发静默数据不一致;myisam表级锁易致sql线程中断;alter转innodb需主从同步操作且全程锁表。

MyISAM表在ROW格式复制下直接报错
MySQL 5.7+ 默认 binlog_format 为 ROW,而 MyISAM 引擎不支持基于行的事件重放。一旦主库执行 UPDATE 或 DELETE,binlog 会记录行变更,但从库 SQL 线程尝试回放时会拒绝执行,报错:Cannot execute statement: binlogging impossible since the storage engine of table ... does not support it。这不是配置能绕过的限制,是引擎层硬性约束。
STATEMENT 格式下看似正常实则危险
若手动设为 STATEMENT,MyISAM 表可能暂时同步成功,但遇到非确定性函数(如 NOW()、UUID()、SYSDATE())或用户变量时,从库执行结果与主库不一致——因为时间戳、随机值等在从库生成,而非复刻主库原始值。这种不一致静默发生,SHOW SLAVE STATUS 不报错,但数据已偏移。
锁机制差异导致SQL线程中断
- MyISAM 是表级锁,主库写入时整个表阻塞;从库回放 DML 时若遇并发读写冲突(尤其配合
concurrent_insert或崩溃恢复),容易触发Got error 1296 from storage engine或Table is read only -
Seconds_Behind_Master变为NULL,Slave_SQL_Running变No,Last_SQL_Error明确指向 MyISAM 表 - 即使临时修复(如跳过错误),后续相同语句仍会失败,形成“反复中断→人工介入→漏同步”的恶性循环
ALTER TABLE ENGINE=InnoDB 的真实代价
必须在主库执行 ALTER TABLE t ENGINE=InnoDB,但注意:
- 该操作不支持
ALGORITHM=INPLACE,强制走COPY模式:全程锁表,DML 阻塞,binlog 记录完整重建过程 - 从库需同步执行同等耗时操作,复制延迟飙升,大表(>50GB)可能超时断连
- 切勿只改从库引擎——主库仍是 MyISAM,后续 DML 仍发 ROW 事件,从库照样报错
- 验证顺序必须是:先停从库 SQL 线程 → 在从库单独转换并确认无误 → 再在主库执行 → 最后重启复制
真正麻烦的不是转换动作本身,而是它暴露了长期被忽略的架构前提:主从引擎一致性不是可选项,是 ROW 复制的生存底线。











