问题描述
你好Oracle大师,
我有一个非常基本的问题来了解oracle的内部行为。我读了几个博客,不幸的是最终陷入了混乱。所以想问你 ..
假设,我正在升级一个区块 (记录),但没有发布 “委员会”。
发生检查点时,数据库编写器将脏块写入磁盘。
问题:
假设当另一个用户查询同一块 (未提交) 时,oracle如何知道 “该” 特定块是脏的,并且应该从 “撤消” 日志中读取 (以保持一致性)?
比如,oracle是否在块标头中维护标志?
我有一个非常基本的问题来了解oracle的内部行为。我读了几个博客,不幸的是最终陷入了混乱。所以想问你 ..
假设,我正在升级一个区块 (记录),但没有发布 “委员会”。
发生检查点时,数据库编写器将脏块写入磁盘。
问题:
假设当另一个用户查询同一块 (未提交) 时,oracle如何知道 “该” 特定块是脏的,并且应该从 “撤消” 日志中读取 (以保持一致性)?
比如,oracle是否在块标头中维护标志?
专家解答
它在块标题上。你可以从v $ bh看到这个,
但是在最简单的概念形式中,SCN可以驱动所有这些。
当我运行查询时,我实际上是在说 “我需要所有块作为SCN 1234” (即,当查询开始时SCN)。
当我遇到一个块时,无论它是否脏,是否已提交,我的要求将是-该块上的SCN是否等于或在1234之前。如果不是,那么这个块对我来说太 “新” 了,这是一个信号,表明我需要得到它的旧版本。
SQL> alter system flush buffer_cache;
System altered.
SQL> create table t ( x primary key, y ) as select 1 x, 2 y from dual;
Table created.
SQL> select data_object_id from user_objects where object_name = 'T';
DATA_OBJECT_ID
--------------
101919
SQL>
SQL> select
2 dbms_rowid.rowid_relative_fno(rowid) f,
3 dbms_rowid.rowid_block_number(rowid) b
4 from t;
F B
---------- ----------
7 16259
--
-- here's the freshly created block
--
SQL> select status
2 from v$bh
3 where file# = 7
4 and block# = 16259
5 and objd = 101919
6 /
STATUS
----------
xcur
--
-- if I flush the buffer cache, the block is still "there" but its marked as free, ie, I could replace it
-- with something else
--
SQL> alter system flush buffer_cache;
System altered.
SQL> select status
2 from v$bh
3 where file# = 7
4 and block# = 16259
5 and objd = 101919
6 /
STATUS
----------
free
--
-- I query it back in, and it is the current version of this block because
-- nothing else has ever need to read it consistently
--
SQL> select * from t where x=1;
X Y
---------- ----------
1 2
SQL> select objd, status
2 from v$bh
3 where file# = 7
4 and block# = 16259
5 and objd = 101919
6 /
OBJD STATUS
---------- ----------
101919 xcur
--
-- now I delete it (without commit)
--
SQL> delete from t;
SQL> select objd, status, dirty
2 from v$bh
3 where file# = 7
4 and block# = 16259
5 and objd = 101919
6 /
OBJD STATUS DIRTY
---------- ---------- -----
101919 xcur Y
--
-- and now another session gets an older version of it via a query
--
SQL> select * from t where x=1;
X Y
---------- ----------
1 2
--
-- and we can see the consistent version be created
--
SQL> select objd, status
2 from v$bh
3 where file# = 7
4 and block# = 16259
5 and objd = 101919
6 /
OBJD STATUS
---------- ----------
101919 xcur
101919 cr
但是在最简单的概念形式中,SCN可以驱动所有这些。
当我运行查询时,我实际上是在说 “我需要所有块作为SCN 1234” (即,当查询开始时SCN)。
当我遇到一个块时,无论它是否脏,是否已提交,我的要求将是-该块上的SCN是否等于或在1234之前。如果不是,那么这个块对我来说太 “新” 了,这是一个信号,表明我需要得到它的旧版本。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




