innodb_page_size不可动态修改,启动时校验ibdata1文件头页大小与配置值是否一致,不匹配则报“InnoDB: Error: page size mismatch”并拒绝启动;唯一合法设置方式是在初始化实例时通过--innodb-page-size参数指定,且后续永久固定。

innodb_page_size 不能动态修改,改错就启不来
MySQL 启动时会校验系统表空间(ibdata1)头里的实际页大小,和配置中 innodb_page_size 值做比对。不一致直接报错:InnoDB: Error: page size mismatch,mysqld 进程退出。这不是警告,是硬性拒绝启动。
常见误操作包括:
- 在已有数据的实例上,仅修改
my.cnf中的innodb_page_size并重启 - 以为像
innodb_buffer_pool_size那样可在线 SET GLOBAL - 用 xtrabackup 恢复备份后,误配了不同页大小的配置再启动
唯一合法路径:初始化新实例时通过 --innodb-page-size=8k(或带单位如 16KB)传参,且后续永远不可变。
4KB vs 16KB vs 32KB:B+ 树深度和 I/O 次数直接受控
页越小,单页能存的索引键越少 → B+ 树层级越深 → 主键等值查询平均多 1–2 次随机 I/O。比如主键是 BIGINT(8 字节),指针按 6 字节算:
-
16KB页:非叶子节点约存 1000+ 键值 → 1000 万行数据树高通常为 3–4 层 -
4KB页:同结构只剩 ~250 键值 → 同样数据量树高可能达 5–6 层 -
32KB页:扇出翻倍,但写放大加剧,且ROW_FORMAT=COMPRESSED不支持
SSD 随机读延迟低,所以 4KB 在高频小记录 OLTP 场景下未必更快;HDD 上反而因层数增加更慢。
页大小决定单行最大长度和索引列长度上限
很多人混淆 innodb_page_size 和 innodb_large_prefix,其实前者才是底层硬约束:
-
4KB页 → 单索引列最大长度为 768 字节(不是字符数,是字节数) -
16KB页 → 默认上限 3072 字节(启用innodb_large_prefix+ROW_FORMAT=DYNAMIC后) -
32KB页 → 单行最大长度约 16000 字节,但禁用压缩行格式,且 xtrabackup 对其支持不稳
如果你建表时报 Specified key was too long,先查 SHOW VARIABLES LIKE 'innodb_page_size',再确认当前页大小是否已卡死上限。
确认真实页大小别信 SHOW VARIABLES 或 SHOW ENGINE INNODB STATUS
SHOW VARIABLES LIKE 'innodb_page_size' 显示的是配置值,不是运行时真实值;SHOW ENGINE INNODB STATUS\G 里 PAGE SIZE 字段是编译时硬编码值(通常是 16384),完全不可信。
真正有效的验证方式只有两个:
- 查 error log 初始化阶段输出:
InnoDB: Using page size of 8192 - 用
hexdump -C ibdata1 | head -20,看第 16 字节起的 4 字节(小端序)——比如00 00 20 00就是 8192(8KB)
线上环境一旦混用不同页大小的实例(比如迁移、恢复、克隆),这个验证步骤漏掉,后面索引损坏、复制中断都很难定位。



















