【有书共读】《高性能MySQL》第一期《架构与历史》
这是第一次笔记,尽自己最大的努力去理解书中的每一个知识点,尽量把可能会面试的点提出来供大家参考,如有不对的或者争议的地方请私信,谢谢!
图1:MySQL服务器路基架构图
如果你能在头脑中构建一幅图1所示的MySQL各组件之间如何协同工作的架构图,就会有助于深入理解MySQL服务器。
最上层服务并不是MySQL独有的,大多数基于网络的客户端/服务器工具或者服务都有类似的架构。通常会处理一些连接,授权认证,安全等等,这是MySQL的入口。
第二层是MySQL的核心功能层,包括了查询解析,优化,缓存以及所有的内置函数(例如:日期,时间,数学和加密函数),所有跨存储引擎功能的实现都在这一层:存储过程,触发器,视图等。
第三层包括了存储引擎,存储引擎负责了数据的存储和提取。不同的存储引擎各有优劣。特别注意MySQL5.1及以前版本的默认存储引擎是MyISAM,而之后则是InnoDB。
因为是MySQL进阶类书籍,除了架构和历史之外,第一章也简单的普及了下面的内容。
在并发情况下,数据的操作存在安全性问题,解决这类经典问题的方法便是锁,大的分类下,锁分为共享锁和排他锁,也叫读锁和写锁(这里不讨论锁的具体实现)。读锁是共享的,各个线程见对于加了读锁的数据进行操作是不会阻塞的,而写锁是排他的,一个写锁会阻塞其他的写锁和读锁。从锁粒度的角度来说,锁又分为表锁和行锁,以及间隙锁和next-key锁,在MyISAM存储引擎中只支持表锁,其他粒度锁都不支持。
有了并发和锁的概念,其次就是事务(InooDB支持事务,而MyISAM不支持)。首先就是事务的ACID,然后从事务的隔离性中又引出了隔离级别,其中有四种隔离级别:
READ UNCOMMITED(未提交读):在此种隔离级别下,一个事务可以读到其他事务已经修改但还没有提交的数据,因此很容易产生脏读,不可重复,幻读等多种问题,一般情况下很少使用这种隔离级别。
READ COMMITED(提交读):在此种隔离级别下,可以避免脏读,但是由于在一次事务中(事务A),可能先读取一条数据,之后其他事务(事务B)修改了该数据并提交,此时事务A在读取该数据时会发现前后读取数据的结果不一致,因此产生了不可重复读问题。
REPEATABLE READ(重复度,MySQL的默认隔离级别):该级别下避免了脏读和不可重复读问题,但是会产生幻读情况,所谓幻读,就是事务A在读取某个范围的记录时,另一个事务B有插入或者删除了一些记录,事务A在读取该范围记录时,会发现少了或者多了一些行,似乎产生了幻觉,该书中指出InooDB引擎通过多版本并发控制(MVCC)可以解决幻读问题,但是我个人认为MVCC并不能完全解决幻读,后续会有实验数据。
SERIALIZABLE(可串行化):该级别下,通过事务串行执行,因此不会产生任何数据安全问题,但也会造成服务器效率低下,只有在非常需要保证数据一致性的情况下才考虑该隔离级别。
MVCC可以认为是一个行级锁的变种,但是它在很多情况下避免了加锁操作,MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。之所以会是如此,因为InnoDB引擎会通过在每个记录行后面保存两个隐藏的列来实现的,这两个列,一个是行的创建时间(本质上是事务ID),另一个是行的删除时间。MVCC的操作针对不同语句有不同的做法:
SELECT
InnoDB会根据以下两个条件检索并返回记录:
a. InnoDB只查找版本早于当前事务版本的数据行
b. 行的删除版本号要么未定义,要么大于当前事务版本号,这样可以确保事务读取到的行在开始之前未被删除。
UPDATE
InnoDB会更新数据并更新当前更新列的事务版本号
INSERT
InnoDB会插入数据并添加当前事务ID为隐藏列的事务版本号
DELETE
InnoDB会为删除的每一行保存当前事务版本号作为删除标识
MVCC测试:
测试表,只有一列,此时该列的隐藏列,事务id为1,删除时间为undefined
事务A,因为MVCC的存在,当前事务的id为2,因此它可以查询到所有小于等于事务2记录的行,这没什么问题。
事务B,插入二条数据,并提交,然后查看,没什么问题。
此时在事务A中查看,完美的避免了幻读,因为始终只能读取到小于等于当前事务id的列,而新插入的事务版本号大于大于当前事务版本号。
然后再事务A中更新事务B中插入的列,再select,就会发现比以前多了一行?这算是一种幻读吗?
最后说说MyISAM和InooDB存储引擎的区别:
MyISAM不支持事务,不支持外键,不支持行级锁,不支持聚簇索引并且索引采用前缀压缩技术,最关键的是崩溃后无法恢复,适合读要求高,写要求低,对数据安全不敏感的系统。
InooDB支持事务,支持外键,支持行级锁,主键默认采用聚集索引,适合绝大多数系统。
面试点:
1.MySQL架构了解吗?简单讲讲
2.事务的特性和隔离性说说?
3.MVCC机制了解吗?
4.Mysql常用的两种引擎有什么区别?