MySQL 存储引擎到底是什么?
它不是“数据库类型”,也不是“配置选项”,而是 MySQL 真正干活的底层组件——
负责把你的 INSERT/UPDATE/SELECT 转成磁盘读写操作。你可以理解为:同一个表结构(比如
t_user),用
InnoDB存,数据和索引一起写进
.ibd文件;换成
MyISAM,就拆成
.frm+
.MYD+
.MYI三个文件,连锁机制、崩溃恢复、事务支持都完全不同。
怎么查当前支持哪些引擎?别只看默认值
执行
SHOW ENGINES \G是最直接的方式,但要注意输出里
Support字段的值:
DEFAULT:当前 MySQL 实例默认引擎(5.7+ 基本都是
InnoDB)
YES:编译时启用,且运行时可用(比如
MEMORY可能被禁用)
NO:要么没编译进去,要么配置里显式禁用了(如
skip-innodb)
DISABLED:服务启动时加载失败(常见于插件路径错误或依赖缺失)
别只信
SHOW VARIABLES LIKE '%storage_engine%'——它只告诉你“默认设成啥”,不反映实际可用性。
建表时不指定 ENGINE=?后果很现实
如果你写
CREATE TABLE t_log (id INT) DEFAULT CHARSET=utf8;却漏了
ENGINE=,MySQL 就按
default_storage_engine配置走。问题在于: 开发环境是
InnoDB,测试库却因配置差异用了
MyISAM→ 外键失效、事务回滚不生效、高并发更新卡死 线上迁移时没检查引擎,
ALTER TABLE t_order ENGINE=InnoDB可能锁表几分钟,尤其大表
mysqldump默认不导出 ENGINE 信息,还原后可能变成
MyISAM(除非加
--force或手动补)
建议:所有建表语句显式声明
ENGINE=InnoDB,哪怕它是默认值——这是防止环境漂移最便宜的保险。
为什么 InnoDB 成了事实标准?关键不在“默认”,而在行为差异
不是因为它功能多,而是它的行为更贴近现代应用的真实约束:
InnoDB的行级锁 + MVCC,让
UPDATE t_user SET balance=balance-100 WHERE id=123不会阻塞其他用户查
id=456的记录;而
MyISAM表级锁会让整张表“冻结”
InnoDB崩溃后靠
redo log自动前滚恢复,
MyISAM崩溃大概率要
REPAIR TABLE,且无法保证数据一致性
foreign_key只在
InnoDB生效,
MyISAM上加外键语法不报错,但纯属摆设
真正容易被忽略的是:即使你只读不写,
MyISAM的
CONCURRENT INSERT在有 DELETE 时也会退化为表锁;而
InnoDB的读不加锁(RC/RR 隔离级下),天然适合读多写少场景——这点常被误认为“InnoDB 更慢”。
