LRU list
innodb中新读取到的页,并不直接放在LRU列表首部,而是放在midpoint位置。默认该位置在LRU列表5/8处。midpoint可有参数innodb_old_blocks_pct控制
mysql> show variables like 'innodb_old_blocks_pct'\G;
*************************** 1. row ***************************
Variable_name: innodb_old_blocks_pct
Value: 37
1 row in set (0.00 sec)
当有大的查询时,可能会将热点数据页从LRU列表中移除,为了避免这个问题可以通过参数innodb_old_blocks_time的修改来实现,该参数表示页读取到mid位置后需要等待多久才会被加入到LRU列表的热端。
mysql> show variables like 'innodb_old_blocks_time'\G;
*************************** 1. row ***************************
Variable_name: innodb_old_blocks_time
Value: 1000
1 row in set (0.00 sec)
可以通过innodb status来查看LRU列表和Free列表的使用和运行状态
mysql> show variables like 'innodb_old_blocks_time'\G;
。。。。。。
Buffer pool size 8191
Free buffers 7699
Database pages 491
Old database pages 0
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 449, created 42, written 101
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
Buffer pool hit rate 788 / 1000, young-making rate 0 / 1000 not 0 / 1000
。。。。。。
可以看到Buffer pool size共有8179个页,即8179*16k,共128M的缓冲池。
Free buffefreers表示free列表中页的数量
Database pages表示LRU列表中页的数量
Database pages与Free buffers之和不等于Buffer pool size,因为还可能分配给自适应哈希索引、lock信息、insert buffer等页。
因为是本地环境,没有做更新操作,所以即使设置了innodb_old_blocks_time,not young还是为0。
buffer pool hit rate,表示缓冲池命中率,一般不低于95%,如果偏低,要看看是不是有全表扫描造成LRU列表污染。
还可以通过innodb_buffer_pool_stats查看缓冲池的运行状态
mysql> select pool_id,hit_rate,
-> pages_made_young,pages_not_made_young
-> from information_schema.innodb_buffer_pool_stats\G;
*************************** 1. row ***************************
pool_id: 0
hit_rate: 0
pages_made_young: 0
pages_not_made_young: 0
1 row in set (0.00 sec)
可以通过innodb_buffer_page_lru 观察每个LRU列表中每个页的具体信息
mysql> select table_name,space,page_number,page_type
-> from information_schema.innodb_buffer_page_lru where space=1;
+------------------------------+-------+-------------+-------------+
| table_name | space | page_number | page_type |
+------------------------------+-------+-------------+-------------+
| `mysql`.`innodb_table_stats` | 1 | 3 | INDEX |
| NULL | 1 | 1 | IBUF_BITMAP |
+------------------------------+-------+-------------+-------------+
2 rows in set (0.13 sec)
innodb存储引擎支持压缩页功能,即将原本16k的页压缩为1k、2k、4k、8k。所以对于非16k的页通过unzip_LRU列表管理
mysql> show engine innodb status\G;
。。。。。。
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 223, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
。。。。。。
可以看到LRU列表义工223个页,unzip_LRU 列表中没有数据。LRU中的页包含unzip_LRU列表中的页。可以通过innodb_buffer_page_lru来观察unzip_LRU 列表中的页。
mysql> select
-> table_name,space,page_number,compressed_size
-> from information_schema.innodb_buffer_page_lru
-> where compressed_size <> 0;
Flush list
LRU列中数据被修改后,产生脏页。数据库通过checkpoint机制将脏页刷新会磁盘,flush list中的页即为脏页列表。脏页即存在于LRU中,也存在于Flush中。LRU list用于管理缓冲池中页的可用性,Flush list用于将页刷新回磁盘。
mysql> show engine innodb status\G;
。。。。。。
Modified db pages 2456
。。。。。。
Modified db pages显示了脏页的数量。
脏页的数据可通过innodb_buffer_page_lru查询
mysql> select table_name,space,page_number,page_type from information_schema.innodb_buffer_page_lru where oldest_modification>0;