MySql运行机制原理和架构

原文地址:MySQL运行机制原理&架构

主要补充了一些事务隔离级别会带来的问题以及可以避免什么问题,还有就是MYSQL内部优化语法树的规则。

目录

一、MySQL知识普及

二、MySQL逻辑架构

三、并发控制和锁的概念

四、事务

五、MySQL存储引擎及应用方案


一、MySQL知识普及

MySQL是一个开放源代码的关系数据库管理系统。

MySQL架构可以在多种不同场景中应用并发挥良好作用。主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离。

二、MySQL逻辑架构

1.Connectors

MySQL首先是一个网络程序,其在TCP之上定义了自己的应用层协议。所以要使用MySQL,我们可以编写代码,跟MySQL Server建立TCP连接,之后按照其定义好的协议进行交互。当然这样比较麻烦,比较方便的办法是调用SDK,比如Native C API、JDBC、PHP等各语言MySQL Connector,或者通过ODBC。但通过SDK来访问MySQL,本质上还是在TCP连接上通过MySQL协议跟MySQL进行交互。

2.Connection Management

每一个基于TCP的网络服务都需要管理客户端链接,MySQL也不例外。MySQL会为每一个连接绑定一个线程,之后这个连接上的所有查询都在这个线程中执行。为了避免频繁创建和销毁线程带来开销,MySQL通常会缓存线程或者使用线程池,从而避免频繁的创建和销毁线程。

客户端连接到MySQL后,在使用MySQL的功能之前,需要进行认证,认证基于用户名、主机名、密码。如果用了SSL或者TLS的方式进行连接,还会进行证书认证。

3.SQL Interface

MySQL支持DML(数据操作语言)、DDL(数据定义语言)、存储过程、视图、触发器、自定义函数等多种SQL语言接口。

4.Parser

MySQL会解析SQL查询,并为其创建语法树,并根据数据字典丰富查询语法树,会验证该客户端是否具有执行该查询的权限。创建好语法树后,MySQL还会对SQl查询进行语法上的优化,进行查询重写。

关于MySql如何对语法树进行优化,可以参考这篇文章(MySql内部如何优化SQL语句),在查询优化器中,分别讲述了逻辑优化和物理优化的规则,包括MySql遇见关键字like、group by、函数等优化的规则,下面是一些例子:

5.Optimizer

语法解析和查询重写之后,MySQL会根据语法树和数据的统计信息对SQL进行优化,包括决定表的读取顺序、选择合适的索引等,最终生成SQL的具体执行步骤。这些具体的执行步骤里真正的数据操作都是通过预先定义好的存储引擎API来进行的,与具体的存储引擎实现无关。

6.Caches & Buffers

MySQL内部维持着一些Cache和Buffer,比如Query Cache用来缓存一条Select语句的执行结果,如果能够在其中找到对应的查询结果,那么就不必再进行查询解析、优化和执行的整个过程了。

7.Pluggable Storage Engine

存储引擎的具体实现,这些存储引擎都实现了MySQl定义好的存储引擎API的部分或者全部。MySQL可以动态安装或移除存储引擎,可以有多种存储引擎同时存在,可以为每个Table设置不同的存储引擎。存储引擎负责在文件系统之上,管理表的数据、索引的实际内容,同时也会管理运行时的Cache、Buffer、事务、Log等数据和功能。

三、并发控制和锁的概念

当数据库中有多个操作需要修改同一数据时,不可避免的会产生数据的脏读。这时就需要数据库具有良好的并发控制能力,这一切在MySQL中都是由服务器和存储引擎来实现的。

解决并发问题最有效的方案是引入了锁的机制,锁在功能上分为共享锁(shared lock)和排它锁(exclusive lock)即通常说的读锁和写锁。当一个select语句在执行时可以施加读锁,这样就可以允许其它的select操作进行,因为在这个过程中数据信息是不会被改变的这样就能够提高数据库的运行效率。当需要对数据更新时,就需要施加写锁了,不在允许其它的操作进行,以免产生数据的脏读和幻读。锁同样有粒度大小,有表级锁(table lock)和行级锁(row lock),分别在数据操作的过程中完成行的锁定和表的锁定。这些根据不同的存储引擎所具有的特性也是不一样的。

