暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Mvcc机制

IT那活儿 2022-07-10
657
点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!

mvcc的全称是(Multi-Version Concurrency Control)多版本并发控制。此机制是为了解决事务之间同时读写造成的锁导致阻塞。

在数据库中多个用户对一张表的操作,可以简单的概括为三种状态。
  • 一张表,多个用户同时读取数据。(读读)
  • 一张表,一个用户读数据,一个用户写数据。(读写)
  • 一张表,多个用户同时写数据。(写写)
像是第一种情况不会出现冲突,多个用户可以同时执行。
第三种情况是肯定有冲突不能同时执行。

而第二种情况之前有一种很简单粗暴的解决办法,就是加锁但是这样的效率很低,而mvcc机制则是将表中每次更改的记录都保存下来,如果有多个用户进行读写操作,那么读数据的用户所看到的只会是历史数据。执行写操作的用户只要事务没有提交,在事务中所执行的变更对于其他用户来说都是不可见的。

事务与隔离

1. 事务
什么是事务?
简单的说,事务就是将多个操作捆绑成一个操作。所有的操作要么同时执行成功,要么同时执行失败全部回滚成初始状态不会有第三种可能。这就是事务中非常重要的一个概念“原子性”。
  • 一致性:一个事务的执行不能破坏数据库的完整性和一致性,比如如果从A账户转账到B账户,不可能因为A账户扣了钱,而B账户没有加钱。
  • 隔离性:是指多个事务并发执行时,应该是互相隔离,不可相互干扰。此性质下文会详细解释。
  • 持久性:是指事务一旦提交数据就必须永久保存,就算遇到系统或者服务器的故障也不会丢失。
2. 隔离的四个级别
  • 读未提交 Read uncommitted

    这个级别可能会遇到一个问题“脏读”,就是a事务中读取到了b事务中更改的数据,此时b事务回滚a事务读到的数据最终未被更改。而a事务后续所有基于这个数据的操作都是错误的。这个就是脏读。

  • 读已提交 Read committed

    这个级别不会出现脏读的问题,但是重复读的时候可能会发现多次读取的结果不一样。

    举个例子a事务有两个查询x表的数据,第一次查询值为1。此时b事务执行update修改x表值为2。a事务的第二个查询的值就是2。

  • 读可重复 Repeatable read

    该级别解决了读已提交的不可重复读的问题,在事务开启的时候,不能再修改操作了,直到该事务提交。(此时的不能修改值得是在事务中修改了也不会生效)。

    举个例子a事务有两个查询x表的数据,第一次查询值为1。此时b事务执行update修改x表值为2。a事务的第二个查询的值还是1。明明已经被修改但是查询的结果还是未修改的的值,类似这样的结果就是幻读。(在gp中此隔离级别不会出现幻读)

  • 序列化 Serializable

    在该级别下,事务是按照串行化的顺序执行,可以避免脏读,重复读,幻读。虽然可以避免以上的几种问题但是此级别的效率可想而知是非常低的。

在greenplum中每一行数据,有4个隐藏字段。虽然这四个字段是隐藏的,但可以访问。

  • xmin :在创建(insert)记录(tuple)时,记录此值为插入tuple的事务ID。
  • xmax :默认值为0.在删除tuple时,记录此值。
  • cmin和cmax :标识在同一个事务中多个语句命令的序列值,从0开始,用于同一个事务中实现版本可见性判断。

mvcc机制的相关实验

建表:

开启一个事务,插入记录,查看当前的事务号,可以看到隐藏的四个字段值,只有 xmin变成了13511。
开两个窗口,一个窗口更新数据,一个窗口更新数据前查一次,更新后查一次。可以看到xmax已经改变,因为pg更新数据是先删除后插入所以xmax会发生变更。
这样就证明了,greenplum中,读写时不冲突的。

本文作者:徐 瑞(上海新炬王翦团队)

本文来源:“IT那活儿”公众号

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论