首页 > MySQL > Mysql的innodb缓冲池管理(二)

Mysql的innodb缓冲池管理(二)

2010年5月4日 admin 发表评论 阅读评论

页面读入机制

当读入页面的时候, 首先需要找到一个可用的block, 这个block或者来自于free list或者lru-list; 在读入数据块的时候, block会加上排他锁以防止其他线程再次使用这个block,

会在block中标记出这个块正处于io状态, 然后把io请求加入到io调用请求对列; 完成读入操作时, 再释放block上的拍它锁更新io状态。

数据页面的读取写入

缓冲池中的数据基本是采用同步aio的方式,这里的同步aio的意思是: 工作线程发出读或写请求后,请求会被放到一个读写请求队列中,由专门的io线程负责写盘和读盘,而工作线程则等待io的完成,

注意, 这里是等待完成,而不会放弃执行,因而称作为同步aio.

提前读(预读)机制

为了优化数据读入性能, 缓冲区读入采取了提前读的机制(当然,这个机制可以配置成不激活),当然, 提前读的机制是基于数据局部性的原理来的,

这就是为什么采用取值过于随机的字段作为主键会导致性能降低的原因之一:过于随机的主键会导致提前读不起作用, 而且会导致更多的换页行为; 这个预读取对于上层的功能如索引管理是透明的,

对于上层的功能来说, 需要提供的信息是需要读取的页是否有后继页和前置页。 有两种预读机制: 线性预读和随机预读

线性预读: 当第一读缓冲区中某一个已经存在(注意,这里必须是已经存在于缓冲区额数据块)的数据块时, 会检查这个数据块是不是处于所谓的线性预读区域(比如, 区域大小是64, 当前读入的也是100,那么所在的预读区域是65 ~ 128),如果是, 则统计一下这个区域中目前没有被访问过的页面,如果数量多于预读机制设定的预读数量,则放弃本次预读, 这个其实是检查目前的区域是否还有大量的页面没有被访问过, 如果是的话, 自然没有必要去做预读了; 否则, 取得读取页面的后继页和前置页(按照数据页的自然顺序?,然后检查后继页或者前置页是否是一个新区域的边界,如果是, 则发出读取

该区域里面的数据页面的异步请求。

随机读: 当读取一个页面时, 根据所读取页的位置计算出该页面所在的随机预读区域, 区域的计算也基于设定的区域页面数量来计算的(如前面关于线性预读的例子), 然后根据lru对列的信息计算该区域中有多少块最近被访问到了, 如果被访问的数量达到一定的额度(这个额度是根据预读区域的大小计算出来的, 5 + 预读区域大小 / 8),则预读取该区域中目前还没有读取到缓冲区的块.

show innodb status 中关于buffer pool的输出

Buffer pool size 262144 整个缓冲池中的页的数量, 包括flush列表中的和flush列表中的,以及被分配出去的页的数量

Free buffers 0           free列表中的页的数量

Database pages 258053    分配出去, 正在被使用页的数量

Modified db pages 37491 flush列表中的数量

Pending reads 0          发出了请求但没有完成的io读个数

Pending writes: LRU 0, flush list 0, single page 0 发出了请求但没有完成的io读个数在各个列表上的体现

Pages read 57973114, created 251137, written 10761167, 从磁盘上读取出来的页数, 在内存中建立了页面但是没有从磁盘上读取出来的页面数以及写入了的页面数

9.79 reads/s, 0.31 creates/s, 6.00 在刚过去的时间间隔里, 平均每秒的读取数和新建数

Buffer pool hit rate 999 / 1000       命中率, 缓冲区中读到的页 / 总共发出的读页数

与缓冲池相关的状态变量及含义

| Innodb_buffer_pool_pages_data      分配出去, 正在被使用页的数量

| Innodb_buffer_pool_pages_dirty     脏页但没有被flush除去的页面数

| Innodb_buffer_pool_pages_flushed     已经flush的页面数

| Innodb_buffer_pool_pages_free        当前空闲页面数

| Innodb_buffer_pool_pages_latched     当前被锁住的页面数

| Innodb_buffer_pool_pages_misc        用于管理功能的页面数, 如adaptive hash等

| Innodb_buffer_pool_pages_total    缓冲区总共的页面数

| Innodb_buffer_pool_read_ahead_rnd     随机预读的次数

| Innodb_buffer_pool_read_ahead_seq 线性预读的次数

| Innodb_buffer_pool_read_requests 总共从缓冲池中缓存的页面中读取出的页数

| Innodb_buffer_pool_reads             从磁盘上一页一页的读取的页数,从缓冲池中读取页面, 但缓冲池里面没有, 就会从磁盘读取

| Innodb_buffer_pool_wait_free        缓冲池等待空闲页的次数, 当需要空闲块而系统中没有时, 就会等待空闲页面

| Innodb_buffer_pool_write_requests 缓冲池总共发出的写请求次数

| Innodb_data_fsyncs                    总共完成的fsync次数

| Innodb_data_pending_fsyncs           innodb当前等待的fsync次数

| Innodb_data_pending_reads          innodb当前等待的读的次数

| Innodb_data_pending_writes           innodb当前等待的写的次数

| Innodb_data_read                       |    总共读入的字节数

| Innodb_data_reads                      innodb完成的读的次数

| Innodb_data_writes                   innodb完成的写的次数

| Innodb_data_written                 总共写出的字节数

关于缓冲池的关键的配置变量

innodb_buffer_pool_size: 缓冲池的大小

相关日志

分类: MySQL 标签: ,
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.
Easy AdSense by Unreal