|
一、Mysql的逻辑架构
a.大致将Mysql分为3层:
1.mysql客户端,提供一些基本服务,比如连接处理、授权、安全等.
2.第二层为mysql提供的一些核心处理内容,比如查询解析、分析、优化等.
3.第三层则包含了mysql的存储引擎,用于存储和提取存放在mysql中的内容,服务器通过存储引擎API和存储引擎进行通信,存储引擎不会进行SQL解析(InnoDB是个例外,它会解析外键定义,因为MySQL服务器自身没有实现它),也不会互相通信,只是简单的响应服务器的请求.
b.连接管理和安全
每个客户连接在服务器上都有自己的线程,每个连接所属的查询都会在指定的某个单独线程中完成,这些线程轮流的运行在某个cpu上,服务器负责缓存线程,因此不必为每个新连接重建或撤销线程.
当客户端连接到服务器时,服务器要对其进行认证,认证基于用户名、主机、口令,一旦连接成功,客户端就会验证该客户端是否具有执行某个具体查询.
c.优化与执行
MySQL会解析查询,并创建一个内部数据结构(解析书),然后进行各种优化.其中包括重新查询、决定查询的读写顺序、以及选择使用的索引等.用户可以通过特殊的关键字给以优化器提示,影响它的决策过程.另外还可以请求服务器给出优化的各种说明,使用户可以知道服务器是如何进行决策的.
优化器并不关心某个表使用哪种存储引擎,但存储引擎会对服务器的查询优化有影响.优化器会请求存储引擎为某种具体操作提供性能与开销方面的信息以及表内部的统计信息.
在解析查询以前,服务器会询问查询缓存,它只能保持selelct语句和相应的结果,如果能在缓存中找到要执行的查询,服务器就不必从新解析、优化、查询.
二、并发控制
无论何时,只要不止一个查询同时修改数据库,都会产生并发控制的问题.
a.读锁和写锁
读锁和写锁又分别叫做共享锁和排他锁.
某一资源上的读锁是共享的或者互不阻塞的,在同一时间里多个用户可以读取同一资源而互不干扰;写锁是排他的,一个写锁会阻塞其他的读锁和写锁.
b.锁粒度
任何时间里,在给定的资源上,被加锁数据量越小就允许更多的并发操作,只要相互之间互不冲突即可.问题是加锁也会消耗系统资源,每一种锁操作,如获得锁、检查锁是否已解除、解除锁都会增加系统的开销.
锁策略就是在锁开销和数据安全之间寻求一种平衡,这种平衡也能影响系统性能,每种MySQL存储引擎都可以实现独有的锁策略和锁粒度。以下是两种重要的锁策略
表锁:表锁是MySQL开销最小的锁策略,它将整个表加锁,当有一个用户进行写操作时,用户会获得一个写锁,写锁会禁止其他用户任何的读写操作,只有无人做写操作时用户才能获得读锁,读锁之间互不冲突.写锁比读锁据用更高的优先级,即使有读操作用户排列在队列中,新申请的写操锁仍然会排在队列的前面(写锁会被安置在读锁之前,而读锁不能排在写锁之前).
行级锁:行级锁支持最大的并发处理,同时也带来最大的性能开销,行级锁由存储引擎实现而不是MySQL服务器实现
三、事务
事务是一组原子性的SQL查询语句,也可以看着一个工作单元.事务内的语句要么全部执行要么全部不执行.
ACID:
原子性(Atomicity):一个事务必须被视作一个单独的内部不可分的工作单元,以确保一个事务要么全部执行要么全部回滚.
一致性(Consistency):数据库总是从一种一致性状态转换到另一种一致性状态,即任何事务处理过程中作的数据改变都不会影响到数据库的内容.
隔离性(Isolation):某个事务的处理结果只有在完成之后才对其他事务可见.
持久性(Durabilit):一旦一个事务提交,事务所做的数据改变将是永久的.
a.隔离级
SQL标准定义了4类隔离级,包括了一些具体规则,用来限定事务内外哪些改变是可见的哪些是不可见的.低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销.
1.READ UNCOMMITED(读取未提交内容):很少实际应用
2.READ COMMITED(读取提交内容):大多数系统默认的隔离级,但不是MySQL默认的
3.REPEATEABLE READ(可重读):MySQL的默认隔离级
4.SERIALIZABLE(可串行化):
b.死锁
死锁是指两个或多个事务在同一资源上互相占有并请求加锁导致的恶性循环,多个事务以不同的顺序加锁同一资源是就会产生死锁 .
为了解决这种问题,数据库实现了多种死锁检测和死锁超时机制.对于更复杂的系统,例如InnoDB存储引擎能够预知循环相关性,并立刻返回错误(比较好),其他的解决方法是让查询达到一个锁等待超时时间,然后再放弃争用(不够好),目前InnooDB的处理死锁的方法是回滚具有最少排他行级锁的事务(一种对最易回滚事务的估算).
c.事务日志
事务日志可以使事务处理更加高效.和每次数据一改变就更新数据表的数据不同,存储引擎可以先更新数据在内存中的拷贝,这非常快,然后存储引擎会将数据改变记录到事务日志,事务日志位于磁盘上,因此具有持久性,这相对较快,因为追加日志导致的写操作只涉及到了磁盘上很小的顺序IO,而替代了写磁盘中表所需要的大量随机IO.最后系统会在某个时间把数据更新到磁盘上的表中.大多存储引擎使用了此技术,也就是通常所说的预写式日志,利用2此磁盘操作将数据写入磁盘.
d.MySQL中的事务
MySQL中默认操作是AUTOCOMMIT型的,这意味着除非显示的开始一个事务,否则它将每一个查询视作一个单独的事务自动执行.可以通过设置变量启用和禁用AUTOCOMMIT
SHOW VARIABLES LIKE 'AUTOCOMMIT';//查看autocommit的值
SET AUTOCOMMIT = 1;//修改autocommti的值
MySQL允许用户通过命令 SET SESSION TRANSATION ISOLATION LEVEL设置隔离级,新的隔离级将在下一个事物开始时生效.用户也可以在配置文件中为整个服务器设置隔离级;使用下列命令只会为当前事务设置隔离级
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITED;
在事务中混合使用事务性表和非事务性表,如果事务回滚,那么在非事务性表上所做的修改将无法取消.
一个事务在任何时候都可以获得锁,但只有在commit或rollback的时候才会释放锁,它会同时释放掉所有锁,一般情况下InnoDB的锁定都是隐式锁,InnoDB会根据用户的隔离级别自动出来锁定.InnoDB也支持显示锁定,如下所示:
SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
MySQL也支持LOCK TABLES 和 UNLOCK TABLES命令,这些命令由MySQL服务器实现,而不是存储引擎.LOCK TABLE命令和事务处理之间的交互是比较复杂的,在某些服务器版本上可能出现一些不可预料的行为,因此,除非是在一个事务中使用LOCK TABLES,同时AUTOCOMMIT模式是被禁止的,否则无论使用何种存储引擎都不要使用LOCK TABLES 命令.
四.多版本并发控制
大多数MySQL的事务性存储引擎,不是简单的使用行加锁机制,而是选用一种叫做多版本并发控制(MVCC)的技术,和行加锁机制关联使用,以应对更多的并发处理问题.以下简单描述InnoDB的简化版的行为方式来说明MVCC的工作原理:
InnoDB通过为每个数据行添加两个隐含值的方式来实现MVCC,这两个隐含值记录了行数据的创建时间和过期时间,每一行都存储了事件发生时的系统版本号用来替代事件发生时的实际时间.每一次开始一个事务,系统版本号会自动增加.每个事务都会保存它在开始时的"当前系统版本"的记录,而每个查询都会根据事务的版本号,检查每行数据的版本号.下面是事务隔离级别设置在REPEATABLE READ时,MVCC的实际操作:
SELECT
InnoDB检查每行数据,确保它们符合两个标准:1.InnoDB只查找版本早于( 这种语法适合所有存储引擎,不过这里有一个陷阱:这种转换会耗费大量时间.MySQL要执行一个旧表到新标的逐行复制.
2.DUMP和IMPORT
3.CREATE和SELECT
|
|