高性能msyql之mysql构架和历史
mysql最重要、最与众不同的特性是它的存储引擎架构,这种架构的设计将查询处理(query processing)及其他系统任务(server task)和数据的存储/提取相分离。这种处理和存储分离的设计可以在使用时根据性能、特性、以及其他需求来选择数据存储的方式
Mysql 逻辑架构
下图是mysql各组件之间如何协同工作的架构图。
最上层处理类似:连接处理、授权认证、安全等等。
第二层mysql核心服务功能都在这一层,包括查询解析、分析、优化、缓存以及所有的内置函数。
第三层包含了存储引擎。存储引擎负责mysql中数据的存储和提取。
连接管理与安全性
当客户端(应用)连接到msyql服务器时,服务器需要对其进行认证。认证基于用户名、原始主机信息和密码。一旦客户端连接成功,服务器会继续验证该客户端是否具有执行某个特定查询的权限。
优化和执行
mysql会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的顺序,以及选择合适的索引等。
对于select语句,在解析查询之前,服务器会先检查查询缓存(query cache),如果能够在其中找到对应的查询,服务器就不必执行查询解析、优化和执行的整个过程,而是直接返回查询缓存的结果集。
并发控制
无论何时,只要有多个查询需要在同一时刻修改数据,都会产生并发控制的问题。
读写锁
读锁(共享锁):读锁是共享的,或者说互相不阻塞的。多个客户在同一时刻可以同时读取同一个资源,而互不干扰。
写锁(排它锁):它是排他的,也就是说一个写锁会阻塞其他的写锁和读锁这是出于安全的策略考虑,只有这样,才能确保在给定的时间里,只有一个用户能执行写入,并防止其他用户读取正在写入的同一资源。
锁粒度
一种提高共享资源并发性的方式就是让锁定对象更有选择性,尽量只锁定需要修改的部分数据,而不是所有资源。任何时候,在给定的资源上,锁定的数据量越少,则系统的并发程度越高,只要互相之间不发生冲突即可。但是,加锁也需要消耗资源。所谓锁策略,就是在锁的开销和数据的安全性之间寻求平衡,这种平衡当然会影响到性能。
表锁
表锁是msyql中最基本的锁策略,并且是开销最小的策略:它会锁定整张表。一个用户在对表进行写操作(插入、删除、更新)前,需要先获得写锁,这会阻塞其他用户对该表的所有读写操作。只有没有写锁是,其他读取的用户才能获得读锁,读锁之间是不相互阻塞的。
行级锁
行级锁可以最大程度地支持并发处理(同时也带来了最大的锁开销)。行级锁只在存储引擎层实现,而mysql服务器层没有实现。
事务
事务就是一组原子性的sql查询, 或者说一个独立的工作单元。事务内的语句,要么全部执行成功,要么全部执行失败
原子性(atomicity):一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分。
一致性(consistency):数据库总是从一个一致性的状态转换到另外一个一致性的状态。如果事务最终没有提交,所有事务中所做的修改也不会保存到数据库中。
隔离性(isolation):通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。
持久性(durability) 一点事务提交,则其所做的修改就会永久保存到数据库中。
一个实现了ACID的数据库,相比没有实现ACID的数据库,通常会需要更强的cpu处理能力、更大的内存和更多的磁盘空间。
隔离级别
未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据,脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读),是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
幻读:第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
死锁
死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。
将持有最少行级排它锁的事务进行回滚,只是相对比较简单的死锁回滚算法。
mysql中的事务
mysql默认采用自动提交(autocommit)模式,即,如果不是显示地开始一个事务,则每个查询都被当做一个事务执行提交操作。
mysql的存储引擎
在文件系统中,mysql将每个数据库(schema)保存为数据目录下的一个子目录。创建表时,msyql会在数据库子目录下创建一个和表同名的.frm文件保存表的定义。
可以使用
show table status like '表名'
来显示表的相关信息
innodb存储引擎
innode是mysql的默认事务型引擎,也是最重要、使用最广泛的存储引擎。它被设计用来处理大量的短期(short-lived)事务。
总结
msyql拥有分层的架构。上层是服务器层的服务和查询执行引擎,下层是存储引擎。虽然有很多不同作用的插件API,但存储引擎api还是最重要的。如果能理解mysql在存储引擎和服务层之间处理查询时如何通过api来回交互,就能抓住mysql的核心基础架构的精髓。