MySQL源码分析(5):Innodb缓存系统

作者: Yuan Zhou (Intel) (7 篇文章) 日期: 九月 1, 2010 在 11:52 上午

Innodb缓存系统

  1. buffer操作
    1. 根据tbl_test文件的space id和offset检查buffer pool中是否已经有缓存,若有则直接读取该page信息,并返回结果;
    2. 若没有缓存则会先分配一个空白的page,然后读取磁盘上的数据加载进内存,并将结果返回。

    当Sql级别命令执行到Innodb的buffer层时就对应到在buf_pool上的对buffer block的读写等操作。
    例如客户端输入以下查询语句:
    select * from tbl_test;
    层层解析执行至缓存系统中将产生如下动作:

  2. Innodb buffer pool 系统简介


  3. buf_pool->free, 空闲块链表


  4. buf_pool->flush_list, 待写块链表

    ?

  5. buf_pool->LRU, LRU块链表

    ?

  6. buf_pool->unzip_LRU, 解压后的LRU块链表

    ?

  7. buf_pool->zip_clean, 干净的压缩块链表

    ?

  8. buf_pool->zip_free[BUF_BUDDY_SIZE],空闲的压缩块链表

buf0buf.c 是整个buffer系统的核心部分,提供了磁盘文件与内存交互的接口。整个buffer pool主要通过这几个链表来进行组织。

Buf0lru.c是buffer系统中负责缓存替换的算法,主要操作对象是LRU链表,目的是为了更好的使用缓存。
Buf0flu.c是系统中负责写数据到磁盘的部分。为了节省系统的IO开销,Innodb实现该部分时,还考虑当前系统中脏的页数、当前系统的负载等因素。
Buf0rea.c是系统中负责读数据的部分,包括普通的读、预读取、insert buffer、恢复。
Buf0buddy.c二进制伙伴分配算法,在分配压缩过的内存块时使用,避免系统中出现内存碎片。
此外,还包含了mem0pool.c来处理一些底层的数据。

读操作(从磁盘上加载数据到内存中)

当数据库文件未使用压缩格式存储时,innodb直接通过buf_LRU_get_free_block获得一个空闲的控制块。而当MySQL配置了压缩格式存储时,系统会通过二进制伙伴算法分配得到一个大小合适的控制块,防止出现内存碎片。主要调用流程如下:

Buf_page_get_gen是InnoDB缓存系统封装给外部系统调用的一个主要API。该函数用途是获得一个包含数据的page,并返回给调用函数。在实际使用时调用栈如下图所示:

写操作(从buffer pool中删除page并flush到磁盘上)

入口函数是buf_page_release,用以释放buffer pool中的page,该函数会把脏的数据标记到flush队列中。

在Innodb中有一个主控线程(srv_master_thread),主要负责定时写数据到磁盘文件上,其刷新频率的理论值为1秒或10秒,具体参照服务器当前的负载及buffer pool中脏页的比例动态调整,其主要的代码调用过程如下:


 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29114615/viewspace-1792440/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29114615/viewspace-1792440/

你可能感兴趣的:(数据结构与算法,数据库)