详细介绍了隔离级别、MVCC
Innodb MVCC
Innodb MVCC 2
MVCC (Multiversion Concurrency Control),对数据库的任何修改的提交都不会直接覆盖之前的数据,而是产生一个新的版本与老版本共存(快照),使得读取时可以完全不加锁
MVCC原理.png即多版本并发控制技术,它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代之的是把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能
- 快照版本可以有多个,是由undo段来实现,而undo段用于回滚,所以快照版本无需额外的开销。
- 读取快照版本不会加任何锁,因为没有事务会对历史版本进行修改。
Innodb 事务原理
innodb存储的最基本row中包含一些额外的存储信息 DATA_TRX_ID,DATA_ROLL_PTR,DB_ROW_ID,DELETE BIT
InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列,分别保存了这个行的创建时间,一个保存的是行的删除时间。这里存储的并不是实际的时间值,而是系统版本号(可以理解为事务的ID),没开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的ID
begin->用排他锁锁定该行->记录redo log->记录undo log->修改当前行的值,写事务编号,回滚指针指向undo log中的修改前的行
上述过程确切地说是描述了UPDATE的事务过程,其实undo log分insert和update undo log
,因为insert时,原始的数据并不存在,所以回滚时把insert undo log丢弃即可,而update undo log则必须遵守上述过程
删除多余的快照
那么那些多出来的无用数据怎么被最终被清理呢?支持MVCC的数据库一般会有一个背景任务来定时清理那些肯定没用的数据。只要一个数据记录的deleted_by_txn_id不为空,并且比当前还没结束的事务ID中最小的一个还要小,该数据记录就可以被清理掉。在PostgreSQL中,这个背景任务叫做“VACUUM”进程;而在MySQL InnoDB中,叫做“purge“。
当事务提交之后,undo log并不能立马被删除,
而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。
Serializable实现策略
读要block写,写也要block读,读不block读
两阶段加锁 (2 Phases Locking, 2PL):
- 加锁阶段:在事务过程中,根据不同的SQL指令加锁。
- 释放锁阶段:锁定直到这个事务被提交或者回滚(包括等待超时造成回滚)时释放。
Serializable除了锁记录,还会锁记录的间隙
,避免意外的插入。这种锁概念上被称为区间锁(Range Lock)
MySQL InnoDB中的叫法是Gap Lock和间隙锁(Next-key Lock)
网友评论