读书笔记,Oracle Core(1) redo and undo

第一时间在amazon上买了Jonathan Lewis的新书,Oracle Core: Essential Internals for DBAs and Developers,经过漫长的等待,这本书在年前终于到了我的手上。趁着过年的这段时间,好好读了这本书,我喜欢在读书的时候做笔记,博客便是我做笔记、心得的一个地方。

说句题外话,在亚马逊上买书,纸质的书运费很贵,如果想在2周内到达,基本运费的价格要超过一本书的价格了,所以我们不得不选择比较慢的船运。不过,如果你有kindle或者iPad(装kindle app),那就又是另外一片天地了,你可以选择买电子的图书,价格还比纸质的书便宜,而且瞬间就能push到你的kindle或者iPad上了。所以,如果以后真的再有什么好书的话,我可能会选择买电子的书,而不再是傻傻的等纸书。电子的书可以很方便的进行搜索,单词翻译,做笔记,这都是纸质的书所做不到的事情,特别是翻译,当你遇到一个不认识的单词的时候,点一下就有该单词的翻译了,相当的方便。但是电子书也有不好的地方,特别是在iPad上,看书看个十几分钟,眼睛就酸疼的受不了了,还是纸质的书看起来舒服。

ok,我们言归正传,开始这本书的学习之旅。我不会涉及到这本书的所有方面,只是列出我认为重要的,或者我需要实验的地方,毕竟,纸上得来终觉浅,绝知此事要躬行。

第一章,get started

(1)读一致和scn和undo相关,而undo和transaction相关,transaction有和scn和ITL相关。
(2)有3种必要的表空间:undo tablespace,temporary tablespace和the rest
(3)kcmgss(get snapshot scn)->kcmgas(get and advance scn)

第二章,redo and undo

(1)记录产生的步骤:
(1.1) 创建redo向量,用来描述如何在undo block中插入一条undo记录
(1.2) 创建另一个redo向量,用来描述data block的变化
(1.3) 将上述2个变量合并成一个redo记录,写入到log buffer中
(1.4) 开始在undo block中插入undo记录
(1.5) 开始在data block中执行需要的变化。

我们来看看例子:
某table:

做update前的block情况:

做update:

看看该block的情况:

我们看到在block中,username的那一列,即col 0变了,从asc码的54 45 53 54 5f 32(6个字符,即TEST_2),变成了asc码的54 45 53 54 5f 54 45 53 54 5f 54 45 53 54 5f 32 32 32 32 32 32(21个字符,即TEST_TEST_TEST_222222)。

我们再来看看redo中的情况:
在update前后,进行dump redo:

我们发现update之后的redo log中多了如下的内容:

我看到change #2中有我们的更改前的记录:

change #3中有我们更改后的记录

在这里,我们在redo中除了看到上述的数据变化之外,我们还能获得以下信息:

注意这部分的undo的dump的内容,很像刚刚我们dump出来的redo中的change #2部分。而且change #2中第一行的DBA:0x008004ca,也即为undo block的地址。这也符合我们刚刚1.1~1.5的顺序,先有change #2,即1.1,你可以看到在redo中该change向量和undo block中是多么的类似,完成change #2之后,再做change #3,即block中的更改后的信息。

既然聊到了IMU,这里是传统的undo和IMU的一些比较。注意,不管是传统的undo机制还是IMU,oracle还是会产生一样多的redo向量,他们之间的差别,只是提交到logbuffer的次数。

举例:

那么传统的undo和redo机制为:
在t1:

在t2:

在t3:


关于commit是先更新TX table还是先Flush redo buffer,崔华这里有篇有意思的文章。

那么在IMU的情况下,又是怎么样的呢?
在t1:

在t2:

在t3,commit的时候(我们这里假设commit的时候,IMU也flush了)。

【图一,合并以及写到redo buffer:】



【图二,写redo log以及flush IMU:】

关于是否存在private redo allocation latch和public redo allocation latch,我们可以找到所有redo allocation latch,将其用oradebug poke住,此时运行一个脚本来update和commit,发现会hung住,然后从gets的少数向多数一个一个的释放redo allocation latch,你会发现在倒数第三个时update能做了,但是commit不能做。因为commit需要public redo allocation latch,此时还是poke住的,我们是否第一个或第二个的时候,commit能完成了。因此,在10g的20个redo allocation latch中,18个是private的,2个是public的。
说个题外话,关于各个latch的parent latch数量和子latch数量,可以用以下sql检查。

9i的redo allocation child latch是一个,而10g有20个。

如果说redo的特性是“即写即忘”,那么undo有2个特性:读一致和回滚。

读一致性主要针对某个块,找到这个块所连接的所有的undo记录(前映像)。
而回滚主要针对事务,需要找undo记录所在事务链表。

相关文章

3条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据