mysql页⾯⼤⼩_MySQLinnodb_page_size
原标题:MySQL innodb_page_size
墨墨导读:Page是MySQL Innodb存储的最基本结构,也是Innodb磁盘管理的最⼩单位,了解page的⼀些特性,可以更容易理解MySQL。
innodb_page_size作为innodb和OS交互单位。⽂件系统对⽂件的buffer IO,也是page为单位进⾏处理的。Linux的默认page的⼤⼩4096字节,当要将数据写⼊到⽂件的时候,会先在内存⾥,然后将对应的page cache,整个的从内存刷到磁盘上。但是如果要写⼊的⽂件区域,因为还没有被缓存或者被置换出去了等原因,在内存⾥不存在对应的page cache,则需要先将对应page的内容从磁盘上读到内存⾥,修改要写⼊的数据,然后在将整个page写回到磁盘;在这种情况下,会有⼀次额外的读IO开销,IO的性能会有⼀定的损失。假如mysql的16K的页表数据⽀持起,那就是⼀次内存IO光是虚拟地址到物理地址的转换就要去内存查4次页表,再算上真正的内存访问,需要5次内存IO才能获取⼀个内存数据。
操作系统PAGE:
在操作系统层⾯,每个进程都有⾃⼰独⽴的地址空间,看到的都是操作系统虚拟出来的地址空间,虚拟地址最终还是要落在实际内存的物理地址上进⾏操作的。操作系统就会通过页表的机制来实现进程的虚拟地址到物理地址。其中每⼀页的⼤⼩都是固定的。
获取当前操作系统的page size:
####X86:
[root@ens8 ~] # getconf PAGESIZE
4096
####ARM:
root@ens8ARM :~# getconf PAGESIZE
65536
页表级数:
页表级数越少,虚拟地址到物理地址的映射会很快,但是需要管理的页表项会很多,能⽀持的地址空间也有限。
相反页表级数越多,需要的存储的页表数据就会越少,⽽且能⽀持到⽐较⼤的地址空间,但是虚拟地址到物理地址的映射就会越慢。
备注:ARM系统来说需要编译指定才可以。因为Linux 默认4kb页是通过长期的跟MySQL磨合,才有现在的稳定的表现。
MySQL数据库Page
InnoDB逻辑存储单元主要分为表空间、段、区和页。层级关系为tablespace -> segment -> extent(64个page,1M) -> page。(⾮常经典的图)
在看看innodb_page_size的官⽅描述:
第⼀个系统表空间数据⽂件(ibdata1)的最⼩⽂件⼤⼩取决于innodb_page_size值
innodb_page_size只能在初始化MySQL实例之前配置,不能在之后修改。如果没有指定值,则使⽤默认页⾯⼤⼩初始化实例。
MySQL 5.7增加了对32KB和64KB页⾯⼤⼩的⽀持。对于32KB和64KB的页⾯⼤⼩,最⼤⾏长度约为16000字节。当
innodb_page_size设置为32KB或64KB时,不⽀持ROW_FORMAT= compression。对于innodb_page_size=32k,区段⼤⼩为
mysql下载选x86还是arm
2MB。对于innodb_page_size=64KB,区段⼤⼩为4MB。当使⽤32KB或64KB的页⾯⼤⼩时,innodb_log_buffer_size应该⾄少设置为16M(默认)。
默认的16KB或更⼤的页⾯⼤⼩适⽤于各种⼯作负载,特别是涉及表扫描的查询和涉及批量更新的DML操作。对于涉及许多⼩写操作的OLTP⼯作负载,较⼩的页⾯⼤⼩可能更有效,在这种⼯作负载中,当单个页⾯包含许多⾏时,可能会出现争⽤问题。对于通常使⽤较⼩块的SSD存储设备,较⼩的页⾯也可能是有效的。保持InnoDB页⾯⼤⼩接近存储设备块⼤⼩,可以最⼤限度地减少被重写到磁盘的未更改数据量.
对于row,index,tablesapce的影响
Page对Row的影响:
对于4KB、8KB、16KB和32KB的页⼤⼩,最⼤⾏⼤⼩(不包括存储在页外的任何可变长度的列)略⼩于页⼤⼩的⼀半。例如,默认
innodb_page_size为16KB的最⼤⾏⼤⼩约为8000字节。然⽽,对于InnoDB页⾯⼤⼩为64KB的页⾯,
最⼤⾏⼤⼩⼤约是16000字节。LONGBLOB和LONGTEXT列必须⼩于4GB,包括BLOB和⽂本列在内的总⾏⼤⼩必须⼩于4GB。
Page对index的影响:
如果在创建MySQL实例时通过指定innodb_page_size选项将InnoDB页⾯⼤⼩减少到8KB或4KB,索引键的最⼤长度将按⽐例降低,这是基于16KB页⾯⼤⼩的3072字节限制。也就是说,当页⾯⼤⼩为8KB时,最⼤索引键长度为1536字节,⽽当页⾯⼤⼩为4KB时,最⼤索引键长度为768字节。
不同的Page⼤⼩,表空间限制:
Pages对字段的影响 :
对于4KB、8KB、16KB和32KB的innodb_page_size设置,最⼤⾏长度略⼩于数据库页的⼀半。例如,对于默认的16KB InnoDB页⾯⼤⼩,最⼤⾏长度略⼩于8KB。对于64KB的页⾯,最⼤⾏长度略⼩于16KB。
如果⼀⾏不超过最⼤⾏长度,则所有⾏都存储在本地页中。如果⼀⾏超过最⼤⾏长,则选择可变长度列⽤于外部页外存储,直到该⾏符合最⼤⾏长限制为⽌。可变长度列的外部离页存储因⾏格式不同⽽不同:
COMPACTRow Formats:
当⼀个可变长度的列被选择⽤于外部页外存储时,InnoDB将前768个字节本地存储在⾏中,其余的存储在外部溢出的页⾯中。每个这样的列都有⾃⼰的溢出页列表。768字节的前缀伴有⼀个20字节的值,该值存储列的真实长度,并指向存储其余值的溢出列表
DYNAMICRow Formats:
当⼀个可变长度的列被选择⽤于外部页外存储时,InnoDB在本地的⾏中存储⼀个20字节的指针,其余的则在外部存储到溢出的页⾯
中,LONGBLOB和LONGTEXT列必须⼩于4GB,包括BLOB和TEXT列在内的总⾏长度必须⼩于4GB。
Page如何计算记录数
page构成结构:
除数据外ROW额外信息存在哪些:
16k页为基准,能保存多少记录数:
按照上⾯Page结构图,可以如下计算:
1.page⼤⼩(16*1024=16384)- 必要信息(File Header38字节+page header56字节+虚拟最⼤最⼩记录26字节+Page Directory4字节+File Trailer8字节)=16252字节
2.约每4条记录占⽤⼀个slot,⼀个slot⼤⼩占⽤2字节
4.假如单⾏长度计算公式为:row header5字节 + 主键索引列4字节 + 指针4字节 = 13字节
单个page最多能容纳最多⾏数为 单⾏长度N+N/4*2 = 16252,
N为1203测试:
通过sysben压测,发现MySQL默认页16K 相⽐8K 对CPU压⼒较⼩,但8k页的情况下所有指标都会有所提升。
sysbench压测是基于主键,8k的页来说,⾏⼩于4k的数据来说性能提升,假如⼤于4k的数据,性能肯定会有下降,因为会出现⾏溢出,会导致读取列需要多⼀个IO。所以不同的业务场景可以有效的调整innodb page size 进⾏调试。当然硬件也要⽀持,传统的SAS硬盘会存在IO效率下降,更上⼀层的硬盘(SSD,PCIE)能提供更⾼的IOPS。
总结
那么innodb_page_size的如何设置,按照个⼈理解,⽣产环境中,可以选择16kb 和8kb的长度。
可以考虑⼀下⽅⾯:
1.遵守单⾏略⼩于页⼤⼩的⼀半。不能发⽣⾏溢出现象,随之⽽来的要求是尽量主键操作,分配跟多的内存
2.硬件设备的⽀持,很多⾼端服务器cpu使⽤率也就在30%以内的服务器,完全可以使⽤8kb,提⾼整体性能。
innodb_page_size设置问题,最终还是io性能⽅⾯的优化。需要有效的利⽤MySQL的⼀些特性(索引组织表,尽量⾛主键避免回表,尽量减少随机读写等)结合实际情况进⾏配置。
前⼏天⼀起⼯作的同事聊到,现在出现新的⾼端内存。⼜能放到内存,⼜能保存数据的内存条!
责任编辑:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。