InnoDB引擎

此文章是 《MySQL技术内幕:InnoDB存储引擎(第2版)》 一书的学习笔记,感兴趣的小伙伴可以自己买书学习。

InnoDB 中数据库和数据库实例的区别

在 mysql 中,数据库和数据库实例是有区别的,数据库指的是数据库文件,数据库实例是运行起来的数据库软件,用户通过数据库实例操作数据库,而非直接操作数据库。也就是说虽然数据库是文件,但是对数据库的一些操作并不一定就是很慢的磁盘IO。

InnoDB 是一个单进程多线程的数据库

InnoDB 是多线程的模型,通过下面的这些后台线程,对数据库进行操作。

  • Master Thread 主要负责将缓存池中的数据异步刷新到磁盘。这个线程下有多种循环,InnoDB 根据不同的情况切换不同的循环
    • 主循环 loop
    • 后台循环 background loop
    • 刷新循环 flush loop
    • 暂停循环 suspendloop
  • Io Thread ,InnoDB 通过 AIO 进行异步IO操作, Io Thread 负责处理这个异步 IO 的回调
  • Purge Thread, InnoDB 1.1 版本后增加的, 负责在事务处理后,回收事务产生的 undolog
  • Page Cleaner Thread, InnoDB 1.2 版本后增加的,负责刷新脏页。

InnoDB 内存分配

主要由下面几个部分组成

  • 缓冲池
  • LRU List、Free List和Flush List
  • 重做日志缓存
  • 额外的内存池,主要用来内存管理,内存管理也需要内存进行操作。

InnoDB 缓存池

InnoDB对数据的操作首先都是在缓冲池完成的,在查询的时候首先判断该页是否在缓冲池中。修改的时候先更新缓冲池中的页,然后通过 ckeckpoint 机制将数据页刷新回磁盘。缓存池中主要包含下面这些部分:

  • 索引页
  • 数据页
  • undo 页
  • 插入缓冲 insert buffer
  • 自适应哈希索引 adaptive hash index
  • 存储的锁信息 lock info
  • 数据字典信息 data dictionary

InnoDB 的checkpoint 机制

正常数据发生修改时,数据库实例会先写入重做日志缓存,然后再写入磁盘。但是如果每一个缓存页发生更新时都马上写入磁盘,那么开销是特别大的,某些情况下会影响数据库实例的性能。所以只有当缓存池不够用的时候,再将缓存池中的脏页(与磁盘不一致的页)写入磁盘。这里 checkpoint 解决的问题主要是以下几点。

  • 缩短数据库的恢复时间。 当服务器宕机时,服务器不需要重做所有的日志,只重做 checkpoint 之后的就可以
  • 缓冲池不够用时,将脏页刷新到磁盘
  • 重做日志不可用时,刷新脏页。比如重做日志很大了, 需要清理重做日志,在清理重做日志之前,需要将缓存池中的脏页刷新到当前重做日志的位置, 避免数据无法恢复。

InnoDB 的 AIO

前面提到了 InnoDB 是通过 AIO (Asyncchronous IO) 的方式进行磁盘操作, 和同步IO (Sync IO) 的区别在于,异步IO不用等上一次的操作结果返回就能立即进行下一个操作,比如同时发出10个IO请求然后再等待10个请求完成。AIO 还有一个好处是 InnoDB可以有选择性的合并IO, 比如AIO判断有多次IO请求操作的页是连续的,那么AIO就会合并到一个IO里。使用AIO据说可以使查询速度提高 75% 。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!