Oracle - 事务、回滚段和undo_retention参数是如何工作的?

9
我不是DBA,对Oracle的事务管理流程有些难以理解。
根据我在互联网上阅读的可靠页面(尤其是这个AskTom note - 但不要管评论),当事务提交时,新数据并没有立即报告到实际数据块上,而是留存在回滚段中。当有人对数据进行SELECT操作或者UNDO_RETENTION秒数已经过去 - 无论哪种情况先发生 - 新数据才会被写入数据块。
但我们公司的一位据说很懂行的人最近告诉我相反的情况:据他所说,当事务提交时,新数据会立即写入数据块,而回滚段/撤销表空间会保留旧数据UNDO_RETENTION秒。这些旧数据在此期间仍可供查询使用,前提是在事务之前启动了SCN。
那么,在Oracle内部真正发生了什么,并且您能提供支持您回复的参考资料吗?
我们正在使用Oracle 9.2.0.8。
提前致谢。
3个回答

14

这里涉及到很多内容!你公司的人基本上是正确的,除了更改在提交之前就被写入内存数据块中,并且它们独立于提交时被完全写入磁盘(可能在之前、之后、永远不会作为提交操作的一部分)。

1)UNDO_RETENTION与更改何时写入内存或磁盘的数据块无关。 UNDO_RETENTION控制在提交更改后需要撤消更改所必需的数据持续的时间。其目的是其他查询或在您提交之前启动的可串行事务可能仍需要该数据。参考:http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/undo.htm#sthref1477

2)当您执行更新时,内存中的数据块会被修改。它们可能会被写入磁盘(我相信这可能会在提交之前或之后进行);这由后台进程完成。还会将重做信息写入重做日志缓冲区。 撤消生成并存储在一个撤消段中。

3)当您提交时,Oracle确保将重做信息写入磁盘,并将撤消数据标记为已提交。 但它不会将内存中更改的数据块写入磁盘,也不会返回并标记每个块为已提交。这是为了使提交尽可能快。参考:http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/transact.htm#sthref628

4) 内存中的数据块将在后台进程将它们写入磁盘时或下一次使用(通过 SELECT 或任何其他操作)时标记为已提交。这就是 AskTom 文章讨论的内容。这与您对数据所做更改是否写入该块无关,而是关于它们是否在块本身中标记为已提交。


3
是的,你说得对,脏块可以在提交之前写入磁盘。这就是为什么SELECT语句可能会生成重做日志--它可能需要执行“延迟块清除”的操作。重要的是,提交仅保证将重做日志写入磁盘--而不是数据本身。 - David Aldridge

0

我的理解是(基本上)后者,此链接有详细信息。

数据块不必被写入,只需在缓冲区中更新,它们可能会被写入磁盘,也可能不会。但是,在提交之前必须将重做日志写入磁盘。


0

我也支持第二个版本,基于这个链接(它是Oracle 10.2,但我认为它仍然适用于9.2)。

它说: “在提交事务后,回滚或事务恢复目的不再需要撤消数据。但是,对于一致性读取目的,长时间运行的查询可能需要此旧的撤消信息以生成数据块的旧图像。”

“启用自动撤消管理时,始终存在当前的撤消保留期,这是Oracle数据库尝试在覆盖它之前保留旧的撤消信息的最短时间。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接