mysql技术内幕之innodb简介

本系列是mysql技术内幕-innodb存储引擎一书的笔记总结

一、Innodb存储引擎

1.1 体系架构

1.1.数据库文件

.frm: myisam和innodb存储引擎的表结构文件
.MYI: myisam存储引擎的表索引文件
.MYD: myisam存储引擎的表数据文件
.ibd: innodb存储引擎的索引文件和数据文件

mysql是单进程多线程架构,插件式存储引擎,存储引擎是基于表的
每张表的存储是按主键顺序进行存放,若没显式指定主键,会字动生成6字节rowid作为主键
myisam只缓存索引文件,数据文件的缓存由操作系统负责

mysql> show engines\G 

1.2主要线程介绍

  • 1.2.1 后台线程

    • 作用:刷新内存池中数据,将修改的数据刷写到磁盘,保证mysql异常情况下能恢复到正常运行状态

    • master thread:核心后台线程,将缓冲池中数据异步刷新到磁盘,保证数据一致性

    • io thread:使用了aio来处理写io请求,负责io请求回调处理

      
                 > show variables like 'innodb_%io_threads';
                  +-------------------------+-------+
                  | Variable_name           | Value |
                  +-------------------------+-------+
                  | innodb_read_io_threads  | 4     |
                  | innodb_write_io_threads | 4     |
                  +-------------------------+-------+
                 > show engine innodb status\G   查看io thread情况
      
                  I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
                  I/O thread 1 state: waiting for completed aio requests (log thread)
                  I/O thread 2 state: waiting for completed aio requests (read thread)
                  I/O thread 3 state: waiting for completed aio requests (read thread)
                  I/O thread 4 state: waiting for completed aio requests (read thread)
                  I/O thread 5 state: waiting for completed aio requests (read thread)
                  I/O thread 6 state: waiting for completed aio requests (write thread)
                  I/O thread 7 state: waiting for completed aio requests (write thread)
                  I/O thread 8 state: waiting for completed aio requests (write thread)
                  I/O thread 9 state: waiting for completed aio requests (write thread)
    • purge thread:作用是用来回收已经使用并分配的undo页,老版本该线程在master thread中,新版本可以使用独立的,需要在配置文件中设置

      innodb_purge_threads=1
      > show variables like 'innodb_purge_threads';
          +----------------------+-------+
          | Variable_name        | Value |
          +----------------------+-------+
          | innodb_purge_threads | 4     |
          +----------------------+-------+
    • page cleaner thread: 从master thread中独立出来,负责脏页刷新

1.3 内存

  • 1.3.1 缓冲池

    • 对页的修改,先修改缓冲池中的页,再以一定频率刷写到磁盘

    • 刷写磁盘通过checkpoint机制完成

    • 缓冲池中缓存的类型有:索引页,数据页,undo页,insert buffer,自适应哈希索引,锁信息,数据字典信息等

    • 允许多个缓冲池,默认是1个

      > show variables like 'innodb_buffer_pool_instances';
      > show engine innodb status\G   查看目前缓冲池情况
      也可以通过information_schema中的innodb_buffer_pool_stats表查看缓存状态
    • 缓冲池管理使用改进的LRU算法

    • 脏页:缓冲池中数据与磁盘数据不一样

  • 1.3.2 redo log buffer

    • 一般不需要设置太大,一般每秒钟刷新一次redo log buffer到redo log中,该值大小由innodb_log_buffer_size,默认8mb
    • 以下三种情况,会将buffer中内容刷写到磁盘redo log中
      • master thread每秒钟会刷写一次
      • 每个事务提交时会刷写
      • 当redo log buffer 剩余空间小于1/2,会刷写
  • 1.3.2 额外内存池

    • innodb对内存管理使用内存堆方式

