【高性能MySQL】第一章 MySQL架构

1.1 MySQL逻辑架构

MySQL最与众不同的是它的存储引擎架构,这种架构将查询处理(Query Processing)及其他的系统任务(Server Task)和数据的存储/提取相分离。
MySQL用于分层的架构,上层是服务器层的服务和查询执行引擎,下层则是存储引擎。
在这里插入图片描述
第一层关注的是连接处理、授权管理、安全等等。
第二层是MySQL核心的部分。大部分的MySQL核心服务都在这一层。包括查询解析、分析、优化、缓存以及所有的内置函数都在这一层。所有跨存储引擎的功能都在这一层实现:存储过程,触发器,视图。
第三层包含了存储引擎。存储引擎负责MySQL中的数据存储和提取。各个存储引擎各有特点,服务器通过API与存储引擎通信。这些接口屏蔽了不同存储引擎之间的差异。

1.1.1 连接管理与安全性

每个客户端连接都会在服务器进程中拥有一个线程,该连接的查询只会在这个单独的线程中执行,该线程只能轮流在某个CPU核心或者CPU中运行。
服务器会负责缓存线程,因此不需要为每一个新建的创建或者销毁线程。
当客户端(应用)连接到MySQL服务器时,服务器需要对其进行认证。认证基于用户名、主机信息和密码。一旦连接成功,服务器还会验证该客户端是否具有某个特定查询的权限。

优化与执行

MySQL会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询,决定表的读取顺序,以及选择合适的索引等
用户可以通过特殊的关键字提示(hint)优化器,影响他的决策过程。也可以请求优化器解释(explain)优化过程的各个因素,使用户可以知道服务器是如何进行优化决策的,并提供一个参考基准,便于用户重构查询和schema(对于MySQL下的schema,可以理解成就是存储数据的地方)、修改相关配置,使应用尽可能高效运行。
优化器并不关心表使用的是什么存储引擎,但存储引擎对于优化查询是有影响的。优化器会起请求存储引擎提供容量或某个具体操作的开销信息,以及表数据的统计信息等。
对于SELECT语句,在解析查询之前,服务器会先检查缓存(Query cache),如果能够在其中找到对应的查询,服务器就不必在执行查询解析、优化和执行的整个过程,而是直接返回查询缓存中的结果集。

1.2 并发控制

无论何时,只要有多个查询需要在同一时刻修改数据,都会产生并发控制的问题。
假如一个用户正在读取表中的数据,而另一个数据正在试图删除该表中的一条记录,会导致数据的不一致性。

1.2.1 读写锁

解决上面这个问题的方式就是通过并发控制。
在处理并发读或写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题。
这两种类型的锁通常被称为共享锁(shared lock)和排他锁(exclusive lock),也称为读锁(read lock)和写锁(write lock)。

概念如下

  • 读锁是共享的,也就是相互不阻塞的。多个用户可以在同一时刻同时读取同一个资源而互不干扰
  • 写锁是排他的,也就是一个写锁会阻塞其他的写锁和读锁。这样才能确保一个时刻只有一个用户能执行写入,并防止其他的用户读取正在写入的同一资源

1.2.2 锁粒度

一种提高共享资源并发性的方式就是让锁定对象更有选择性。尽量只锁定需要修改的部分,而不是所有的资源。更理想的也就是精确的锁定。锁定的数据量越少,则系统的并发程度就越高。
所谓的锁策略指的就是在锁的开销和数据的安全性之间寻求平衡。MySQL提供了多种选择,每种存储引擎都可以实现自己的锁策略和锁粒度。
下面将介绍两种最重要的锁策略

表锁(table lock)

表锁是MySQL最基本的锁策略,也是开销最小的策略。
它会锁定整张表,一个用户在对表进行写操作的时候,需要先获得写锁。这会阻塞其他用户的所有读写操作。只有没有写锁的时候,其他读取的用户才能获得该锁,读锁之间是不相互阻塞的

行级锁(row lock)

行级锁会最大程度的支持并发(同时也带来了最大的锁开销)

1.3 事务

