其实很多朋友都知道_NEXT_OBJECT是怎么回事,但这里我还是说一说吧,已经很清楚_NEXT_OBJECT的作用的朋友可以不用看剩下的内容了。
bootstrap$里并没有obj#=1的记录,如下所示:
SQL> select * from bootstrap$ where obj#=1;
LINE# OBJ# SQL_TEXT
---------- ---------- --------------------------------------------------------------------------------
这是因为在oracle里obj#=1的object有特殊的作用,我们来看一下obj#=1的object是什么:
SQL> select obj#,name,type#,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid) location from obj$ t where obj#=1;
OBJ# NAME TYPE# LOCATION
---------- ------------------------------ ---------- -----------------------------------------------
1 _NEXT_OBJECT 0 1_122
可以看到oracle里obj#=1的object是_NEXT_OBJECT,这条记录现在的位置是在file 1,block 122。注意这里其TYPE#是0,关于obj$中type#的定义可以从sql.bsq中获取详细的信息,如下所示:
type# number not null, /* object type (see KQD.H): */
/* 1 = INDEX, 2 = TABLE, 3 = CLUSTER, 4 = VIEW, 5 = SYNONYM, 6 = SEQUENCE, */
/* 7 = PROCEDURE, 8 = FUNCTION, 9 = PACKAGE, 10 = NON-EXISTENT, */
/* 11 = PACKAGE BODY, 12 = TRIGGER, 13 = TYPE, 14 = TYPE BODY, */
/* 19 = TABLE PARTITION, 20 = INDEX PARTITION, 21 = LOB, 22 = LIBRARY, */
/* 23 = DIRECTORY , 24 = QUEUE, */
/* 25 = IOT, 26 = REPLICATION OBJECT GROUP, 27 = REPLICATION PROPAGATOR, */
/* 28 = JAVA SOURCE, 29 = JAVA CLASS, 30 = JAVA RESOURCE, 31 = JAVA JAR, */
/* 32 = INDEXTYPE, 33 = OPERATOR , 34 = TABLE SUBPARTITION, */
/* 35 = INDEX SUBPARTITION */
/* 57 = SECURITY PROFILE */
可以看到sql.bsq中对obj$的type#说明里唯独没有type#是0的情况。
那么_NEXT_OBJECT到底是什么呢?
311922.1中提到:
SYS._NEXT_OBJECT is an internal mechanism to generate the next OBJECT_ID or DATA_OBJECT_ID value when a new object is created in the database or you truncate an exisitng table. Oracle needs to lock this object, which is actually a sequence generator to get the value and use it. Waits on the _NEXT_OBJECT is expected as your application is doing repeatedly truncates and creates of database tables.
说的是再清晰不过了,我们现在来验证一下:
SQL> create table t1 as select * from dba_users;
Table created
SQL> alter system checkpoint;
System altered
SQL> select dump('_NEXT_OBJECT',16) from dual;
DUMP('_NEXT_OBJECT',16)
--------------------------------------------------
Typ=96 Len=12:
BBED> set file 1
FILE# 1
BBED> set block 122
BLOCK# 122
BBED> dump
File: /dras11/oradata/astca/system01.dbf (1)
Block: 122 Offsets: 0 to 511 Dba:0x
------------------------------------------------------------------------
06020000
00080000 00010200 00000000 0005001e 0001b684
aa
01101dec 1da41d64 1d221ce1 1ca
161415d8 15981559 151d14d5
122411e3
0e150dd6 0d960d55 0d150cd5
00000000 00000000 00000000 00000000 00000000
<32 bytes per line>
BBED> set offset 340
OFFSET 340
BBED> dump
File: /dras11/oradata/astca/system01.dbf (1)
Block: 122 Offsets: 340 to 851 Dba:0x
------------------------------------------------------------------------
c102ff01
ff0180ff
280180ff ff0180ff
2b340778
05640180
042b2807
<32 bytes per line>
从dump出来的结果我们可以看到:现在在_NEXT_OBJECT上ITL上的LCK是01,其对应的XID为0005001e 0001b684,我们接着来看一下undo$:
SQL> select file#,block# from undo$ where us#=5;
FILE# BLOCK#
---------- ----------
2 73
我们dump一下上述block,如下是dump出来的内容:
Start dump data blocks tsn: 1 file#: 2 minblk 73 maxblk 73
buffer tsn: 1 rdba: 0x00800049 (2/73)
scn: 0x0008.aa
frmt: 0x02 chkval: 0x0000 type: 0x26=KTU SMU HEADER BLOCK
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 2 #blocks: 15
last map 0x00000000 #maps: 0 offset: 4080
Highwater:: 0x
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Unlocked
Map Header:: next 0x00000000 #extents: 2 obj#: 0 flag: 0x40000000
Extent Map
-----------------------------------------------------------------
0x
0x
Retention Table
-----------------------------------------------------------
Extent Number:0 Commit Time: 1243855490
Extent Number:1 Commit Time: 1244001080
TRN CTL:: seq: 0x
mgc: 0x8201 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
uba: 0x
Version: 0x01
FREE BLOCK POOL::
uba: 0x
uba: 0x00000000.4725.04 ext: 0x10 spc: 0x1e
uba: 0x00000000.4690.07 ext: 0x0 spc: 0x1ce8
uba: 0x
uba: 0x00000000.3ab4.01 ext: 0x2 spc: 0x1fa0
TRN TBL::
index state cflags wrap# uel scn dba parent-xid nub stmt_num
------------------------------------------------------------------------------------------------
0x00 9 0x00 0x1b72b 0x0010 0x0008.aa059391 0x
......省略显示部分内容
0x1e 9 0x00 0x1b684 0x0004 0x0008.aa
......省略显示部分内容
0x
End dump data blocks tsn: 1 file#: 2 minblk 73 maxblk 73
我们从dump出来的结果可以看到XID为0005001e 0001b684所对应的那条在transaction table中的记录的state是9,9表示Inactive,no local transaction,即obj$中_NEXT_OBJECT这条记录实际上是已经commit了,只不过其行头的ITL没有被清掉,从我后续的测试来看,不管我怎样操作,只要我没碰122这个block,那oracle这里根本就不会清掉_NEXT_OBJECT所对应记录行头上的ITL。
我们这里继续,现在我们来看一个能清掉行头ITL的例子:
继续来看一下我们之前建的表T1:
SQL> select obj#,name,type#,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid) location from obj$ where name='T1';
OBJ# NAME TYPE# LOCATION
---------- ----------- ---------- --------------------------------------------------------------------------------
86148 T1 2 1_55579
SQL> select dump('T1',16) from dual;
DUMP('T1',16)
-------------------
Typ=96 Len=2: 54,31
BBED> set file 1
FILE# 1
BBED> set block 55579
BLOCK# 55579
BBED> dump
File: /dras11/oradata/astca/system01.dbf (1)
Block: 55579 Offsets: 0 to 511 Dba:0x0040d91b
------------------------------------------------------------------------
06020000 0040d91b aa
00080000
aa
1de21d93 1d3b1cf6 1cac
19591912
14d2148b 144213fc 13b6136d 131e0618 12931250
10541000 0fb
0ba
50455253
06140b19
ff
ff0180ff
50445454
786d0303 0e
c
<32 bytes per line>
BBED> set offset 1335
OFFSET 1335
BBED> dump
File: /dras11/oradata/astca/system01.dbf (1)
Block: 55579 Offsets: 1335 to 1846 Dba:0x0040d91b
------------------------------------------------------------------------
1b
c1410954 45535444
121b0607 786d
786d
c
c102ff
02ffff01 80ff
1d1d0778 6d
1407786d
<32 bytes per line>
从dump结果里我们可以看到现在obj$中T1这条记录的行头的ITL是01,现在我们让这个01消失:
SQL> create table t2 as select * from dba_users;
Table created
SQL> alter system checkpoint;
System altered
SQL> select obj#,name,type#,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid) location from obj$ where name='T2';
OBJ# NAME TYPE# LOCATION
---------- ------------------ ---------- --------------------------------------------------------------------------------
86149 T2 2 1_55579
退出BBED后再次进入:
$ bbed parfile=par.txt
Password:
BBED: Release
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED> set file 1
FILE# 1
BBED> set block 55579
BLOCK# 55579
BBED> set offset 1335
OFFSET 1335
BBED> dump
File: /dras11/oradata/astca/system01.dbf (1)
Block: 55579 Offsets: 1335 to 1846 Dba:0x0040d91b
------------------------------------------------------------------------
1b
c1410954 45535444
121b0607 786d
786d
c
c102ff
02ffff01 80ff
1d1d0778 6d
1407786d
<32 bytes per line>
可以看到,我这里已经成功让obj$中T1这条记录的行头的ITL由01变成了00,这里的本质原因是因为55579这个block里ITC只有1个。
呵呵,说了一大堆没什么用的东西,现在来说一点有用的,很多朋友都知道obj#小于56的那些object是oracle中的核心bootstrap对象,其实还有一些非核心的bootstrap对象也需要我们注意,301416.1中对这些非核心的bootstrap对象有所描述:
Objects with data_object_id less than 56 are classified as core bootstrap objects.
The objects are added to the bootstrap. The objects affected are:
hist_head$
histgrm$
i_hh_obj#_col#
i_hh_obj#_intcol#
i_obj#_intcol#
i_h_obj#_col#
c_obj#_intcol#
From 10.1 the following objects have been added:
fixed_obj$
tab_stats$
ind_stats$
i_fixed_obj$_obj#
i_tab_stats$_obj#
i_ind_stats$_obj#
object_usage
These additional objects shall be re-classified (or) ignored by following methods.
1. Opening the database in migrate mode
Leave a comment