高性能MySQL -MySQL架构,MVCC多版本并发控制和一些基本概念

内容源于《高性能MySQL》

一、MySQL逻辑架构

架构图:
高性能MySQL -MySQL架构,MVCC多版本并发控制和一些基本概念_第1张图片

最上层不是Mysql独有的, 比如连接处理,授权认证, 安全 等等
第二层核心服务功能,包括查询解析,分析,优化,缓存以及所有内置函数,存储过程,触发器,视图等都在这层实现
第三层 存储引擎,存储引擎API包含几十个底层函数

二、优化与执行
什么是优化: MySQL解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询,决定表的读取顺序,以及选择合适的索引等。 (用户可以通过特殊的关键字提示优化器,影响它的决策过程。也可以请求优化器解释优化过程的各个因素)

三、并发控制
采用读写锁来进行并发控制,提高并发性的方式就是让锁定的对象更有选择性,只锁定部分数据,而不是所有的资源,这就是锁粒度要考虑的问题。

表锁:MySQL最基本的锁策略,开销最小的策略。它会锁定整张表,用户对表进行写操作前,先获得写锁,这会阻塞其他用户对该表的所有读写操作。只有没有写锁时,其他读取用户才能获得读锁,读锁之间是不相互阻塞的。

行级锁:行级锁可以最大程度地支持并发处理(最大锁开销),InnoDB和XtraDB,还有其他一些存储引擎中实现了行级锁,行级锁只在存储引擎层实现,而MySQL服务器层没有实现。

四、事务
事务这个概念比较基础,就不过多介绍。 记住一句话要么都做,要么都不做的。 还有ACID四大特征:原子性,一致性(从一个一致性的状态转换到另一个一致性的状态),隔离性,持久性。

五、隔离级别
四种隔离级别
1. READ UNCOMMITED(未提交读)
其他事物可以读取未提交数据,会导致脏读(读脏数据),这种会导致很多问题,一般不采用。
2. READ COMMITED(提交读)
事务提交之前,所做的任何修改对其他事务不可见,也叫不可重复读,同一个事务执行两次相同的查询,可能得到不一样的结果。
3. REPEATABLE READ(可重复读)
保证了在同一个事务中多次读取同样记录的结果是一致的。但无法解决幻读问题。即当某个事务在读取范围内的记录时,另外一个事务又在该范围内插入了新纪录,导致之前的事务再次读取时,产生幻行。
4. SERIALIZABLE(可串行化)
最高的隔离级别,通过加锁确保数据的一致性。

看到这里的时候很容易产生一个困惑,可重复读和幻读怎么感觉没区别,实际上区别是:
1.可重复读是指一个事务查询了数据,另一个事务提交了对这个数据的修改,于是再次读取数据的时候就出现了重复读的问题。例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。
2.幻读则是一个事务修改了数据表,另一个数据插入了一条新数据,导致出现幻行。例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。

六、死锁
1. 多个事务不同顺序锁定资源时,会产生死锁,
2. 多个事务同时锁定同一个资源,产生死锁。
InnoDB目前处理死锁的方法是,将持有最小行级排他锁的事务进行回滚(相对比较简单的死锁回滚方法)
越复杂的系统,越能检测到死锁的循环依赖,并立即返回一个错误,否则会导致出现非常慢的查询。

七、MySQL中的事务
MySQL 提供了两种事务型的存储引擎:InnoDB 和 NDB Cluster
MySQL默认采用自动提交模式,即每个查询都被当做一个事务执行提交操作。另外有一些命令在执行之前会强制执行commit提交,比如ALTER TABLE。

MySQL服务层不管理事务,事务是由下层的存储引擎实现的,所以同一个事务中,使用多种存储引擎是不可靠的。

InnoDB采用的是两阶段锁定协议,事务执行过程中,随时可以锁定,锁只有在执行commit或者rollback的时候才会释放,并且同一个时刻被释放。

八、多版本并发控制MVCC
MySQL的大多数事务型存储引擎都不是简单的行级锁。各大数据库基本都采用MVCC,但不尽相同。

InnoDB的简化版:(MVCC实现原理)
在每行记录后面保存两个隐藏的列来实现,一个保存了行的创建版本号,一个保存行的过期版本号(删除版本号)。

版本号:
1. 系统版本号:每开始一个新的事务,系统版本号就会自动增加
2. 事务版本号:事务开始时刻的系统版本号

当执行select操作时候:
1. 只查找版本早于当前事务版本的数据行。 确保事务读取的行,在事务开始之前就存在的,或者是事务自身插入或者修改过的。
2. 行的删除版本号要么未定义,要么大于当前事务版本号。 确保事务查询到的行,在事务开始之前没被删除。

insert操作:
为新插入的每一行保存当前系统版本号为行创建版本号。

delete操作:
为删除的行保存当前系统版本号作为行删除版本号。

update操作:
为插入一行新数据保存当前版本号作为该新行行创建版本号,同时保存当前系统版本号到原来的行作为行删除版本号。

可见update = delete+insert

采用MVCC这个原理,大多操作可以不用加锁,使得读数据操作简单,性能好,缺点是额外的存储空间消耗,更多的行检查和维护工作。MVCC只能在REPEATABLE READ 和READ COMMITTED两个隔离级别下工作。其他两个隔离级别跟MVCC不兼容。

你可能感兴趣的:(数据库)