一、MySQL逻辑架构图

image.png

1.客户端连接管理层

负责管理客户端的连接/认证/授权等。

2.服务器层

负责查询解析/优化重写/查询缓存等。

3.存储引擎层

负责数据的存储和提取。

二、数据库死锁

image.png
当事务1执行完第1个update时,锁定了stockid=4的行,准备去update stockid=3的行;此时假如事务2页执行完第1个update,锁定了stockid=3的行
,准备去update stockid=4的行,这样就形成了死锁的四个必要条件。资源互斥、持有并请求新资源、资源不可剥夺、循环等待。
解决办法:
打破循环等待的条件,innodb为例,回滚持有行级锁最少记录的事务。使得某一个或部分事务回滚,释放行级锁,其他事务就能获取到被占有的行级锁,达到解决死锁的目的。
由于死锁无法避免,因此应用程序设计时必须考虑死锁发生后的处理逻辑。最简单的办法是重新执行被数据库存储引擎回滚的那个事务即可。

三、多版本并发控制(MVCC)

MVCC可以认为是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。MVCC没有一个统一的标准,各个数据库如Mysql,Oracle,PostgreSQL等都有自己的实现方式。虽然实现机制不同,但大都实现了非阻塞的读操作,写操作也只锁定必要的行。
实现原理:
通过保存数据在某个时间点的快照,使得每个事物看到的数据都是一致的。前面说到不同的数据库实现原理不同,典型的有乐观锁和悲观锁。下面以innodb的简化版行为来说明MVCC是如何工作的。

InnoDB的MVCC,是通过在表的每行记录后面保存两个隐藏的列来实现的。这两个列的值,分别保存行的创建时间和过期时间(即删除时间)。但是,它们存的并不是真实时间戳,而是系统版本号。每开始一个新的事务,这个系统版本号都会自动递增。事务开始时的系统版本号会作为事务版本号,用来和查询到的每行记录的版本号做比较。下面看一下在REPEATABLE READ的隔离级别下,MVCC具体是怎么工作的。

1.SELECT操作
a.InnoDB只查找版本号小于或等于当前事务版本号的数据行,这样可以确保事务读取到的行,要么是事务开始前就存在的,或者是这个事务本身插入或修改的。
b.行的删除版本号要么未定义,要么大于当前事务版本号,这样可以确保事务读取到的行,在事务开始前没有被删除。
只有符合a,b两个条件的记录行才会被查询到。
2.INSERT操作
InnoDB为新插入的每一行保存当前系统版本号作为行创建版本号。
3.DELETE操作
InnoDB为删除的每一行保存当前系统版本号作为行删除版本号。
4.UPDATE操作
InnoDB为插入一行新记录,保存当前系统版本号作为新创建行的创建版本号;同时当前系统版本号作为原来行的行删除版本号。

注意,MVCC只在可重复读和读已提交的隔离级别下工作。因为读未提交总是会读取最新的数据,而不是符合当前事务版本号要求的数据。而串行化会为所有的读操作加锁。

更详细版本博客:
https://blog.csdn.net/qq_4100...


小强大人
34 声望4 粉丝