mysql 5.5起支持compressed行格式,但需满足innodb_file_per_table=on、innodb_file_format=barracuda且建表时同时指定row_format=compressed和key_block_size,否则静默降级为compact。

确认 MySQL 版本与基础配置是否支持 COMPRESSED
MySQL 5.5 起才支持 ROW_FORMAT=COMPRESSED,但真正稳定可用要到 5.6+;5.7.7 及以后版本默认启用 innodb_file_format=BARRACUDA,老版本必须手动设置并重启。不满足前提时,即使建表语句写了 ROW_FORMAT=COMPRESSED,MySQL 也会静默降级为 COMPACT,SHOW TABLE STATUS 中的 Row_format 字段仍显示 Compact。
检查当前配置:
SHOW VARIABLES LIKE 'innodb_file_format';<br>SHOW VARIABLES LIKE 'innodb_file_per_table';<br>SHOW VARIABLES LIKE 'innodb_page_size';
关键点:
-
innodb_file_per_table必须为ON:否则表数据写入系统表空间ibdata1,而它完全不支持压缩 -
innodb_file_format必须是BARRACUDA(注意大小写,antelope不行) -
innodb_page_size默认是16384(16K),KEY_BLOCK_SIZE必须是它的约数(如1、2、4、8、16,单位 KB)
新建表时启用 COMPRESSED 行格式
建表语句中必须同时指定 ROW_FORMAT=COMPRESSED 和 KEY_BLOCK_SIZE,缺一不可。只写 ROW_FORMAT=COMPRESSED 会报错或被忽略(取决于 MySQL 版本)。
示例(推荐从 KEY_BLOCK_SIZE=4 或 8 开始试):
CREATE TABLE logs (<br> id BIGINT PRIMARY KEY,<br> content TEXT<br>) ENGINE=InnoDB<br>ROW_FORMAT=COMPRESSED<br>KEY_BLOCK_SIZE=4;
注意:
-
KEY_BLOCK_SIZE写成4K或4k会报语法错误,必须是纯数字(如4) - 如果用
ENGINE=InnoDB但没写ROW_FORMAT,则走默认格式(5.7+ 是DYNAMIC,不压缩) -
ROW_FORMAT=COMPRESSED仅对独立表空间(.ibd文件)生效,通用表空间(CREATE TABLESPACE)虽支持,但需额外验证
对已有表启用压缩:ALTER TABLE 的实际影响
ALTER TABLE t ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 看似简单,但背后是全表重建:读取原数据 → 压缩写入新页 → 替换原 .ibd 文件。这意味着:
- 表会被锁(
ALGORITHM=COPY,MySQL 5.6+ 默认),DML 阻塞,线上大表慎用 - 需要双倍磁盘空间(旧文件未删 + 新文件已写),操作前确保
tmpdir和数据目录有足够剩余空间 - 执行后务必验证:
SHOW TABLE STATUS LIKE 't'\G中Row_format必须是Compressed,且Data_length明显小于同数据量的非压缩表 - 如果表上有全文索引(
FULLTEXT),COMPRESSED格式不支持,会直接报错
为什么 SHOW CREATE TABLE 显示 row_format=COMPRESSED 却没压缩?
这是最常被忽略的陷阱:建表语句里写了 ROW_FORMAT=COMPRESSED,SHOW CREATE TABLE 也显示它,但 SHOW TABLE STATUS 中 Row_format 仍是 Compact —— 说明压缩根本没生效。
根本原因只有两个:
-
innodb_file_format在建表时不是BARRACUDA(比如当时是antelope,之后才改):InnoDB 会保留建表语句里的声明,但实际忽略压缩逻辑 -
innodb_file_per_table=OFF:表被建在ibdata1里,而系统表空间强制禁用所有压缩机制,连参数校验都不做
修复方式不是重跑 ALTER TABLE,而是先确认并修正全局配置,再重建表(或导出导入)。别指望“补一个 ALTER”就能激活早先失效的声明。











