MySQL架构与概念
一、MySQL的逻辑架构数据库
最上面不是MySQL特有的,全部基于网络的C/S的网络应用程序都应该包括链接处理、认证、安全管理等。
中间层是MySQL的核心,包括查询解析、分析、优化和缓存等。同时它还提供跨存储引擎的功能,包括存储过程、触发器和视图等。
最下面是存储引擎,它负责存取数据。服务器经过storage engine API能够和各类存储引擎进行交互。
1.一、查询优化和执行(Optimization and Execution)缓存
MySQL 将用户的查询语句进行解析,并建立一个内部的数据结构——分析树,而后进行各类优化,例如重写查询、选择读取表的顺序,以及使用哪一个索引等。查询优化器不 关心一个表所使用的存储引擎,可是存储引擎会影响服务器如何优化查询。优化器经过存储引擎获取一些参数、某个操做的执行代价、以及统计信息等。在解析查询 以前,服务器会先访问查询缓存(query cache)——它存储SELECT语句以及相应的查询结果集。若是某个查询结果已经位于缓存中,服务器就不会再对查询进行解析、优化、以及执行。它仅仅 将缓存中的结果返回给用户便可,这将大大提升系统的性能。安全
1.二、并发控制
MySQL提供两个级别的并发控制:服务器级(the server level)和存储引擎级(the storage engine level)。加锁是实现并发控制的基本方法,MySQL中锁的粒度:
(1) 表级锁:MySQL独立于存储引擎提供表锁,例如,对于ALTER TABLE语句,服务器提供表锁(table-level lock)。
(2) 行级锁:InnoDB和Falcon存储引擎提供行级锁,此外,BDB支持页级锁。InnoDB的并发控制机制,下节详细讨论。
另外,值得一提的是,MySQL的一些存储引擎(如InnoDB、BDB)除了使用封锁机制外,还同时结合MVCC机制,即多版本两阶段封锁协议(Multiversion two-phrase locking protocal),来实现事务的并发控制,从而使得只读事务不用等待锁,提升了事务的并发性。
注:并发控制是DBMS的核心技术之一(实际上,对于OS也同样),它对系统性能有着相当重要的影响,之后再详细讨论。
服务器
1.三、事务处理
MySQL中,InnoDB和BDB都支持事务处理。这里主要讨论InnoDB的事务处理(关于BDB的事务处理,也十分复杂,之前曾较为详细看过其源码,之后有机会再讨论)。
1.3.一、事务的ACID特性
事务是由一组SQL语句组成的逻辑处理单元,事务具备如下4个属性,一般简称为事务的ACID属性(Jim Gray在《事务处理:概念与技术》中对事务进行了详尽的讨论)。
(1)原子性(Atomicity):事务是一个原子操做单元,其对数据的修改,要么全都执行,要么全都不执行。
(2)一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着全部相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,全部的内部数据结构(如B树索引或双向链表)也都必须是正确的。
(3)隔离性(Isolation):数据库系统提供必定的隔离机制,保证事务在不受外部并发操做影响的“独立”环境执行。这意味着事务处理过程当中的中间状态对外部是不可见的,反之亦然。
(4)持久性(Durable):事务完成以后,它对于数据的修改是永久性的,即便出现系统故障也可以保持。
1.3.二、事务处理带来的相关问题
因为事务的并发执行,带来如下一些著名的问题:
(1)更新丢失(Lost Update):当两个或多个事务选择同一行,而后基于最初选定的值更新该行时,因为每一个事务都不知道其余事务的存在,就会发生丢失更新问题--最后的更新覆盖了由其余事务所作的更新。
(2) 脏读(Dirty Reads):一个事务正在对一条记录作修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另外一个事务也来读取同一条记录,若是不加 控制,第二个事务读取了这些“脏”数据,并据此作进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫作"脏读"。
(3)不可重复读(Non-Repeatable Reads):一个事务在读取某些数据后的某个时间,再次读取之前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫作“不可重复读”。
(4)幻读(Phantom Reads):一个事务按相同的查询条件从新读取之前检索过的数据,却发现其余事务插入了知足其查询条件的新数据,这种现象就称为“幻读”。
1.3.三、事务的隔离性
SQL2标准定义了四个隔离级别。定义语句以下:
SET TRANSACTION ISOLATION LEVEL
[READ UNCOMMITTED |
READ COMMITTED |
REPEATABLE READ |
SERIALIZABLE ]
这 与Jim Gray所提出的隔离级别有点差别。其中READ UNCOMMITTED即Jim的10(浏览);READ COMMITTED即20,游标稳定性;REPEATABLE READ为2.99990隔离(没有幻像保护);SERIALIZABLE隔离级别为30,彻底隔离。SQL2标准默认为彻底隔离(30)。各个级别存在 问题以下:
网络
隔离级数据结构 |
脏读架构 |
不可重复读并发 |
幻象读性能 |
读未提交优化 (Read uncommitted) |
可能 |
可能 |
可能 |
读提交 (Read committed) |
不可能 |
可能 |
可能 |
可重复读 (Repeatable read) |
不可能 |
不可能 |
可能 |
可串行化 (Serializable) |
不可能 |
不可能 |
不可能 |
各 个具体数据库并不必定彻底实现了上述4个隔离级别,例如,Oracle只提供READ COMMITTED和Serializable两个标准隔离级别,另外还提供本身定义的Read only隔离级别;SQL Server除支持上述ISO/ANSI SQL92定义的4个隔离级别外,还支持一个叫作“快照”的隔离级别,但严格来讲它是一个用MVCC实现的Serializable隔离级别。MySQL 支持所有4个隔离级别,其默认级别为Repeatable read,但在具体实现时,有一些特色,好比在一些隔离级别下是采用MVCC一致性读。国产数据库DM也支持全部级别,其默认级别为READ COMMITTED。