1.4 checkpoint技术

  • 为避免在缓冲中刷写磁盘时发生宕机,数据库普遍采用write ahead log策略,即当事务提交时,先写重做日志,再修改页。一旦宕机,通过redo log来完成数据恢复,这是acid中持久性的要求
  • check point解决以下问题:
    • 缩短数据库恢复时间
    • 缓冲池不够时,将脏页刷写到磁盘
    • 重做日志不可用,刷新脏页
  • 数据库宕机,只需对checkpoint后的重做日志进行恢复,
  • 当进行LRU时,溢出的页若为脏页,那就要强制执行checkpoint,将脏页刷写到磁盘
  • 重做日志是循环使用的,不需要的数据可以被覆盖
  • innodb通过lsn来标记版本,重做日志,每个页,checkpoint都有lsn,可以通过show engine innodb status来查看
  • 有两种checkpoint:
    • sharp checkpoint:在数据库关闭时将所有脏页都刷写到磁盘,这是默认的,即innodb_fast_shutdown=1
    • fuzzy checkpoint:但在数据库运行时也使用sharp checkpoint,数据库可用性会收很大影响,此时使用fuzzy checkpoint进行页刷新,只刷新部分脏页,而不是所有脏页
      • 以下情况会发生fuzzy checkpoint:
        • master thread checkpoint
        • flush_lru_list checkpoint
        • Async/sync flush checkpoint
        • dirty page too much chekpoint: innodb_max_dirty_pages_pct参数控制,当脏页数大于该参数值,强制checkpoint,刷新一部分脏页到磁盘

1.5 innodb关键特性

  • insert buffer:在innodb中,主键是行唯一的标识符,行插入顺序是按主键递增的顺序插入,并不是所有主键插入都是顺序的,插入聚集索引一般是按顺序的,不需要磁盘的随机读取,一张表也会有辅助索引,这些索引插入不一定是顺序的

    • 对于非聚集索引的插入或更新,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引是否在缓冲池中,在就直接插入,不在,则先放入一个insert buffer对象中
    • insert buffer使用需要同时满足两个条件:索引是辅助索引,索引不是唯一的
  • change buffer:引入inset buffer,delete buffer, purge buffer

  • 两次写:doublewrite

    • 数据库宕机,会通过重做日志进行恢复,但redo log中记录的是对页的物理操作,如偏移量800,写‘aaa’记录,如果这个页本身发生损坏,再进行重做是没意义的
    • 双写就是在apply重做日志之前,需要一个页的副本,当写入失效,先通过页的副本来还原该页,再进行重做
    • innodb_doublewrite 可以设置是否使用doublewrite,在从服务器需要较快性能,可以关闭,需要数据高可靠性的数据库上应该开启此参数,如果文件系统提供了写失效的防范机制,也可以关闭
  • 异步io

    1.6 重要参数

innodb_fast_shutdown
  0:数据库关闭时,innodb需要完成所有的full purge和merge insert buffer操作,并将所有脏页刷写到磁盘。这需要一定时间,若进行innodb升级,必须设置为0,然后在关闭数据库
  1:默认值,不需要完成full purge和merge insert buffer操作,但脏数据要刷写到磁盘
  2: 不完成full purge和merge insert buffer操作,也不将脏页写入磁盘,而是写入日志文件。这样没有任何事务丢失,下次启动数据库,会进行恢复操作
  某些情况,不需要进行完整恢复,如用户直到如何恢复,进行完整恢复时间会很长,这时可以用户自己进行恢复

innodb_force_recovery:
  0:默认为0,当发生需要恢复操作时,进行所有恢复操作,当不能有效恢复,如mysql crash,把错误写入到错误日志
  1:忽略检查到的corrupt页
  2:阻止master thread线程的运行,如master thread需要进行full purge,而这会导致mysql crash
  3:不进行事务回滚操作
  4:不进行insert buffer的合并操作
  5:不查看undolog,innodb会将未提交的事务视为已提交
  6:不进行前滚操作

  设置大于0的值,可以对表进行select,create,drop。但insert,update,delete操作

文章作者: BY 木易杨
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 BY 木易杨 !
评论
 上一篇
restful相关知识 restful相关知识
一、Restfull介绍 参考资料: https://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html 此系列是python框架学习系列,根据相关资料学习整理
2020-10-26 BY Jemmy yang
下一篇 
mysql技术内幕之备份恢复 mysql技术内幕之备份恢复
备份与恢复1.1 备份类型 按备份方法划分 hot backup:在线备份 cold backup:停止数据库备份 warm backup:在线备份,但会对数据库操作有影响,例如加全局读锁,保证数据一致性 按备份文件内容分: 逻辑备份:
2020-05-26 BY 木易杨