搜索
写经验 领红包

多版本并发控制mvcc(并发控制带来的三个问题)

导语:多版本并发控制(MVCC)与一致性读(二)

上篇介绍了执行update语句,undo中保存的信息。今天我们再看看执行delete和insert时,undo中保存了什么。

执行一条delete语句

dump出undo块,查看trace文件

undo块中第7条记录记录了此事务的回滚信息

记录了两列信息,转换成文本后,正好是8 和name8。由此可见当执行delete语句时,undo中记录的是删除的行的所有字段的值。

执行一条insert语句,记住编号100,表示这行数据在数据块中的位置。

dump出undo块,查看trace文件

查看undo块中第2条记录信息

KDO Op code: DRP --表示操作类型,DRP=delete row piece

bdba: 0x01800417 --对应的数据文件和块,转换成二进制,前10位为数据文件号,后22位为块号 ,6 号数据文件,1047号块。

slot: 100(0x64) --行在数据块中的位置,与上面select出来的row number正好对应。

由此可见,当执行insert时,undo中只会记录回滚时需要的操作DRP,和数据行的位置。

总结:

update、insert、delete操作时,undo中记录的信息不一样。insert时,只记录了插入数据在数据块中的位置。update时,记录的是修改字段的前镜像值。delete时,记录的是整行数据。insert记录的信息最好,update记录的信息居中,delete记录的信息最多。因此,执行delete操作需要更多的undo空间记录回滚信息,回滚时需要从undo中拷贝更多的数据到数据块中,因此,delete操作的代价最昂贵。

如果在同一个事务里,对某一行数据的某一个字段值进行了多次修改,如将name=&39;修改为name=&39;,再改为name=&39;,最后改成name=&39;,此时undo中会记录每一次的修改信息呢,还是只记录最后一次修改的信息呢?

查看undo块信息

查看第6条undo记录

col 1: [ 1] 63 --转换成字符为c

rci 0x05 -- 指向同一个事务的上一条undo记录

依次转换col 1的值为字符得到 c->b->a->name1,正好与更新的顺相反,一次撤销即可实现回滚。rci 0x00表示本事务的第一条记录。

因此可以得出如下结论:

在同一事务里,对某一个字段值反复更新,undo会记录每次操作的前镜像值,即会记录中间结果。

介绍了这么多undo的内容,是因为Oracle的多版本并发控制(MVCC)与一致性读是通过undo实现的。MVCC简单来说就是在同一时刻,数据有多个版本,不同的会话可以获取不同版本的数据。一致性读是在同一时刻,其他会话不能看到本话会修改但是未提交的数据,这是为了避免脏读。其他会话看到的是当前内存中的数据块和undo块构造的包含数据修改前的旧数据的一致性数据块,因此称为一致性读。构造一致性读数据块的过程就是先读取内存中实际的数据块,再根据undo记录的条目,逐条地回滚到指定的时刻,即完成了数据的回滚操作。通过构造一致性读数据块,读不会影响写操作,写也不会影响读操作,极大地提高了数据块的并发能力。Oracle的闪回功能也是通过undo来实现的。

免责声明:本站部份内容由优秀作者和原创用户编辑投稿,本站仅提供存储服务,不拥有所有权,不承担法律责任。若涉嫌侵权/违法的,请反馈,一经查实立刻删除内容。本文内容由快快网络小芦创作整理编辑!