美文网首页
InnoDB存储引擎 一

InnoDB存储引擎 一

作者: BitGuo | 来源:发表于2019-11-12 23:48 被阅读0次

    InnoDB基础架构


    InnoDB存储引擎具有多个内存块,组成一个内存池。
    内存池:

    • 维护所以进程线程需要访问的多个内部数据结构
    • 缓存磁盘文件数据,方便快速存取,同时对磁盘文件的数据修改之前在这里缓存
    • 重做日志 redo log 缓冲

    重要的后台线程

    1. Master Thread
      负责将数据异步刷新到磁盘,保证数据一致性
    2. IO Thread
      负责异步IO(AIO:Async IO)请求的回调。1.0版本的InnoDB共有4个IO:write,read,insert buffer,log IO Thread
    3. Purge Thread 清除/净化线程
      用来回收已经使用并分配的undo页
    4. Page Cleaner Thread
      负责将脏页的刷新操作放到单独的线程中完成

    内存

    1. 缓冲池
      InnoDB是基于磁盘存储的,缓冲池的作用在于弥补CPU速度和磁盘速度之间的鸿沟。(类比操作系统的CACHE

    缓冲池中存储的页类型有:索引页,数据页,undo页,插入缓冲(insert buffer),自适应哈希索引(adaptive hash index),InnoDB存储的锁信息(lock info),数据字典信息(data dictionary)。其中最主要的是索引页和数据页。

    1. 缓冲池管理
    • LRU:
      在InnoDB中,对LRU作了改进,最新读到的页并不直接放在队列首部,而是放在midpoint的位置,此算法称为midpoint insertion strategy。默认midpoint在LRU队列5/8处。在InnoDB中,把在midpoint之前的列表称为new列表,之后的列表称为old 列表,可以理解为new 列表是活跃的热点数据。
      为了管理LRU列表,InnoDB还有一个参数innodb_old_blocks_time,用于表示把页读取到mid位置后还要等待多久才会被加入表头热端。

    • Free List
      用于维持空闲页,LRU起初列表为空,申请时先看Free中有无空闲页,有则申请,无则淘汰LRU末尾页将其内存空间分配给新页。

    • Flush List
      脏页:在对LRU列表中的页进行修改之后,该页称为“脏页”,即缓冲区和磁盘上的页数据不一致。数据库会通过checkpoint机制把脏页刷新回磁盘。
      Flush列表中存储的页就是脏页。

    1. 重做日志缓冲
      redo log buffer
      独立于缓冲池的另外一个缓冲区,重做日志缓冲
      每秒刷新
      3种情况 发送刷新
      1.Master thread 每一秒将重做日志缓冲刷新到重做日志文件
      2.每个事务提交时会将重做日志刷新到重做日志文件
      3.当重做日志缓冲池剩余容量小于1/2时,刷新

    2. 额外内存池
      对数据结构本身(自身)存储的内存进行分配
      比如缓冲池中的一些对象如帧缓冲对象,缓冲控制对象等,这些对象存储了LRU 、锁以及等待信息。但是这些对象的内存需要从额外内存池获取。

    checkpoint技术

    write ahead log
    当事务提交时,先写重做日志,再修改页。防止当往磁盘刷写脏页时由于及其宕机造成数据不一致,数据丢失。保证ACID的D(durability 持久性)。

    Sharp checkpoint:发生在数据库关闭时,将所有的脏页都刷新回磁盘,这是默认的工作方式。

    Fuzzy checkpoint:InnoDB中会发生如下几种情况的Fuzzy checkpoint

    • Master Thread checkpint
    • FLUSH_LRU_LISTcheckpoint
    • Async/Sync Flush checkpoint
    • Dirty Page too much checkpoint

    Master Thread的工作方式

    InnoDB 1.0xx版本之前的Master Thread

    首先明确在主线程中包括几个主要的循环

    • loop 主循环
    • background loop 后台
    • flush loop
    • suspend loop 挂起循环
    Master Thread 的工作机制伪代码
    void master_thread(){
      goto loop;
    loop:
    for(int i=0;i<10;i++){
    //循环内为每秒钟执行的动作,主循环中操作分两类:1.每秒 2.每十秒
      thread_sleep(1)//sleep 1 second
      do log buffer flush to disk; //每秒都做
      if (last_one_second_ios<5)//如果前一秒的IO操作小于5次,那么就认为IO压力小,执行并行插入缓冲区
       do merge at most 5 insert buffer
      if (buf_get_modified_ratio_pct>innodb_max_dirty_pages_pct)
        //innodb_max_dirty_pages_pct是系统设置的脏页比例 默认为90%
        //如果缓冲池中脏页比例大于90%,则InnoDB存储引擎认为需要进行磁盘同步操作,将100个脏页写入磁盘
        do buffer pool flush 100 dirty page
      if (no user activity)
        goto background loop
     }
    if(last_ten_second_ios<200)//此时跳出上面的for循环 表示下面是每10秒要进行的操作,此处是指如果过去10秒的io次数小于200,那么就磁盘刷写100页脏页
      do buffer pool flush 100 dirty page
    //下面这三个是每10秒都要无条件执行的
    do merge at most 5 insert buffer
    do log buffer flush to disk
    do full purge//将无用的undo页删除
    if(buf_get_modified_ratio_pct>70%)
      do buffer pool flush 100 dirty page
    else
      do pool flush 10 dirty page
    goto loop //继续第二个 为期11秒的循环(10+1)
    background  loop:
    do full purge // 删除无用的undo页
    do merge 20 insert buffer//合并插入20个缓冲区
    if not idle://如果不空闲了 跳回主循环
      goto loop
    else:
      goto flush loop
    flush loop:
    do buffer pool flush 100 dirty page
    if (buf_get_modified_ratio_pct>innodb_max_dirty_pages_pct)
      goto flush loop
    goto suspend loop
    suspend loop:
     suspend_thread()
    wating event
    goto loop;
    
    }
    }
    

    相关文章

      网友评论

          本文标题:InnoDB存储引擎 一

          本文链接:https://www.haomeiwen.com/subject/fmrcictx.html