Fork me on GitHub

InnoDB 读书笔记 2

缓冲池

副标题:姜承尧《MySQL技术内幕 InnoDB存储引擎》读书笔记 2

缓冲池的简介

  • InnoDB引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理

  • 缓冲池是一块内存区域,在数据库进行读取页的操作,首先将磁盘读到的页放在缓冲池中,称为将页“FIX”在缓冲池。下一次读到相同页时,首先判断该页是否在缓冲池中,若是则直接在缓冲池中读取该页,否则,读取磁盘上的页

  • 对于数据库中页的修改操作,首先修改在缓冲池中的页,然后以一定的频率刷新到磁盘上。但并不是每一次修改都会触发刷回数据的操作,而是按照一种称为checkpoint的机制进行

  • 缓冲池的大小直接影响数据库的整体性能,32位操作系统下,该值最多可以设置为3G,此外用户可以打开操作系统的PAE选项来获得32位OS下最大64G内存的支持

    1
    2
    3
    4
    5
    6
    //查看缓冲池的大小,以下134217728B表示128MB
    mysql> show variables like 'innodb_buffer_pool_size'\G;
    *************************** 1. row ***************************
    Variable_name: innodb_buffer_pool_size
    Value: 134217728
    1 row in set (0.00 sec)
  • 缓冲池中缓存的数据页类型:索引页、数据页、undo页、插入缓冲、自适应哈希索引、InnoDB存储的锁信息、数据字典信息等,如下图

    1

  • InnoDB允许有多个缓冲池实例,如下图查看,可以在配置文件中修改。同时也可以使用命令SHOW ENGINE INNODB STATUS查看每个缓冲池实例对象运行的状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    mysql> show variables  like 'innodb_buffer_pool_instances'\G;
    *************************** 1. row ***************************
    Variable_name: innodb_buffer_pool_instances
    Value: 1
    1 row in set (0.00 sec)

    //部分代码:
    mysql> show engine innodb status\G;
    Total large memory allocated 137428992
    Dictionary memory allocated 216425
    Buffer pool size 8191
    Free buffers 6983
    Database pages 1190
    Old database pages 419

InnoDB如何管理缓存池(即一大块内存)

  • 通常的缓冲池是通过LRU(Latest Recent Used)算法来进行管理的,最常使用页放在LRU列表的前端,最少使用的页放在尾端。当缓冲池不能存放新读取的页时,将首先释放LRU列表中尾段的页。
  • InnoDB对LRU算法进行了一些优化,在LRU列表中新增了midpoiont位置,新读取的页并不放在首部,而是放在midpoint处,约5/8的位置,可由参数innodb_old_blocks_pct控制。至于为什么不放在首部,是因为新读取的页通常仅是这次查询操作中需要,并不是活跃的热点数据。所以InnoDB引入另一个参数来进一步管理LRU列表,即innodb_old_blocks_time,用于表示页读取到mid位置后需要等待多久才会被加入到LRU列表的热端。
  • 当页从LRU列表的old部分加入到new部分时,此时发生的操作为page made young,而因为innodb_old_blocks_time的设置导致页没有从old部分移动到new部分的操作称为page not made young,page made young显示了LRU列表中页移动到热端的次数。
  • 还有一个重要的观察变量——Buffer pool hit rate ,表示缓冲池的命中率,通常不应该小于95%。
  • 在LRU列表中的页被修改后,称该页为脏页,这时DB会通过CheckPoint机制将脏页刷回磁盘,而Flush列表中的页即为脏页列表。

日志缓存和额外的内存池

  • InnoDB将重做日志信息先放入重做日志缓存区,一般每一秒钟将重做日志缓冲刷新到日志文件,由参数innodb_log_buffer_size 控制,默认为8MB;
  • InnoDB对内存的管理使用heap的方式,详略

CheckPoint技术

  • 背景:如果每次update或delete都要将新页的版本刷新到磁盘,这个开销是非常大的。同时如果在刷新时发生了宕机,那么数据就不能恢复了。

  • 所以为了避免数据丢失的情况,事务数据库系统普遍采取了Write Ahead Log策略,即当事务提交时,先写重做日志,再修改页。

  • CheckPoint技术目的是为了解决以下几个问题:

    1. 缩短DB的恢复时间;
    2. 缓冲池不够用时,将脏页刷新到磁盘;
    3. 重做日志不可用时(重做日志被需要,不能被覆盖的情形下),刷新脏页
  • InnoDB采用LSN(Log Sequence Number)来标记版本,每个页有LSN,重做日志也有LSN,CheckPoint也有LSN。

  • CheckPoint有两种:Sharp CheckPoint和Fuzzy CheckPoint

    1. Sharp CheckPoint发生在DB关闭时将所有脏页刷回磁盘;
    2. Fuzzy Checkpoint只刷新部分脏页,有四种方式,此处咱不讨论
-------------The End-------------