首页oracle数据库好文转载 › 一致性读2-翻译jonathanlewis的一篇blog

一致性读2-翻译jonathanlewis的一篇blog

Add to Google 鲜果阅读器订阅图标

翻译自:http://jonathanlewis.wordpress.com/2009/06/12/consistent-gets-2/

一致性读(2):

如何用简洁的语言来描述“db block gets” 和 “consistent gets”之间的区别呢?在看了很多答案之后,我觉得我有必要仔细的说明一下我对这个问题的理解。

在阐述想法之前,我想先说明一下,oracle访问数据库高速缓冲区中的数据块通常有两种方式(至少两种):重新读取钉住的缓冲块(pinned buffers),并在提交(commit)时做一次快速块清除(Fast Block Cleanout)。可以通过“buffer is pinned count”和“commit cleanouts successfully completed”这两个统计信息条目得到这类缓冲区块的相关统计信息。(其中,统计信息条目“commit cleanouts”会告诉你oracle一共进行了多少次提交块清除(Commit Cleanout),另外,还有多个统计信息条目可用于解释块清除的失败原因。)

在最初的回答中,我已经指出,oracle在变更数据块时,可能不会产生任何类型的“get”以及undo和redo,这就是提交块清除(“commit cleanout”)。严格来说,我没有准确表达我的意思,即真正的清理将交由下一个更新这个块的事务完成,并且由下一个操作产生相关的UNDO和REDO。因此,从技术角度讲,“commit cleanout”是产生undo和redo的原因,即使它出现了延迟。

言归正传:

oracle需要查看最新版本的块时,会产生db block gets,它包括所有未提交的块变更。但是,即使当前块已经是最新版本,“commit cleanouts”操作也不会产生db block gets。

下面是产生db block gets的两个常见场景:

 访问的数据块发生变更。你将改变块的最新版本…

l   通过访问索引块去检查唯一约束和其它的完整性约束。在后台运行过程中,你的会话(session)需要看到其它会话未提交的变更(即使那些用户没有权限允许查看这些变更),这是为了避免在别的会话提交后,出现你想做的变更违反了约束的情况。这类冲突常常引起TXEnqueue上模式为4的等待。

l     一致性读是另一种“latch  protected”的块访问(也就是说,不仅仅只访问pinned buffers),这种情况下,不需要看到块的最新版本。

下面是产生consistent gets的两个常见场景:

l     读取undo段去找出相关的记录,用于构造数据块的一致读版本…

l     读取某个特定时间点的数据块以用于展示,这是一个已经提交的块(通过scn号来选取)。

当然,你要做的就是给已经发生变更的块映象作一个正确的排序:db block get读取块的最新版本,consistent read使用undo去回放块映象到一个较前的时间点。但是,通过查看Statspack或AWR报告能够获取更准确的数据。

这里,有一个点经常会被忽略,那就是我前面提到的一个点。一个“read-consistent”块可能会处于以前从没出现过的状态。考虑下面的场景:

l     Session 1 更新了块中的row 1(第一行记录),但是没有提交。

l     Session 2 更新了块中的row 2(第二行记录),并提交。

l     Session 3 查询这个块。

Session 3需要应用undo的记录,它复制undo块并还原到row 1更新之前的版本。这时,因为“read-consistent”,需要复制块,块的内容变成:变更后的row 2,和未变更的row 1。这时,块就处在一个之前没有出现过的状态。

一旦你理解了这个简单的场景,你就能够明白,当许多长事务和短事务一起更新数据库的一小部分块时,为什么会可能看到大量的逻辑读(consistent gets)。如果一个数据块被另外的会话改变,另外很多个会话常常会通过undo来创建一个块的多个版本。如果使用“select for update”,并在稍后使用“update”,问题可能会更严重。

最后一个观点 –如果想要更新数据块,你需要通过db block get来获取它,从而保证你得到了最新的数据。但是,在更新之前,你必须得到一个此块的一致读版本,以确认以下两点:

l     在update开始时,要更新的行在块中存在。

l     当开始更新一行时,它们可能同时被其它的事务删除或更新了(可能提交,可能没提交),这时你要更新的行已经不存在了(missing 行)。

当你在仔细思考一致性读时,有时候你会感叹oracle的技术是多么的伟大。所以,设法去理解它在所有领域的设计思想吧!

 

1 条评论。[ 发表评论 ]

发表评论

注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

普人特福的博客cnzz&51la for wordpress,cnzz for wordpress,51la for wordpress