0 - 引子

作为一名应用后端开发,工作中最常打交道的关系型数据库非mysql莫属。基本所有业务相关数据都作为一张张表留存在mysql数据库中,这些数据借助其ACID特性安全地躺在硬盘,ssd或别的什么存储介质里。mysql对业务是如此重要,因此后端开发很有必要掌握合理操作mysql的方式。当然,很多开发朋友会说,我会用mysql的,主要就是以下几点:

  • 针对需求建表
  • 加合适的索引
  • 查询时按索引查
  • 需要事务保护时开启事务
  • 尽量少用join而是放在业务代码里处理

这些我都掌握,我还有必要继续了解mysql吗?这个答案可能因人而异,我是这么理解的:

工具是为了简化流程诞生的,知其然而后合理运用工具以提高效率是基础。如果能知其所以然,那么运用起来会更得心应手,就像相机之于摄影师,高端的摄影师不会局限于几个大众化的参数,其必然对成像原理和手中的相机非常了解,才能为不同场合挑选最合适的参数。

在以上思考的契机下,前日拜读了《mysql技术内幕innodb存储引擎》,该书对最常用存储引擎innodb展开了全面的介绍,不同于网络上零散的知识,其有助于读者将知识串在一起加深理解。本文将对此书内容进行归纳汇总,对我自己也是一次不可多得的复习机会。

1 - mysql体系和存储引擎

mysql的组成

  • 连接池组件:和mysql客户端交互,支持tcp/ip,命名管道,共享内存和unix domain socket
  • 管理者和管理工具组件:操作各个组件进行管理
  • sql 接口组件: 未知,处理DML,DDL等?
  • 解析器,优化器,缓存组件:解析查询,挑选执行方案,缓存查询内容
  • 存储引擎:插件式,满足不同需求
  • 存储介质上的物理文件:持久化数据

有哪些常见存储引擎

  • innodb:最常用的存储引擎,支持事务,行锁,面向OLTP
  • myISAM:mysql自带的另一个存储引擎,不支持事务,面向OLAP
  • memory:内存级数据库
  • archive:只新增数据,适合处理归档数据
  • ndb:存储集群

上述存储引擎间的部分区别:

存储引擎事务锁粒度mvcc索引
innodb支持行锁支持b+,hash,全文
myISAM不支持表锁不支持b+,全文
archive不支持行锁支持
memory不支持表锁不支持b+,hash
ndb不支持行锁支持b+,hash

2 - innodb概述

innodb 构成

  • 后台线程:主要负责执行IO,管理内存池中的数据

    • 将赃页持久化
    • 将redo log缓冲持久化
    • 合并插入缓冲
    • 清理undo log
  • 内存池

    • buffer_pool

      • 数据页
      • 索引页
      • 插入缓冲
      • 锁信息
    • redo log buffer
    • undo log
  • 物理文件

buffer_pool中的内存页如何管理

通过LRU保留最新的页,其中有一个优化点:新加入的页只会被放到队列的某个中间位置,以减少热点页被刷出的概率。

redo log buffer

重做日志什么时候产生?
重做日志的内容是?

重做日志不直接写到文件中,而是先写到缓冲再写入文件
写入时机如下:

  1. 后台线程定时刷入文件
  2. 事务提交时刷入文件
  3. 缓冲空间不足一半时,刷入文件

如何保证数据持久化 - Checkpoint

WHY: 突然宕机如何保护内存中还未写入磁盘的赃页数据?

WHAT: checkpoint本质是通过有限的redo log文件大小,来维护最近一次可用存档点,其核心思路是通过同步维护增量更新+异步维护全量更新来完成。(同利用消息队列进行事件缓冲有异曲同工之妙)

HOW:

  1. write ahead log,事务运行过程,先写redo log,再对页进行修改
  2. 维护log sequence number,redo log和被修改的页都持有最新的lsn
  3. 重做日志是循环写入,可能会覆盖之前写入的lsn,在覆盖前,需要将内存中之前的赃页刷入文件
  4. 当mysql从宕机中恢复时,可以通过redo log来完成数据恢复

关键特性 - 插入缓冲(insert buffer, delete buffer, purge buffer)

WHY: 辅助索引的插入不是顺序的,需要离散地访问辅助索引页,为了避免这种离散访问,临时将索引放在插入缓冲中。需要满足以下几个条件:

  1. 是辅助索引
  2. 不是唯一索引
  3. 待插入索引页不在内存中

HOW: 插入缓冲存放在一个全局b+树中,在以下几个节点会合并到索引页上:

  1. 索引页被读到内存中
  2. 索引页空间不足
  3. 后台线程定时合并

关键特性 - 两次写

WHY: 避免宕机时,中断正在写入的过程,导致一个页部分写入失败,造成数据损坏
HOW: 刷入磁盘时,并不直接写入磁盘中,而是先写入双写缓冲中,待缓冲写满,先将缓冲顺序写入一个缓冲文件,再将数据离散地写入。

关键特性 - 自适应哈希

根据查询情况,对热点数据自适应建立临时哈希索引


iamrockrepublic
1 声望0 粉丝