MySQL服务器逻辑架构

MySQL服务器逻辑架构

MySQL服务器逻辑架构图

MySQL服务器逻辑架构
MySQL服务器的逻辑架构采用的是分层架构

  • 最上层主要负责连接管理与安全性,MySQL客户端与服务端的通信连接管理以及用户名密码、对数据库及表的权限校验,都是在这一层完成的
  • 第二层包括MySQL核心服务功能,像查询解析、分析、优化、缓存、所有的内置函数以及所有跨存储引擎的功能(存储过程、触发器、视图等)都在这一层
  • 第三层就是存储引擎层,存储引擎负责数据的存储和提取,服务器通过一套标准的API可以和不同的存储引擎进行通信,这些API屏蔽了不同存储引擎之间的差异

第二层的组件解析器及优化器会对查询进行解析,并创建内部数据结构(解析树),然后优化器对查询进行优化,包括重写查询、决定表的读取顺序以及选择合适的索引等;
用户可以通过 explain 命令来请求优化器解释优化过程的各个因素,使得用户大概知道服务器是如何进行优化决策的,并提供一个参考基准,便于用户对查询进行性能调校;
如果对优化器的优化结果不满意,用户可以通过优化器预留的有限的关键字来提示优化器该怎么决策。

对于SELECT查询,在解析查询之前,服务器会先检查查询缓存(Query Cache), 如果能够在其中找到对应结果,服务器就不必继续解析优化执行的流程,而是直接返回查询缓存中的结果集

MySQL进程模型

MySQL服务器逻辑架构

  • MySQL早期采用的是每个DBMS工作者拥有一个系统线程的模型
  • 版本5.6之后,提供了对线程池的支持;使得MySQL能通过少量的线程服务大量的连接

并发控制

MySQL是通过读写锁来控制并发的

  • 读锁是共享锁,是互不阻塞的;多个客户端在同一时刻可以同时读取同一资源而不互相干扰
  • 写锁是排他的,一个写锁会阻塞其它的写锁和读锁,这是出于安全策略的考虑,只有这样,才能确保在给定的时间里,只有一个用户能够执行写入,并防止其他用户读取正在写入的统一资源
  • MySQL存储引擎都可以实现自己的锁策略和锁粒度,锁管理也非常耗费资源,最终的锁策略都是在锁开销和数据安全性以及实际的应用需求之间寻求平衡
  • 最常见的锁策略是表锁和行锁,5.6版本之后,InnoDB还提供了间隙锁

MySQL事务

  • 隔离级别, READ UNCOMMITED(读未提交)、READ COMMITED(读已提交)、REPEATABLE READ(可重复读)、SERIALIZABLE(可串行化);MySQL默认的事务隔离级别是可重复读,而在生产中,很多公司DBA都采用的是读已提交这一隔离级别
  • 死锁,当多个事务以不同的顺序锁定资源时,如果资源有重叠,就会各自等待对方释放资源,造成死锁;InnoDB目前处理死锁的方法是,将持有最少行级排他锁的事务进行回滚
  • 事务日志,存储引擎不会在每次数据修改时都直接将修改的数据持久化到磁盘,而是将修改记录持久到事务日志中,然后在后台可以按照事务日志顺序批量刷回磁盘;如果数据已经进入事务日志,但还没有刷回磁盘的时候,存储引擎崩溃,重启存储引擎,可以自动恢复这部分数据

多版本并发控制(MVVC)

MySQL的大多数事务型存储引擎实现的都不是简单的行级锁,基于提升并发性能的考虑,它们都同时实现了多版本并发控制(MVVC)
可以认为MVVC是行级锁的一个变种,它在很多情况下避免了加锁操作,因此减小了开销;MVVC是通过保存数据再某一个时间点的快照来实现的。
MVCC只在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下工作,InnoDB的MVVC是在每行元数据后面增加三个隐藏的列配合undo-log来实现的

  • 6字节DB_TRX_ID字段指示插入或更新行的最后一个事务的事务标识符
  • 7字节DB_ROLL_PTR称为滚动指针,roll指针指向写入回滚段的撤消日志记录
  • 6字节的DB_ROW_ID字段包含一个行ID,当插入新行时,该行ID会单调增加

在REPEATABLE READ(可重复读)隔离级别下,MVVC的操作过程如下:

  • SELECT
    InnoDB会根据以下两个条件检查每行记录:
    • InnoDB只查找版本早于当前事务版本的数据行,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的
    • 行的删除版本要么未定义,要么大于当前的事务版本号,这可以确保事务读取到的行,在事务开始之前未被删除
      只有符合上述两个条件的记录,才能返回作为查询结果
  • INSERT
    InnoDB为新插入的每一行保存当前系统版本号作为行版本号
  • DELETE
    InnoDB为删除的每一行保存当前系统版本号作为删除标识
  • UPDATE
    InnoDB对修改的操作是,插入一行新记录,保存当前系统版本号作为行版本号,同事保存当前版本号到原来的行作为删除标识

MySQL的存储引擎

MySQL版本5.6之后,默认的存储引擎是InnoDB

  • 如非有特殊需要,一般都选择默认存储引擎,InnoDB在事务支持、并发控制、索引等方面都表现的相当优秀
  • MyISAM存储引擎不支持事务和行级锁,崩溃后无法安全恢复,但MyISAM也提供了大量不错的特性,包括全文索引,压缩存储,空间函数等,在特定的场合,还是有一定的优势的

参考文献