最近一段时间忙,尤其对MYSQL的原理的知识感觉到生疏了,所以还是的从新来过,让一些知识在重新印到脑子里面。今天就从 innodb buffer pool 开始。
作为MYSQL 重要的组成部分innodb buffer pool 一直是一个关注到疏忽的点,大部分DB人员对其的认识
1 INNODB buffer pool 为基于MYSQL的 INNODB 数据库引擎的数据缓存使用
2 INNODB buffer pool 划分的大小从数据库内存的 55% -70% 的设定与具体的数据库使用的环境有关。
3 INNODB buffer pool 在MYSQL 8 后期的版本可以进行动态调整了
4 INNODB 中通过LRU 算法对进入到内存的页面进行有效的退出机制
基于浅薄的我,可能暂时只能想起这些,那么这是不够的,需要对MYSQL的innodb buffer pool 进行更深入的理解。
INNODB BUFFER POOL 实际上是一块给MYSQL 使用装载需要处理数据的内存块,并且是在启动MYSQL 后就开始进行分配的。
1 INNODB BUFFER POOL 是怎么组成的
1 MYSQL 中的innodb buffer pool 是通过 instance 进行划分的,在MYSQL 中的BUFFER POOL 中的数据是通过链表的方式成型的
2 其中每个INSERTANCE 存在独立管理的内存页列表,通过分段的方式让每个链更有效的管理
2.1 这些链是可以进行并发处理
2.2 根据CPU 与内存的大小对buffer pool 进行内存的划分
2.3 数据的管理中 buffer pool 分为2个区域,将长使用的数据与短时使用的数据进行分割
3 BUFFER POOL Instance 组成
在BUFFER POOL instance 中存chunk 一般以128MB为最大的单位,其中通过buf_block_t 数组来控制其中的数据页面,通过hash 的方式将数据页面的地址与指向地址的指针组成,通过访问hash table的方式,直接将
同时每个instance 中包含三个 list 分别是 free list 存储没有被使用的页面
lru list 存储经常被使用的页面与刚刚被使用的页面,最后是修改的页面的list 通过
在MYSQL 数据库操作的过场中还存在以下一些问题
1 线性预读的问题,在读取数据的过程中,数据一般不会只在一个数据块中,并且可能在后续的数据的使用中,会对已经加载的数据页周边的页面机械能数据的访问,这就需要对数据访问提供线性方面的预读操作。
liner read-ahead
show variables like 'innodb_read_ahead_threshold';
这个值是将读取页面的边界扩展的设置,举例目前你读取的页面是3号页面,并且已经满足了操作,此时会在往下读 56 + 3 = 59 截止为59号的页面,通过这样的方式降低后续操作可能读取页面并等待页面提取的情况。这个值最大可以设置为64.
那么问题来了,如何判断这个设置的正确性或有效性
我们比对 page read ahead 和 evicted without access 两个来比对预读的有效性的问题。
show global status like '%read_ahead%';
或者通过上面的命令也能获得相关的数据。
下面的一些参数与 INNODB BUFFER POOL 的工作有关
innodb_buffer_pool_chunk_size 设置innodb buffer chunk 的大小
innodb_buffer_pool_dump_pct 这个设置的意思为当BUFFER POOL 中的内存不足的情况下,对于当时正在使用的页面被DUMP 的百分比。
innodb_buffer_pool_instances 是将当前buffer pool的内存划分为几个块
innodb_max_dirty_pages_pct _lwm 当脏页面达到10% 则开始启动刷新的行为
innodb_max_dirty_pages_pct 如果脏页达到了90% ,则自动启动最大化刷新脏页的行为。
这两个参数就与我们的另外两个参数有关。
innodb_io_capacity 这是触发页面刷新时可以使用的刷新的IOPS
innodb_io_capacity_max 是触发脏页达到了 innodb_max_dirty_pct 后可以使用的刷新的IOPS
实际上我们如果想判断写是否有压力的情况,可以通过
show global status like '%pend%'
show global status like '%a%written';
同时通过时间+ 下面参数的方式可以判断出当前,脏页写入到磁盘的每秒的BYTE数据 通过 innodb_data_written - 上一秒的值 获得
show global status like '%dirty%';
show global status like '%total%';
通过上面两个量来判断当前脏页在数据库页面中占的半分比等等
以上的信息可以通过程序撰写,来判断系统的状态。