Quantcast
Channel: Oracle Bloggers
Viewing all articles
Browse latest Browse all 19780

临危不惧 Oracle11g 数据库恢复技术补充 No.2 - v$database.CURRENT_SCN

$
0
0
《临危不惧Oracle 11g 数据库恢复技术》的一位热心读者向我反馈,在11.2.0.3.0中以下命令:

select current_scn from v$database

union all

select current_scn from v$database;

的结果会是两个相同的SCN,与书中描述的11.2.0.1.0版本中会返回两个不同的SCN的情况不符。

的确,该命令与11.2.0.1.0中的不同,11.2.0.3.0只扫描了X$KCCDI(V$DATABASE的一个基表,提供CURRENT_SCN字段)一次,结果只申请了一个新SCN。

----------------------------------------------------
| Id  | Operation            | Name               |
----------------------------------------------------
|   0 | SELECT STATEMENT     |                    |
|   1 |  MERGE JOIN CARTESIAN|                    |
|*  2 |   FIXED TABLE FULL   | X$KCCDI            |
|   3 |   BUFFER SORT        |                    |
|   4 |    VIEW              | VW_JF_SET$6E0AEE5B |
|   5 |     UNION-ALL        |                    |
|   6 |      FIXED TABLE FULL| X$KCCDI2           |
|   7 |      FIXED TABLE FULL| X$KCCDI2           |
----------------------------------------------------

所以如果想在11.2.0.3.0中也要见到一个SQL访问v$database得到不同current_scn的景象的方案就是:让执行计划扫描X$KCCDI的字段dicur_scn(current_scn)至少两次以上。

a. 办法一:多用几个union all,和优化器比耐心,直到优化器把至少一个X$KCCDI2(V$DATABASE的另一个基表)从VIEW里吐出来,迫使X$KCCDI和X$KCCDI2关联多次,即扫描X$KCCDI多次,比如:

SYS@fmw//Scripts> run
  1  select current_scn from v$database
  2  union all select current_scn from v$database
  3  union all select current_scn from v$database
  4* union all select current_scn from v$database

CURRENT_SCN
-----------
    5074384
    5074385
    5074385
    5074385

4 rows selected.

这样,X$KCCDI真正被分别扫了两次,所以一共有两个相异的SCN了。其实两个SCN都是当时扫描时的“新”SCN。

b. 办法二:引入另一个对象,比如:

SYS@fmw//Scripts> run
  1  select current_scn,status from v$database,v$instance
  2  union all
  3* select current_scn,status from v$database,v$instance

CURRENT_SCN + STATUS
----------- + ------------------------
    5075463 + OPEN
    5075464 + OPEN

2 rows selected.

c. 办法三:或者用下面这个查询:

SYS@fmw//Scripts> run
  1* select a.current_scn,b.current_scn from v$database a,v$database b

CURRENT_SCN + CURRENT_SCN
----------- + -----------
    5078328 +     5078329

1 row selected.

当然这连UNION ALL都没有用到。

d. 最后,当然在X$KCCDI上直接多次查询就行了。这其实有违我的“亲民”路线=D,我一般不太希望拿X$什么什么和什么什么$的说事,有故作神秘之嫌,不过由于V$DATABASE和优化器不给面子这次只能俗气一把了:

SYS@fmw//Scripts> run
  1  select dicur_scn from x$kccdi
  2* union all select dicur_scn from x$kccdi

DICUR_SCN
--------------------------------
5082183
5082184

2 rows selected.

SYS@fmw//Scripts> run
  1* select a.dicur_scn,b.dicur_scn from x$kccdi a,x$kccdi b

DICUR_SCN                        + DICUR_SCN
-------------------------------- + --------------------------------
5082913                          + 5082914

1 row selected.

包光磊

Todd Bao

所以,就像我的书里提到的那样,想要获得真正的当前SCN,不要去问V$DATABASE.CURRENT_SCN要,它给的实际上是“next scn”。

×注意,这次的demo采用的是11.2.0.3.版本。




Viewing all articles
Browse latest Browse all 19780

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>