暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

oracle如何识别 “脏块”

askTom 2018-09-04
415

问题描述

你好Oracle大师,
我有一个非常基本的问题来了解oracle的内部行为。我读了几个博客,不幸的是最终陷入了混乱。所以想问你 ..

假设,我正在升级一个区块 (记录),但没有发布 “委员会”。

发生检查点时,数据库编写器将脏块写入磁盘。

问题:
假设当另一个用户查询同一块 (未提交) 时,oracle如何知道 “该” 特定块是脏的,并且应该从 “撤消” 日志中读取 (以保持一致性)?
比如,oracle是否在块标头中维护标志?

专家解答

它在块标题上。你可以从v $ bh看到这个,

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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论