事务就是一组原子性的SQL查询,或者说一个独立的工作单元。事务中的语句,要么全部执行成功,如果任意一条语句执行失败,则所有的语句都不会执行。
事务具有四个基本特性(ACID)

  • 原子性(Atomicity) 一个事务必须被视为一个不可分割的最小工作单元
  • 一致性(Consistency) 数据库总是从一个一致性的状态转换到另外一个一致性的状态
  • 隔离性(Isolation) 通常来说,一个事务所做的修改在最终提交之前,对其他事务是不可见的
  • 持久性(Durability) 一旦事务提交,其所做的修改就会永久地保存到数据库中

1.3.1 隔离级别

SQL标准中定义了四种隔离级别。每一种级别都定义了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的。
较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

READ UNCOMMITTED (读未提交)

隔离级别最低的一种。该级别中,事务中的修改,即使没有修改,对其他事务也都是可见的。如果另一个事务回滚,那么当前事务读到的数据就是脏数据,这就是脏读(Dirty Read)。

READ COMMITTED (读提交)

大多数数据库默认的隔离级别都是READ COMMITTED,但MySQL不是。
在该级别中,一个事务开始时,只能看见已经提交的事务所做的修改。
READ COMMITTED可能会出现不可重复读的情况,指的是事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。

REPEATABLE READ (可重复读)

该级别中解决了脏读的问题,该级别中保证了在一个事务中多次读取同样记录的结果是一直的。也就是可重复读。
但是理论上,不能解决幻读的问题。所谓的幻读就是当某个事务在读取某个范围的记录时,另外一个事务又在该范围内插入了新的记录。当之前的事务再次读取该范围的数据的时候会出现幻行(Phantom Row)。InnoDB存储引擎会通过多版本并发控制(MVCC)解决了幻读的问题。
可重复读是MySQL的默认事务隔离级别。

SERALIZABLE (串行化)

SERALIZABLE (串行化)是最高的隔离级别。它通过强制事务串行执行,避免了幻读的问题。简单来说,SERALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。

隔离级别脏读不可重复读幻读加锁读
READ UNCOMMITTEDYesYesYesNo
READ COMMITTEDNoYesYesNo
REPEATABLE READNoNoYesNo
SERALIZABLENoNoNoYes

1.3.2 死锁

死锁指的是两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。
多个事务以不同的顺序锁定资源,或者多个事务同时锁定同一个资源时,也会产生死锁。

数据库系统中实现了各种死锁检测和死锁超时机制。或者当查询时间超过锁等待超时的设定后放弃锁请求。InnoDB目前的处理方法是,将持有最少行级排他锁的事务进行回滚。

1.4 多版本并发控制

MySQL中大部分事务型存储引擎实现的都不是简单的行级锁。它们一般都实现了多版本并发控制(MVCC),但是实现的机制不尽相同。
可以认为MVCC是行级锁的一个变种,但是在很多情况下避免了加锁操作,因此开销更低。
MVCC的实现是通过保存数据在某个时间点的快照来实现的。
而InnoDB中的MVCC是通过在每行记录后面保存两个隐藏的列来实现的。这两个列一个保存了行的创建时间,一个保存了行的过期时间。存储的是系统版本号。

1.5 MySQL的存储引擎

在文件系统中,MySQL会将每个数据库(也可以称为Schema)保存为数据目录下的一个子目录。创建表时,会在子目录下创建一个和表同名的.frm文件。

InnoDB存储引擎

大部分情况下InnoDB都是正确的存储引擎选择。
InnoDB存储引擎是MySQL的默认事务型引擎,也是最重要的,使用最广泛的存储引擎。它被设计来处理大量的短期事务,短期事务大部分情况下是正常提交的,很少被回滚。具有自动恢复功能。
InnoDB的数据存储在表空间中。
InnoDB采样MVCC来支持高并发,并且实现了四个标注的隔离级别。默认级别是REPEATABLE READ.并且通过间隙锁来防止幻读。
InnoDB表是基于聚簇索引建立的,聚簇索引对主键查询有很高的性能。

MyISAM存储引擎

MyISAM提供了大量的特性,包括全文索引,压缩等,但是不支持事务和行级锁,最致命的是崩溃后不能安全恢复。
MyISAM是对整张表加锁,而不是针对行。读取时会对需要读到的所有表加共享锁。写入时则对表加排他锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值