MySQL 体系结构

标签:MYSQL/数据库/查询原理/体系结构mysql

概述  

学习一门数据库系统首先得了解它的架构,明白它的架构原理对于后期的分析问题和性能调优都有很大的帮助,接下来就经过分析架构图来认识它。sql

目录数据库

架构图

 

1.链接管理与安全验证缓存

每一个客户端都会创建一个与服务器链接的线程,服务器会有一个线程池来管理这些链接;若是客户端须要链接到MYSQL数据库还须要进行验证,包括用户名、密码、主机信息等。安全

2.解析器服务器

解析器的做用主要是分析查询语句,最终生成解析树;首先解析器会对查询语句的语法进行分析,分析语法是否有问题。还有解析器会查询缓存,若是在缓存中有对应的语句,就返回查询结果不进行接下来的优化执行操做。前提是缓存中的数据没有被修改,固然若是被修改了也会被清出缓存。架构

在有的书籍中会把查询缓存放在解析以前,难道不须要判断语法是否有错误吗?若是有知道的麻烦帮忙解惑。并发

3.优化器高并发

优化器的做用主要是对查询语句进行优化操做,包括选择合适的索引,数据的读取方式,包括获取查询的开销信息,统计信息等,这也是为何图中会有优化器指向存储引擎的箭头。以前在别的文章没有看到优化器跟存储引擎之间的关系,在这里我我的的理解是由于优化器须要经过存储引擎获取查询的大体数据和统计信息。性能

4.执行器

执行器包括执行查询语句,返回查询结果,生成执行计划包括与存储引擎的一些处理操做。

存储引擎

1.锁的种类

锁的由来是为了解决并发控制,对于一个查询语句为了避免让查询的数据被其它语句所更改就须要将数据附加锁,咱们比较熟悉的锁有共享锁和排他锁。

2.锁的粒度

任何一种操做都须要消耗资源,附加锁一样也会消耗资源,一样的一个查询若是咱们锁定的资源越少那么并发就越高同时资源消耗越大,反之并发低消耗越小。

  表锁(table lock)

表锁是MYSQL里面资源消耗最小的锁,只须要在查询对应的表上附加锁就能够了。一个SQL语句首先须要得到锁,首先查询语句会判断表上面是否存在锁,若是表上面有排他锁那么查询语句就会等待,因此查询语句只须要获取一次锁就能够了,不须要再往下一层去判断是否存在行锁,锁资源消耗低。同时若是有一个排他锁附加在该表上面其它的语句都须要等待改锁释放,系统的并发度很低。

 行锁(row lock)

行锁与表锁恰好相反,一个update语句首先它会判断对应的表是否存在排他锁,若是不存在接下来会判断对应的更新记录上面是否存在锁,若是不存在附加排他锁。行锁的获取锁资源方面消耗比表锁更多,可是因为它只在对应的记录行上面添加锁,不影响对应表的其它记录行,系统的并发度比表锁要高。

 死锁

在一个高并发的系统中,因为锁和事务的存在每每会有死锁的状况发生。举个简单的死锁的例子,假如两个事务同时执行。

事务1
START TRANSACTION;
UPDATE USER SET NAME='张三' WHERE ID=1
等待5秒
UPDATE USER SET NAME='李四' WHERE ID=2
COMMIT;

事务2
START TRANSACTION;
UPDATE USER SET NAME='张三' WHERE ID=2
等待5秒
UPDATE USER SET NAME='李四' WHERE ID=1
COMMIT;

因为两个事务在更新第一天语句的时候都锁定了对应的行记录,当进行次日更新语句的时候因为对应的记录行已经被锁定须要等待,陷入了死循环,这就是常见的死锁的状况。

 

3.事务

mysql和其它的数据库产品有一个很大的不一样就是事务由存储引擎所决定,例如MYISAM,MEMORY,ARCHIVE都不支持事务,事务就是为了解决一组查询要么所有执行成功,要么所有执行失败。

