赫赫小虾 2014-08-25
一、MySQL逻辑架构
1、连接管理和安全性
每个客户端连接都会在服务器进程中拥有一个线程,这个连接的查询只会在这个单独的线程中执行,该线程只能轮流在某个CPU核心或者CPU中运行。服务器会负责缓存线程,因此不需要为每一个新建的连接创建或者销毁线程。
当客户端连接到Mysql服务器时,服务器需要对其进行认证。认证基于用户名、原始主机信息和密码(mysql.user表)。如果使用了安全套接字(SSL)的方式连接,还可以使用X.509证书认证。一旦客户端连接成功,服务器会继续验证该客户端是否具有执行某个特定查询的权限。
2、优化与执行
mysql会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的读取顺序,以及选择合适的索引等。用户可以通过特殊的关键字提示(hint)优化器,影响它的决策过程。也可以请求优化器解析(explain)优化过程的各个因素,使用户可以知道服务器是如果进行优化决策的,便于用户重构查询和schema、修改相关配置。
优化器并不关心表使用的是什么存储引擎,但存储引擎对于优化查询是有影响的。优化器会请求存储引擎提供容量或某个具体操作的开销信息,以及表数据的统计信息等。
对于select语句,在解析查询之前,服务器会先检查查询缓存(query cache),如果能够在其中找到对应的查询,服务器就不必在执行查询解析、优化和执行的整个过程,而是直接返回查询缓存中的结果集。
3、并发控制
无论何时,只要有多个查询需要在同一时刻修改数据,都会产生并发控制的问题,mysql在两个层面进行并发控制:服务器层和存储引擎层。
①读写锁:分别是读锁和写锁,也成为共享锁和排它锁。读锁是共享的,多个客户在同一时刻可以同时读取同一个资源,而相互不干扰;写锁是排他的,也就是说一个写锁阻塞其他的写锁和读锁,这是出于安全策略考虑,只有这样,才能确保在给定的时间内,只有一个用户能执行写入,并防止其他用户读取正在写入的同一资源。
②锁的力度:每种mysql存储引擎都可以实现自己的所策略和锁力度。在存储引擎的设计中,锁管理是个非常重要的决定。有两种非常重要的所策略---(1)表锁,他会锁定整张表。尽管存储引擎可以管理自己的锁,mysql本身还是会使用各种有效的锁来实现不同的目的,例如服务器会为诸如alter table使用表锁,而忽略存储引擎的锁机制;(2)行级锁,可以最大程度的支持并发处理,在Innodb以及其他的额一些存储引擎中实现了行级锁。行级锁只在存储引擎层实现,而mysql服务器层没有实现。
4、事务
事务就是一组原子性的SQL查询,或者说一个独立的工作单元。如果数据库引擎可以成功执行该组全部语句,那么就执行该组语句。如果其中有任何一条语句不能执行,那么所有的语句都不会执行。也就是说,事务内的语句要么全部执行成功,要么全部执行失败。事务要求系统有严格的ACID。
5、多版本并发控制
mysql大多数事务存储引擎实现的都不是简单的行级锁,基于提升并发性能的考虑,他们一般都会实现多版本并发控制(MVCC)。MVCC是通过保存数据在某个时间点的快照来实现的,根据不同的实现,分为乐观并发控制和悲观并发控制。
Innodb的mvcc,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
6、mysql的存储引擎
①InnoDB是mysql的默认事务型引擎,它被设计用来处理大量的短期事务,短期事务大部分情况是正常提交的,很少会被回滚。InnoDB的性能和自动崩溃恢复特性,使得他在非事务型存储的需求中也很流行。除非有特殊需要,否则就优先考虑InnoDB引擎。
②在mysql5.1之前的版本,MyISAM是默认的存储引擎。MyISAM提供了大量的特性,包括全文索引、压缩、空间函数等。但MyISAM不支持事务和行级锁,而且有一个毫无疑问的缺陷就是崩溃后无法安全恢复。但对于只读的数据,或者表比较小、可以容忍修复操作,则依然可以继续使用MyISAM。
③memory引擎,如果需要快速访问数据,并且这些数据不会被修改,重启以后丢失也没有关系,那么使用memory表是非常有用的。memory表至少比MyISAM表要快一个数量级,因为数据都保存在内存中,不需要进行磁盘I/O。memory表的结构在重启以后还会保留,但数据会丢失。