当前位置: 首页 > 后端技术 > PHP

什么是MySQL的多版本并发控制(MVCC)?

时间:2023-03-30 00:42:26 PHP

1。什么是多版本并发控制?多版本并发控制技术的英文全称是MultiversionConcurrencyControl,简称MVCC。多版本并发控制(MVCC)通过保存某个时间点的数据快照来实现并发控制。也就是说无论事务执行多长时间,在事务内部看到的数据都不会受到其他事务的影响。根据事务的开始时间,每个事务可能会同时看到同一张表的不同数据。的。简单来说,多版本并发控制的思想就是保存数据的历史版本,通过对数据行的多版本管理实现数据库的并发控制。这样我们就可以通过版本号的比较来判断数据是否显示出来,并且在读取数据的时候可以在不加锁的情况下保证事务的隔离效果。可以认为多版本并发控制(MVCC)是行级锁的一种变体,但它在很多情况下避免了加锁操作,因此开销更低。虽然实现机制不同,但大多实现的是非阻塞读操作,写操作只锁定必要的行。大多数MySQL的事务存储引擎不实现简单的行级锁。基于提高并发性能的考虑,他们一般同时实现多版本并发控制(MVCC)。不仅是MySQL,其他数据库系统如Oracle、PostgreSQL等都实现了MVCC,只是各自的实现机制不同,因为MVCC没有统一的实现标准,典型的是乐观的(optimistic)并发控制和悲观的(pessimistic)并发控制.二、多版本并发控制解决了哪些问题1、读写之间阻塞的问题通过MVCC,读写之间不能互相阻塞,即读不阻塞写,写不阻塞读,可以提高并发事务处理能力。提高并发性的进化思路:普通锁只能串行执行;读写锁可以实现读写并发;数据多版本并发控制,可以实现并发读写。2.减少死锁的概率因为InnoDB的MVCC采用了乐观锁,所以读数据时不需要加锁,写操作只需要加锁必要的行。3.解决连读问题。一致性阅读也称为快照阅读。当我们查询数据库某个时间点的快照时,只能看到该时间点之前事务提交更新的结果,而看不到该时间点之后事务提交的更新结果。3.快照读和当前读快照读(SnapShotRead)是不带锁的一致性读,这也是InnoDB有这么高并发的核心原因之一。这里的一致性是指事务读取的数据要么是事务开始前就存在的数据,要么是事务本身插入或修改的数据。没有锁的简单SELECT都是快照读,例如:`SELECT*FROMtWHEREid=1`对应的是当前读,当前读是读取最新的数据,不是数据的历史版本。锁定的SELECT属于当前读,例如:SELECT*FROMtWHEREid=1LOCKINSHAREMODE;SELECT*FROMtWHEREid=1FORUPDATE;四、InnoDB的MVCC是如何工作的1.InnoDB是如何存储的对于记录的事务版本号的多个版本,每次开启一个事务,我们都会从数据库中获取一个事务ID(即事务版本号)。这个交易ID是自增的。通过ID大小,我们可以判断交易订单的时间。行记录的隐藏列InnoDB的叶子段存放数据页,行记录保存在数据页中,行记录中有一些重要的隐藏字段:DB_ROW_ID:6-byte,隐藏行ID,使用生成默认聚合簇索引。如果我们在创建数据表的时候没有指定聚簇索引,InnoDB就会使用这个隐藏的ID来创建聚簇索引。使用聚簇索引可以提高数据查找的效率。DB_TRX_ID:6字节,操作本条数据的交易ID,即最后插入或更新本条数据的交易ID。DB_ROLL_PTR:7字节,回滚指针,即指向这条记录的UndoLog信息。UndoLogInnoDB将行记录快照保存在UndoLog中,我们可以在回滚段中找到,如下图所示:从图中我们可以看出回滚指针连接了数据行的所有快照记录series通过链表的结构也就是说,每一次快照的记录保存了当时的db_trx_id,也就是操作该时间点数据的事务ID。这样,如果我们要找一个历史快照,我们可以通过遍历回滚指针找到。2、在可重复读(REPEATABLEREAD)隔离级别下,InnoDB的MVCC是如何工作的?查询(SELECT)InnoDB根据以下两个条件检查每一行记录:InnoDB只查找版本早于当前事务版本的数据行(即该行的系统版本号小于或等于事务的系统版本号),它确保事务读取的行要么在事务开始之前就存在,要么被事务本身插入或修改。该行的删除版本未定义或大于当前事务版本号。这确保事务读取的行在事务开始之前不会被删除。只有满足以上两个条件的记录才能作为查询结果返回。插入(INSERT)InnoDB将当前系统版本号保存为每个新插入行的行版本号。删除(DELETE)InnoDB将当前系统版本号保存为删除的每一行的行删除标识符。删除在内部被视为更新,行中的一个特殊位被设置为已删除。更新(UPDATE)InnoDB是插入一个新行,将当前系统版本号保存为行版本号,将当前系统版本号保存到原行作为行删除标识。五、总结多版本并发控制(MVCC)在一定程度上实现了读写并发,它只工作在可重复读(REPEATABLEREAD)和提交读(READCOMMITTED)两种隔离级别下。另外两个隔离级别与MVCC不兼容,因为READUNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行。并且SERIALIZABLE将锁定所有读取的行。行锁、并发、事务回滚等各种特性都与MVCC有关。参考:MySQL5.7文档:innodb-multi-versioning《高性能MySQL》