目录
InnoDB内存结构主要分为4个部分:
Buffer Pool
Change Pool #写缓存
Log Buffer #日志缓存
Adaptive Hash Index #自适应hash索引
1.Buffer Pool
也是B+树结构
1.当读一条数据时,会先检查是否在data pages中
如果不在,那么去IO读InnoDB 表空间,读取到data pages后,再返回给client
如果在,读取最新版本
然后进行操作,变成脏数据,再刷新到磁盘。
2.InnoDB对任何数据的读写都是基于内存的
3. 查看buffer pool的组成
select page_type,sum(data_size)/1024/1024 as size_MB
from information_schema.innodb_buffer_page
group by page_type
order by 2 desc;
Database pages #LRU List 列表
Modified db pages #脏页的个数,由于在进行update操作时首先会修改缓冲池中 的数据,在定时异步的将缓冲池的数据刷新到磁盘中(checkpoint技术),所以 缓冲池的数据与磁盘的数据会产生不一致,称为脏页。
Free buffers Free List页的个数
2.Redo Log Buffer
1.修改数据前先记录undo,修改后的数据在脏页,修改动作记录到redo
2.redo log buffer不用太大,由参数innodb_log_buffer_size控制,默认为8M
3.redo log 在下列三种情况下会从buffer中刷新到redo log file:
master thread每一秒刷新
每个事务提交时刷新
redo log buffer 剩余空间小于1/2时
3.change buffer
Change Buffer是一种用于缓存辅助索引页变化的区域,是buffer pool中一块独立的区域。
当需要修改的辅助索引页不在缓冲池中而在磁盘中时,会将这些索引页的变化缓存在change buffer中。
对索引的更新先缓存在change buffer中,然后由master thread做merge——将修改数据合并到 buffer pool,然后刷新到磁盘。
工作机制:
先判断要修改的非聚集索引页(辅助索引页)是否在buffer pool中
存在,则直接修改然后将结果临时存放在change buffer中
不存在,直接将更改缓存到change buffer中(注意,并不通过IO读入,而是直接将修改 缓存在change buffer)
参数:
innodb_change_buffer_max_size ,默认最大允许25%
innodb_change_buffering
基本上change buffer不用管。只需要控制max_size 不要设置太高就ok,innodb会自行适应。
为什么二级索引需要Change Buffer?
减少随机读取IO
对于聚集索引页,DML操作带来的数据磁盘读取和缓存修改往往是顺序的、集中的,这就很好 地利用了聚集索引的优点,但随着聚集索引页的顺序IO,各个二级索引页的读取和修改通常是随 机IO的。而Change buffer将分散的、未缓存的二级索引页的变化进行缓存而非直接从磁盘中读 取索引页,待到其他操作需要访问二级索引时,只需将change buffer中的变化缓存合并然后加 入缓冲池(buffer pool)就行了,这样就大大地减少了磁盘随机读取的IO。
定期批量写入索引变化
如何配置change buffer?
可以用innodb_change_buffering系统变量控制change buffer相关的行为。可以控制change buffer只对部分类操作生效。该变量的值和含义如下:
all
默认值,表示缓存所有DML语句和物理purge操作的索引页变化。
none
不对任何操作缓存,相当于禁用
inserts
只缓存insert
deletes
只缓存标记性delete操作
changes
只缓存写入和标记性delete
purges
只缓存后台物理删除操作
注意:
innodb_change_buffering参数可动态修改,只对修改后发生的操作生效,修改前已缓存的索引 页不受影响
可以用innodb_change_buffer_max_size变量控制change buffer区域的最大大小,表示占缓冲 池总大小的百分点数。默认为25。最大可以设置为50。
当DML语句量较多时,可以适当扩大innodb_change_buffer_max_size.反则反之。