innodb_page_size不能runtime修改,因页大小是InnoDB物理存储核心单位,固化于ibdata1文件头,启动时严格校验配置与实际数据一致性,不匹配则报错退出;它直接影响B+树高度、页分裂频率及OS page cache对齐效率。

innodb_page_size 为什么不能 runtime 修改
因为页大小是 InnoDB 存储层的物理对齐单位,直接绑定 ibdata1 文件头、B+ 树节点结构、redo log 记录粒度和 OS page cache 行为。MySQL 启动时会硬校验 ibdata1 头部记录的实际页大小与配置中 innodb_page_size 是否一致;不匹配就报 InnoDB: Error: page size mismatch 并退出进程——这不是警告,是启动失败。常见误操作包括:只改 my.cnf 里的值然后重启已有实例,或用 xtrabackup 恢复备份后配错页大小再启动。
页大小如何影响 B+ 树并发访问路径
页越小,单页能存的索引键越少,B+ 树层级越深。比如主键是 BIGINT(8 字节),指针按 6 字节算:
- 4KB 页:非叶子节点约存 250 个键值 → 1000 万行数据树高可能达 5–6 层
- 16KB 页:同结构可存 1000+ 键值 → 树高通常为 3–4 层
层数多意味着每次主键等值查询平均多 1–2 次随机 I/O,而这些 I/O 在高并发下会争抢磁盘队列、Buffer Pool latch 和 page hash table 锁。尤其在 SSD 上,虽然单次延迟低,但层数增加仍会放大锁竞争密度——多个线程同时查不同主键,却频繁在中间层页上发生 latch 冲突。
页分裂对写并发的放大效应
页分裂不是“复制粘贴”,而是带状态迁移的重构:原页保留约 50% 记录,新页接收另一半,并重算 heap_no、slot 数组、page directory,还要更新父节点。整个过程至少涉及 3 个页的内存操作(原页、新页、父页),若父页不在 Buffer Pool 中,还会触发一次额外磁盘读。这意味着:
- 4KB 页更容易满 → 分裂更频繁
- 分裂操作持有
btr_search_latch和buf_pool->mutex等关键锁,阻塞其他线程访问同一区(extent)甚至相邻页 - 高并发插入场景下,大量线程卡在分裂路径上,表现为
innodb_row_lock_time_avg升高、innodb_buffer_pool_wait_free出现、QPS 不升反降
页大小与操作系统 page cache 的对齐代价
Linux 默认 page size 是 4KB(x86)或 64KB(ARM),而 InnoDB 页大小必须与之对齐才能避免额外读 I/O。例如:
- 设
innodb_page_size=16KB,OS page size=4KB → 每次刷盘需 4 次 OS page write,且若某 4KB page cache 缺失,还得先 read-in 再 write-out,多一次 I/O - 设
innodb_page_size=64KB(ARM 环境),则与 OS page 完全对齐,减少 page cache 碎片,但 MySQL 5.7+ 才支持,且ROW_FORMAT=COMPRESSED不可用
不对齐不仅拖慢单次写入,还会让内核 page cache 管理更吃力,在高并发混合读写时加剧 pgpgin/pgpgout 波动,间接抬高整体延迟抖动。



















