1.1 MySQL逻辑架构
image.png
- 最上层的服务并不是MySQL所独有的,大多数基于网络的客户端/服务器的工具或者服务都有类似的架构,比如连接处理、授权处理、安全等等
- 第二次架构是MySQL的核心服务功能所在,包括查询解析、分析、优化、缓存以及所有的内置函数(例如:日期、时间、数学加密函数),所有跨存储引擎的功能都在这一层实现:存储过程、触发器、视图
- 第三层包含了存储引擎。存储引擎负责MySQL数据的存储和提取,服务器通过API于存储引擎进行通信。这些接口屏蔽了不同存储引擎之间的差异。存储引擎API包含几十个底层函数,用于执行诸如”开始一个事务“或者”根据主键提取一行记录“等操作。但存储器不会去解析SQL,不同存储引擎之间也不会通信,只是简单的响应上层服务器的请求。
1.1.1 连接管理与安全性
每个客户端链接都会在服务器进程中拥有一个线程,这个连接的查询只会在这个线程中执行,该线程只能轮流在某个CUP核心或者CPU中允许。服务器会负责缓存线程,因为不需要为每个新建的链接创建或者销毁线程。
当客户端连接到MySQL服务器时,服务器需要进行认证,认证基于用户名、原始主机信息和密码。一旦客户端连接成功,服务器会继续验证客户端是否具有执行某个特定操作的权限。
1.1.2 优化与执行
MySQL会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的读取顺序,以及选择合适的索引等。用户可以通过特殊的关键字提示(hint)优化器,影响它的决策过程。也可以请求优化器解释(explain)优化过程的各个因素,使用户可以知道服务器是如何进行优化决策的,并提供一个参考基准,便于用户重构查询和schema(计划),修改相关配置,使尽可能高效运行。
对于select查询,在解析查询之前,服务器会先检查查询缓存(query cache),如果能够在其中找到对应的查询,服务器就不必再执行查询解析、优化和执行的整个过程,而是直接返回查询缓存中的结果集合。
1.2.并发控制
服务器层与层出引擎层的并发控制
1.2.1 读写锁
共享锁和排他锁也叫读锁和写锁
读锁是共享的,或者说叫互不阻塞的,写锁是排他的,写锁会其他的读锁和写锁。
1.2.2 锁粒度
表锁
最基本的锁策略,并且是开销最小的策略
行级锁
行级锁可以最大程序的支持并发处理,同时也带来了最大的锁开销。行级锁只会在存储引擎层实现,而在MySQL服务层没有实现。
1.3 事务
ACID
- 原子性(atomicity)一个事务必须被视为一个不可分割的最小工作单元
- 一致性(consistency)从一个一致性的状态到另外一个一致性的状态
- 隔离性(isolation)事务所做的修改,在其他的事务是不可见的
- 持久性(durability)一旦事务提交,则其所作的修改会永久保存到数据库中
1.3.1 隔离级别
-
未提交读(READ UNCOMMITTED)
事务中的修改,即使没提交,在其他事务中都是可见的,事务可以读取未提交的数据,也被成为脏读。 -
提交读(READ COMMITTED)
没提交前,在其他事务中都是不可见的,也叫不可重复读 -
可重复读(REPETABLE READ)
保证在同一个十五中多次读取同样的记录的结果是一致的,但是可能会导致出现幻读(MySQL的默认事务隔离级别,InnerDB通过多版本并发控制MVCC解决了幻读问题) -
可串行化(SERIALIZEBLE)
最高的隔离级别,强制事务串行执行,简单来说就是会在读取的每一行数据上加锁,所以可能会导致大量的超时和锁争斗的问题。
隔离级别 | 脏读可能性 | 不可重复性读可能性 | 幻读可能性 | 加锁读 |
---|---|---|---|---|
READ UNCOMMITTED | Yes | Yes | Yes | No |
READ COMMITTED | No | Yes | Yes | No |
REPETABLE READ | No | No | Yes | No |
SERIALIZEBLE | No | No | No | Yes |
1.3.2 死锁
两个或者多个事务在同一个资源上相互占用,并请求锁定对方占用的资源,从而导致恶心循环的现象。
InnerDB目前处理死锁的方法是将最少行级排他锁的事务进行回滚
1.3.3 事务日志
事务日志可以帮助提高事务的效率,使用事务日志,存储引擎在修改表的数据是只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不是每次都将修改的数本身持久到磁盘。
1.3.4 MySQL中的事务
自动提交(AUTOCOMMIT)
MySQL默认采用自动提交模式,如果不是显示开始一个事务,则每个查询都被当做一个事务执行提交操作。可以通过设置AUTOCOMMIT变量来启用或者禁用自动提交模式。
网友评论