死锁:两个或多个事务在同一资源上相互占用并请求锁定对方占用的资源,从而导致恶性循环的现象。
对于死锁的处理:MySQL的部分存储引擎能够检测到死锁的循环依赖并产生相应的错误。InnoDB引擎解决的死锁的方案是将持有最少写锁的事务进行回滚。
为了提供回滚或者撤销未提交的变化的能力,许多数据源采用日志机制。例如:sql server使用一个预写事务日志,在将数据应用于(或提交到)实际数据页面前,先写在事务日志上。但是,其他一些数据源不是关系型数据库管理系统,他们管理未提交事务的方式完全不同。只要事务回滚时,数据源可以撤销所有未提交的改变,那么这种技术可用于事务管理。

MySQL大多数事务型的存储引擎都不只是简单的行级锁,基于性能的考虑,他们一般在行级锁基础上实现了多版本并发控制(MVCC)。这一方案也被Oracle等主流的关系数据库采用。它是通过保存数据中某个时间点的快照来实现的,这样就保证了每个事务看到的数据都是一致的。详细的实现原理可以参考《高性能MySQL》第三版。

四、事务

1.事务具有ACID的特性:
1)原子性:
事务中的所有操作要么全部提交成功,要么全部失败回滚
比如你从取款机取钱,这个事务可以分成两个步骤:1划卡,2出钱.不可能划了卡,而钱却没出来.这两步必须同时完成.要么就不完成. 
2)一致性:
数据库总是从一个一致性的状态转换到另一个一致性的状态
例如,完整性约束了a+b=10,一个事务改变了a,那么b也应该随之改变.不管数据怎么改变。一定是符合约束
3)隔离性:
一个事务所做的修改在提交之前对其它事务是不可见的
两个以上的事务不会出现交错执行的状态.因为这样可能会导致数据不一致.
4)持久性:
一旦事务提交,其所做的修改便会永久保存在数据库中。

 

如果不考虑隔离性,就会引发一些 读和写 的问题,以读为例:

脏读 :一个事务读到另一个事务未提交的数据

不可重复读 :一个事务读到了另一个事务已经提交的update数据,导致多次查询结果不一致

幻读): 一个事务读到了另一个事务已经提交的insert数据,导致多次查询的结果不一样

 

2.事务的隔离级别:
1)READ UNCOMMITTED(读未提交):
事务中的修改即使未提交也是对其它事务可见,可能发生脏读、不可重复读、幻读。
2)READ COMMITTED(读提交):
事务提交后所做的修改才会被另一个事务看见,可能产生一个事务中两次查询的结果不同。可能发生不可重复读、幻读
3)REPEATABLE READ(可重读):
只有当前事务提交才能看见另一个事务的修改结果。解决了一个事务中两次查询的结果不同的问题。可能发生幻读
4)SERIALIZABLE(串行化):
只有一个事务提交之后才会执行另一个事务。脏读、不可重复读以及幻读都可避免

五、MySQL存储引擎及应用方案

MySQL采用插件式的存储引擎的架构,可以根据不同的需求为不同的表设置不同的存储引擎

常用MySQL存储引擎介绍:

InnoDB引擎:将数据存储在表空间中,表空间由一系列的数据文件组成,由InnoDb管理。支持每个表的数据和索引存放在单独文件中(innodb_file_per_table);支持事务,采用MVCC来控制并发,并实现标准的4个事务隔离级别,支持外键。索引基于聚簇索引建立,对主键查询有较高性能。数据文件的平台无关性,支持数据在不同的架构平台移植。能够通过一些工具支持真正的热备,如XtraBackup等;内部进行自身优化如采取可预测性预读,能够自动在内存中创建bash索引等。

MyISAM引擎:MySQL5.1默认,不支持事务和行级锁,提供大量的特性如全文索引、空间函数、压缩、延迟更新等。数据库故障后,安全恢复性,对于只读数据可以忍受故障恢复,MyISAM依然非常适用 ,日志服务器的场景也比较适用,只需插入和数据读取操作,不支持单表一个文件,会将所有的数据和索引内容分别存放在两个文件中,MyISAM对整张表加锁而不是对行,所以不适用写操作比较多的场景,支持索引缓存不支持数据缓存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章