这个块存放的就是表BOOTSTRAP$的头块,这个表仅仅占用了一个区间。 继续跟踪文件: ******************************************************************************** SQL ID: 6apq2rjyxmxpj Plan Hash: 867914364 select line#, sql_text from bootstrap$ where obj# != :1
从上面看到,oracle在装载file 1 block 520后,就开始从这个表读取内容,实际上读取的是一些sql语句,然后利用这些sql语句创建数据库启动的必要对象: SYS AS SYSDBA >select line#,obj#,sql_text from bootstrap$ where rownum<=3; LINE#| OBJ#|SQL_TEXT ----------|----------|---------------------------------------------------------------------------------------------------- -1| -1|8.0.0.0.0 0| 0|CREATE ROLLBACK SEGMENT SYSTEM STORAGE ( INITIAL 112K NEXT 56K MINEXTENTS 1 MAXEXTENTS 32765 OBJNO | |0 EXTENTS (FILE 1 BLOCK 128))
20| 20|CREATE TABLE ICOL$("OBJ#" NUMBER NOT NULL,"BO#" NUMBER NOT NULL,"COL#" NUMBER NOT NULL,"POS#" NUMBER | | NOT NULL,"SEGCOL#" NUMBER NOT NULL,"SEGCOLLENGTH" NUMBER NOT NULL,"OFFSET" NUMBER NOT NULL,"INTCOL# | |" NUMBER NOT NULL,"SPARE1" NUMBER,"SPARE2" NUMBER,"SPARE3" NUMBER,"SPARE4" VARCHAR2(1000),"SPARE5" V | |ARCHAR2(1000),"SPARE6" DATE) STORAGE ( OBJNO 20 TABNO 4) CLUSTER C_OBJ#(BO#)
where x.inst_id =userenv('Instance')and y.inst_id =userenv('Instance')and x.indx = y.indx and(x.ksppinm like'%&par%');
/
Enter value for par: init_sql old 3: where x.inst_id = userenv('Instance') and y.inst_id = userenv('Instance') and x.indx = y.indx and (x.ksppinm like '%&par%') new 3: where x.inst_id = userenv('Instance') and y.inst_id = userenv('Instance') and x.indx = y.indx and (x.ksppinm like '%init_sql%')
KSPPINM |KSPPDESC |KSPPSTVL --------------------|----------------------------------------|---------- _init_sql_file |File containing SQL statements to execut|?/rdbms/ad |e upon database creation |min/sql.bs | |q 创建数据库的create database语句隐含就要执行sql.bsp中的内容,这个文件包含了许多个bsp文件,其中的dcore.bsq文件就有表bootstrap$的创建语句: create table bootstrap$ ( line# number not null, /* statement order id */ obj# number not null, /* object number */ sql_text varchar2("M_VCSZ") not null) /* statement */ storage (initial 50K) /* to avoid space management during IOR I */ // /* "//" required for bootstrap */ 通过上面的分析,数据库在内存中建立表结构后,直接定位到file 1 block 520,从而继续后面的工作。那么,他怎么知道是这个块是bootstrap$的块呢?那就要看system表空间记录的root dba了。
5. root dba 相关 system表空间的数据文件头记录了这个东西,转存system表空间一号数据文件头看看: 10 STYLE FILE HEADER: Compatibility Vsn = 186646528=0xb200000 Db ID=763100300=0x2d7bfc8c, Db Name='HX' Activation ID=0=0x0 Control Seq=14715=0x397b, File size=51200=0xc800 File Number=1, Blksiz=8192, File Type=3 DATA Tablespace #0 - SYSTEM rel_fn:1 Creation at scn: 0x0000.00000009 02/06/2013 17:15:16 Backup taken at scn: 0x0000.000cec73 03/31/2013 21:44:20 thread:1 reset logs count:0x30817c6a scn: 0x0000.003cef48 prev reset logs count:0x305eefc2 scn: 0x0000.000c7def recovered at 05/12/2013 22:15:57 status:0x2004 root dba:0x00400208 chkpt cnt: 1095 ctl cnt:1094 begin-hot-backup file size: 41600 Checkpointed at scn: 0x0000.0054c1ba 05/13/2013 20:02:02 thread:1 rba:(0xa2.4d1e.10) 注意:只有system表空间的文件头才具备root dba,它用来定位数据库引导的bootstrap$信息,root dba一共4字节。 root dba(0x00400208)转换为2进制:0000000001 0000000000001000001000,前面10位表示文件号,就是1(/u01/oradata/hx/system01.dbf)。后面22位表示数据文件1上的第520个块。 函数转换root dba(eygle提供的脚本) SYS AS SYSDBA >CREATE OR REPLACE FUNCTION getbfno (p_dba IN VARCHAR2) 2 RETURN VARCHAR2 3 IS 4 l_str VARCHAR2 (255) DEFAULT NULL; 5 BEGIN 6 l_str := 7 'datafile# is:' 8 || DBMS_UTILITY.data_block_address_file 9 (TO_NUMBER (LTRIM (p_dba, '0x'),'xxxxxxxx')) 10 || chr(10)||'datablock is:' 11 || DBMS_UTILITY.data_block_address_block 12 (TO_NUMBER (LTRIM (p_dba, '0x'),'xxxxxxxx')); 13 RETURN l_str; 14 END; 15 / col bfno for a20
Function created. SYS AS SYSDBA >select getbfno('&a') bfno from dual; Enter value for a: 00400208 old 1: select getbfno('&a') bfno from dual new 1: select getbfno('00400208') bfno from dual BFNO -------------------- datafile# is:1 datablock is:520 不同版本数据库中root dba 块的意义: 通过下面sql语句,可以看到头块为520之前的块的对象。
点击(此处)折叠或打开
SYS AS SYSDBA >select b.object_id,a.segment_name,a.segment_type,a.header_block from dba_segments a,dba_objects b where
a.segment_name=b.object_name(+)and a.header_file=1 and a.header_block<=520 orderby a.header_block;