在数据库数据处理中, 缓冲在改善性能方面扮演着很重要的角色, 为了保证性能, innodb 维护了自己的
在innodb中,需要用到数据页(需要保存到磁盘的数据)均是从这个
几个基本的概念
AWE:地址窗口化扩展,允许在 32 位版本的 Windows 操作系统上使用 4 GB 以上的物理内存。最多可支持 64 GB
的物理内存。更多信息请看 http://baike.baidu.com/view/1390438.htm;
innodb是支持AWE内存管理的
Frame;帧,16K的虚拟地址空间,
在缓冲池的管理上,整个缓冲区是是以大小为16k的frame(可以理解为数据块)为单位来进行的,frame是innodb中页的大小。
Page: 页,16K的物理内存, page上存的是需要保存到磁盘上的数据, 这些数据可能是数据记录信息,
也可以是索引信息或其他的元数据等;
Control Block:控制块,对于每个frame,
有一个block, block上的信息是专门用于进行frame控制的管理信息,
但是这些信息不需要记录到磁盘,而是根据读入数据块在内存中的状态动态生成的, 主要包括: 1. 页面管理的普通信息,互斥锁,
页面的状态, awe(windows平台上awe机制的管理信息)等 2. 脏回写(flush)管理信息3. lru控制信息 4.
快速查找的管理信息, 为了便于快速的超找某一个block或frame, 缓冲区里面的block被组织到一些hash表中;
缓冲区中的block的数量是一定得, innodb缓冲区对所管理的block用lru策略进行替换。
互斥访问
缓冲池的整个缓冲区有一个数据结构buf_pool进行管理和控制, 有一个专门的mutex保护着,
这个mutex是用来保护buf_pool这个控制结构中的数据域的, 并不保护缓冲区中的数据frame以及用于管理的block,
缓冲区里block或者frame中的访问是由专门的读写锁来保护的, 每个block/frame有一个。在5.1以前,
每个block是没有专门的mutex保护的,如果需要进行互斥保护,直接使用缓冲区的mutex, 结果导致很高的争用;
5.1以后,每个block有一个mutex对其进行保护, 从而在很大程度上解缓了对buf_pool的mutex的争用。
缓冲池管理用到的几个重要的列表
在缓冲区的管理中, 有几个重要的block列表(双向链表):
LRU列表: 用来进行lru管理的列表,
列表里的每个block所控制的数据都是当前有效的数据;列表中的block基本是按照访问的顺序排列的;最近被访问的放在最前面,
最先被方位的放在最后;lru列表中维护中维护了一个LRU_old, 大概指向整个列表的倒数3/8左右,
当增加一个新的block(主语与最近被访问的block的区别)进来的时候, 把新的块刚好放到这个点附近,
具体是前还是后取决于这个LRU_old目前的位置, 这么做的目的是使新增加进来的block放到一个合适的位置,
不至于放到最先(最近被使用过)或最后(最老)
flush列表: 列表block是那些所管理的数据被修改但是还没有更新到磁盘的脏frame,
根据修改的先后顺序排列的block列表, 最老的放最后。innodb起来后, 主线程会定期去检查
缓冲区中可用空闲block的数量的比例, 一旦大于srv_max_buf_pool_modified_pct(90%),
就会试图把一些脏页flush到磁盘;除了主线程会定期做这个事情外,工作线程在进行数据操作时 ,如果发现没有如果的block,
也会通过flush一些脏页来腾出空间。
free list, 所有空闲block的列表, 当需要分配一个block时, 从中取出一个block。
awe_LRU_free_mapped: 用于方便awe的block列表,
这些block所管理的page已经映射到了frame(物理内存有对应的虚拟内存空间),其中的元素必定也处于free列表或lru列表中。
这个列表会在当分配一个awe页面时用到。
adaptive hash search: 缓冲区中的页面是通过双向列表的方式组织起来的,
如果需要查找根据页号查找某个页面block的话, 速度不会快,尤其是数据块多的时候;
为了加速查找过程,在用双向列表组织block的时候,也采用了adaptive hash的数据组织,
hash的键值(key)是页号(数据页在所在表空间的编号), 这个在一定程度上能加速block的查找,
但是当以awe方式管理内存的话,这种
hash查找方式不会启用