mysql事务默认是采起自动提交的模式,除非显示开始一个事务

SHOW VARIABLES LIKE 'AUTOCOMMIT';

修改自动提交模式,0=OFF,1=ON

注意:修改自动提交对非事务类型的表是无效的,由于它们自己就没有提交和回滚的概念,还有一些命令是会强制自动提交的,好比DLL命令、lock tables等。

SET AUTOCOMMIT=OFF

SET
AUTOCOMMIT=0

你们可能比较熟悉的就是事务的ACID特性:原子性,一致性,隔离性,持久性。

原子性:事务是不可分割的最小工做单元,整个事务要么所有提交要么所有回滚失败。

一致性:数据库老是从一个一致性状态转换到另外一个一致性的状态。

隔离性: 一个事务所作的更改在最终提交以前其它事务是不可见的。

持久性:事务一旦提交所作的修改就会永久保存在数据库中,即便系统崩溃,数据也不会丢失。

 

隔离级别

隔离级别是用来规定一个事务所作的更改,一般会默认系统使用哪种隔离级别,一般隔离级别越高系统的并发就越低,系统开销也越大,mysql有四种隔离级别分别是:

未提交读(READ UNCOMMITTED):未提交读隔离级别也叫读脏,就是事务能够读取其它事务未提交的数据。

提交读(READ COMMITTED):在其它数据库系统好比SQL Server默认的隔离级别就是提交读,已提交读隔离级别就是在事务未提交以前所作的修改其它事务是不可见的。

可重复读(REPEATABLE READ):保证同一个事务中的屡次相同的查询的结果是一致的,好比一个事务一开始查询了一条记录而后过了几秒钟又执行了相同的查询,保证两次查询的结果是相同的,可重复读也是mysql的默认隔离级别,。

可串行化(SERIALIZABLE):可串行化就是保证读取的范围内没有新的数据插入,好比事务第一次查询获得某个范围的数据,第二次查询也一样获得了相同范围的数据,中间没有新的数据插入到该范围中。

查询系统默认隔离级别、当前回话隔离级别
select @@global.tx_isolation,@@tx_isolation; 

 分别设置系统和回话当前隔离级别为可提交读

/*设置系统当前隔离级别*/
SET global transaction isolation level read committed;

/*设置回话当前隔离级别*/
SET SESSION transaction isolation LEVEL read committed;

注意:在同一个事务中避免出现混合存储引擎的表,好比混合了事务和非事务的表,正常提交不会有影响,若是出现了回滚操做,非事务的表的修改就没法回滚这样就会致使数据库处于不一致的状态,一旦出现这种状况将很难修复,因此表选择合适存储引擎很重要。

隐式和显示锁定

所谓的隐式锁定就是系统自动加锁而不是认为的添加锁,INNODB采用两段锁定协议,在事务的执行过程当中随时执行锁定,在执行commit或者rollback的时候全部的锁才同时释放

显示锁定就是人为的添加锁,好比lock tables或者unlock tables,显示锁定是基于服务器层的设定和存储引擎无关,就是无论你的表是myisam仍是innodb均可以显示添加lock tables,可是myisam自己就是lock tables因此再显示添加也画蛇添足。

注意:避免在事务中使用lock tables

存储

 存储这块知识放在后面单独讲解

总结

对于mysql的体系结构每一个人的理解可能会有所不一样,上图是根据本身的理解绘制的不是官方标准的体系结构,仅供参考,若是有不对的地方欢迎讨论,接下来的文章会是关于存储方面的文章,欢迎关注。

 

 

 

备注:

    做者:pursuer.chen

    博客:http://www.cnblogs.com/chenmh

本站点全部随笔都是原创,欢迎你们转载;但转载时必须注明文章来源,且在文章开头明显处给明连接,不然保留追究责任的权利。

《欢迎交流讨论》

相关文章
相关标签/搜索