对bootstrap$、数据字典结构信息和open相关性的研究

来源:互联网 发布:人工智能学派 编辑:程序博客网 时间:2024/05/16 23:58

环境:

[sql] view plaincopy
  1. 00:24:16 sys@ORCL (^ω^) select * from v$version where rownum=1;  
  2.   
  3. BANNER  
  4. --------------------------------------------------------------------------------  
  5. Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod  


    我们要查询自己系统的一个表,则首先是去数据字典中找到该表的结构性信息。这些结构性信息存储在数据字典表中,但我们又从哪里获得数据字典表本身的结构性信息呢?虽然从表中我们可以查询到字典表本身的结构性信息,那在数据库open的时候最初是如何确定结构的?是写死在程序中呢?还是怎样处理的?oracle是怎么找到系统表空间的物理上的数据的?

[sql] view plaincopy
  1. 23:48:02 sys@ORCL (^ω^) shutdown immediate  
  2. 数据库已经关闭。  
  3. 已经卸载数据库。  
  4. ORACLE 例程已经关闭。  
  5. 23:48:54 sys@ORCL (^ω^) startup mount  
  6. ORACLE 例程已经启动。  
  7.   
  8. Total System Global Area  612368384 bytes  
  9. Fixed Size                  1250428 bytes  
  10. Variable Size             192940932 bytes  
  11. Database Buffers          411041792 bytes  
  12. Redo Buffers                7135232 bytes  
  13. 数据库装载完毕。  
  14. 23:49:20 sys@ORCL (^ω^) alter session set sql_trace=true;  
  15.   
  16. 会话已更改。  
  17.   
  18. 23:49:44 sys@ORCL (^ω^) alter database open;  
  19.   
  20. 数据库已更改。  


    trc文件如下:

[sql] view plaincopy
  1. =====================  
  2. PARSING IN CURSOR #1 len=19 dep=0 uid=0 oct=35 lid=0 tim=18716803687 hv=1907384048 ad='33ecf028'  
  3. alter database open  
  4. END OF STMT  
  5. PARSE #1:c=0,e=1749,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=18716803683  
  6. =====================  


    第一个对象的创建:

[sql] view plaincopy
  1. PARSING IN CURSOR #2 len=188 dep=1 uid=0 oct=1 lid=0 tim=18717747631 hv=1365064427 ad='33ec080c'  
  2. create table bootstrap$ ( line#         number not null,   obj#           number not null,   sql_text   varchar2(4000) not null)   storage (initial 50K objno 56 extents (file 1 block 377))  
  3. END OF STMT  
  4. PARSE #2:c=0,e=549,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=18717747628  
  5. EXEC #2:c=0,e=195,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=18717750171  
  6. =====================  


    逐步提取内容,来建立数据字典表本身的结构

[sql] view plaincopy
  1. PARSING IN CURSOR #2 len=55 dep=1 uid=0 oct=3 lid=0 tim=18717751282 hv=2111436465 ad='33ec0098'  
  2. select line#, sql_text from bootstrap$ where obj# != :1  
  3. END OF STMT  
  4. PARSE #2:c=0,e=538,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=18717751278  
  5. EXEC #2:c=0,e=35732,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=18717789730  
  6. FETCH #2:c=0,e=1528,p=4,cr=3,cu=0,mis=0,r=1,dep=1,og=4,tim=18717792281  
  7. FETCH #2:c=0,e=43,p=0,cr=1,cu=0,mis=0,r=1,dep=1,og=4,tim=18717793026  
  8. FETCH #2:c=0,e=34,p=0,cr=1,cu=0,mis=0,r=1,dep=1,og=4,tim=18717793574  
  9. ..................................  


    先对bootstrap$做些观察:

[sql] view plaincopy
  1. 00:05:00 sys@ORCL (^ω^) desc bootstrap$  
  2.  名称                                      是否为空? 类型  
  3.  ----------------------------------------- -------- ----------------------------  
  4.  LINE#                                     NOT NULL NUMBER  
  5.  OBJ#                                      NOT NULL NUMBER  
  6.  SQL_TEXT                                  NOT NULL VARCHAR2(4000)  
  7.   
  8. 00:05:42 sys@ORCL (^ω^) select count(1) from bootstrap$;  
  9.   
  10.   COUNT(1)  
  11. ----------  
  12.         57  
  13.   
  14. 00:05:55 sys@ORCL (^ω^) select obj#,sql_text from bootstrap$ where rownum<11;  
  15.   
  16.       OBJ#  
  17. ----------  
  18. SQL_TEXT  
  19. --------------------------------------------------------------------------------  
  20.         -1  
  21. 8.0.0.0.0  
  22.   
  23.          0  
  24. CREATE ROLLBACK SEGMENT SYSTEM STORAGE (  INITIAL 112K NEXT 1024K MINEXTENTS 1 M  
  25. AXEXTENTS 32765 OBJNO 0 EXTENTS (FILE 1 BLOCK 9))  
  26.   
  27.         20  
  28. CREATE TABLE ICOL$("OBJ#" NUMBER NOT NULL,"BO#" NUMBER NOT NULL,"COL#" NUMBER NO  
  29.   
  30.       OBJ#  
  31. ----------  
  32. SQL_TEXT  
  33. --------------------------------------------------------------------------------  
  34. NULL,"POS#" NUMBER NOT NULL,"SEGCOL#" NUMBER NOT NULL,"SEGCOLLENGTH" NUMBER NO  
  35. NULL,"OFFSET" NUMBER NOT NULL,"INTCOL#" NUMBER NOT NULL,"SPARE1" NUMBER,"SPARE  
  36. 2" NUMBER,"SPARE3" NUMBER,"SPARE4" VARCHAR2(1000),"SPARE5" VARCHAR2(1000),"SPARE  
  37. 6" DATE) STORAGE (  OBJNO 20 TABNO 4) CLUSTER C_OBJ#(BO#)  
  38.   
  39.         40  
  40. CREATE INDEX I_ICOL1 ON ICOL$(OBJ#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  
  41.   INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO  
  42. 40 EXTENTS (FILE 1 BLOCK 249))  
  43.   
  44.       OBJ#  
  45. ----------  
  46. SQL_TEXT  
  47. --------------------------------------------------------------------------------  
  48.   
  49.         28  
  50. CREATE TABLE CON$("OWNER#" NUMBER NOT NULL,"NAME" VARCHAR2(30) NOT NULL,"CON#" N  
  51. UMBER NOT NULL,"SPARE1" NUMBER,"SPARE2" NUMBER,"SPARE3" NUMBER,"SPARE4" VARCHAR2  
  52. (1000),"SPARE5" VARCHAR2(1000),"SPARE6" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 M  
  53. AXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645  
  54.  PCTINCREASE 0 OBJNO 28 EXTENTS (FILE 1 BLOCK 169))  
  55.   
  56.         48  
  57.   
  58.       OBJ#  
  59. ----------  
  60. SQL_TEXT  
  61. --------------------------------------------------------------------------------  
  62. CREATE UNIQUE INDEX I_CON1 ON CON$(OWNER#,NAME) PCTFREE 10 INITRANS 2 MAXTRANS 2  
  63. 55 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCRE  
  64. ASE 0 OBJNO 48 EXTENTS (FILE 1 BLOCK 313))  
  65.   
  66.         49  
  67. CREATE UNIQUE INDEX I_CON2 ON CON$(CON#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STOR  
  68. AGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 O  
  69. BJNO 49 EXTENTS (FILE 1 BLOCK 321))  
  70.   
  71.   
  72.       OBJ#  
  73. ----------  
  74. SQL_TEXT  
  75. --------------------------------------------------------------------------------  
  76.         15  
  77. CREATE TABLE UNDO$("US#" NUMBER NOT NULL,"NAME" VARCHAR2(30) NOT NULL,"USER#" NU  
  78. MBER NOT NULL,"FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT NULL,"SCNBAS" NUMBER,"  
  79. SCNWRP" NUMBER,"XACTSQN" NUMBER,"UNDOSQN" NUMBER,"INST#" NUMBER,"STATUS$" NUMBER  
  80.  NOT NULL,"TS#" NUMBER,"UGRP#" NUMBER,"KEEP" NUMBER,"OPTIMAL" NUMBER,"FLAGS" NUM  
  81. BER,"SPARE1" NUMBER,"SPARE2" NUMBER,"SPARE3" NUMBER,"SPARE4" VARCHAR2(1000),"SPA  
  82. RE5" VARCHAR2(1000),"SPARE6" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255  
  83.  STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREAS  
  84. E 0 OBJNO 15 EXTENTS (FILE 1 BLOCK 105))  
  85.   
  86.       OBJ#  
  87. ----------  
  88. SQL_TEXT  
  89. --------------------------------------------------------------------------------  
  90.   
  91.         34  
  92. CREATE UNIQUE INDEX I_UNDO1 ON UNDO$(US#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STO  
  93. RAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0  
  94. OBJNO 34 EXTENTS (FILE 1 BLOCK 201))  
  95.   
  96.         35  
  97. CREATE INDEX I_UNDO2 ON UNDO$(NAME) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  
  98.   INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO  
  99.   
  100.       OBJ#  
  101. ----------  
  102. SQL_TEXT  
  103. --------------------------------------------------------------------------------  
  104. 35 EXTENTS (FILE 1 BLOCK 209))  
  105.   
  106.   
  107. 已选择10行。  


    由这里我们可以看出,bootstrap$ 中实际上是记录了一些数据库系统基本对象的创建语句。对我们的数据库来说,也可以看成是建立一个表结构,通过这个结构可以借助关系型数据库的方式去获取文件中的数据。

 

    继续trc文件的内容

[sql] view plaincopy
  1. =====================  
  2. 在数据库系统表空间的头部创建了系统回滚段(block 9 开始,1---8  属于数据文件头)  
  3. PARSING IN CURSOR #2 len=129 dep=1 uid=0 oct=36 lid=0 tim=18717824579 hv=0 ad='3e5398'  
  4. CREATE ROLLBACK SEGMENT SYSTEM STORAGE (  INITIAL 112K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 32765 OBJNO 0 EXTENTS (FILE 1 BLOCK 9))  
  5. END OF STMT  
  6. PARSE #2:c=0,e=347,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=18717824575  
  7. EXEC #2:c=0,e=111,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=18717826689  
  8.   
  9. =====================  


    这里同样是直接指定了该cluster 的段头位置  block 25。

[sql] view plaincopy
  1. PARSING IN CURSOR #2 len=209 dep=1 uid=0 oct=4 lid=0 tim=18717827549 hv=0 ad='3e5398'  
  2. CREATE CLUSTER C_OBJ#("OBJ#" NUMBER) PCTFREE 5 PCTUSED 40 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 136K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 2 EXTENTS (FILE 1 BLOCK 25)) SIZE 800  
  3. END OF STMT  
  4. PARSE #2:c=0,e=336,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=18717827546  
  5. EXEC #2:c=0,e=125,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=18717829736  
  6.   
  7. 00:19:30 sys@ORCL (^ω^) select file_id,block_id from dba_extents where segment_name='C_OBJ#';  
  8.   
  9.    FILE_ID   BLOCK_ID  
  10. ---------- ----------  
  11.          1         25  
  12.          1         33  
  13.          1         41  
  14.          1       3665  
  15.          1       4929  
  16.          1       5841  
  17.          1       6105  
  18.          1       6129  
  19.          1       6153  
  20.          1       6169  
  21.          1       6193  
  22.          1       6217  
  23.          1       6249  
  24.          1       6265  
  25.          1       6281  
  26.          1       6313  
  27.          1       6409  
  28.          1       7817  
  29.          1      14601  
  30.          1      27145  
  31.          1      48905  
  32.          1      56585  
  33.   
  34. 已选择22行。  


    我们可以看到,从tab$ 开始,存储发生了变化:STORAGE (  OBJNO 4 TABNO 1),那这里的 objno 4 tabno 1 表示什么意思呢?

[sql] view plaincopy
  1. PARSING IN CURSOR #2 len=827 dep=1 uid=0 oct=1 lid=0 tim=18717834472 hv=4071397944 ad='33ebc484'  
  2. CREATE TABLE TAB$("OBJ#" NUMBER NOT NULL,"DATAOBJ#" NUMBER,"TS#" NUMBER NOT NULL,"FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT NULL,"BOBJ#" NUMBER,"TAB#" NUMBER,"COLS" NUMBER NOT NULL,"CLUCOLS" NUMBER,"PCTFREE$" NUMBER NOT NULL,"PCTUSED$" NUMBER NOT NULL,"INITRANS" NUMBER NOT NULL,"MAXTRANS" NUMBER NOT NULL,"FLAGS" NUMBER NOT NULL,"AUDIT$" VARCHAR2(38) NOT NULL,"ROWCNT" NUMBER,"BLKCNT" NUMBER,"EMPCNT" NUMBER,"AVGSPC" NUMBER,"CHNCNT" NUMBER,"AVGRLN" NUMBER,"AVGSPC_FLB" NUMBER,"FLBCNT" NUMBER,"ANALYZETIME" DATE,"SAMPLESIZE" NUMBER,"DEGREE" NUMBER,"INSTANCES" NUMBER,"INTCOLS" NUMBER NOT NULL,"KERNELCOLS" NUMBER NOT NULL,"PROPERTY" NUMBER NOT NULL,"TRIGFLAG" NUMBER,"SPARE1" NUMBER,"SPARE2" NUMBER,"SPARE3" NUMBER,"SPARE4" VARCHAR2(1000),"SPARE5" VARCHAR2(1000),"SPARE6" DATE) STORAGE (  OBJNO 4 TABNO 1) CLUSTER C_OBJ#(OBJ#)  
  3. END OF STMT  
  4. PARSE #2:c=0,e=633,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=18717834468  
  5. EXEC #2:c=0,e=169,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=18717836262  
  6.   
  7. 00:19:42 sys@ORCL (^ω^) select * from tab$ where obj# = 4 and tab# = 1;  
  8.   
  9.       OBJ#   DATAOBJ#        TS#      FILE#     BLOCK#      BOBJ#       TAB#  
  10. ---------- ---------- ---------- ---------- ---------- ---------- ----------  
  11.       COLS    CLUCOLS   PCTFREE$   PCTUSED$   INITRANS   MAXTRANS      FLAGS  
  12. ---------- ---------- ---------- ---------- ---------- ---------- ----------  
  13. AUDIT$  
  14. ----------------------------------------------------------------------------  
  15.     ROWCNT     BLKCNT     EMPCNT     AVGSPC     CHNCNT     AVGRLN AVGSPC_FLB  
  16. ---------- ---------- ---------- ---------- ---------- ---------- ----------  
  17.     FLBCNT ANALYZETIME    SAMPLESIZE     DEGREE  INSTANCES    INTCOLS KERNELCOLS  
  18. ---------- -------------- ---------- ---------- ---------- ---------- ----------  
  19.   PROPERTY   TRIGFLAG     SPARE1     SPARE2     SPARE3  
  20. ---------- ---------- ---------- ---------- ----------  
  21. SPARE4  
  22. --------------------------------------------------------------------------------  
  23. SPARE5  
  24. --------------------------------------------------------------------------------  
  25. SPARE6  
  26. --------------  
  27.          4          2          0          1         25          2          1  
  28.         37          1          0          0          0          0        529  
  29. --------------------------------------  
  30.       1637        862          0          0          0        135          0  
  31.          0 15-9月 -12           1637                               37         37  
  32.       1024          0          0  
  33.   
  34.   
  35. 30-8月 -05  


    由这里可以看出,存储参数从这里开始,就从数据文件中固定表的记录中取出来。

    由此再往trace文件看下去,就会发现这个时候数据库已经可以通过已有信息从系统表空间文件中提取结构信息和数据信息。

   

    由上面内容我们可以看出,程序中只要提供 bootstrap$ 的创建脚本,确定好bootstap$的结构同时指定了段头的位置,然后就能通过段头去获取bootstrap$中的内容,而这些内容就是为一些字典表创建结构的sql_text,这样就因了bootstrap$这个天生的蛋,孵化出了c_obj#,tab$等等鸡,这些鸡又继续生蛋,则完成了数据库字典表结构的建立。所以,bootstrap$是oracle第一表!数据库每次启动的时候先创建bootstrap$来建立字典表本身的结构,然后再根据bootstrap$去获取数据文件的信息。创建 bootstrap$ 是在内存中进行的,不是真实的 物理对象,在内存中创建的对象恰好对应了 物理磁盘上的对象,这是固定位置的。

 

    也就是说,oracle用关系型表来实现了自身结构的建立。

 

    system表空间、sysaux表空间等这些物理对象都是已经真实地存在的,我们所做的“create”仅仅是在 SGA 中 创建这样一个对应的结构,然后好根据表的特征来读取数据,而为了生成 tab$ 等结构,这个结构的  sql 又来自 bootstrap$ ,最开始,oracle只要拥有了 bootstrap$ 的结构信息,在sga中创建了结构,则立即可以去system  tablespace中获取bootstrap$的内容,然后逐步完成sga中字典表结构的建立。去system 表空间读取的bootstrap$内容,这些sql不需要重用,也不需要相关数据字典信息(也不可能有相关的数据字典信息)。任何一种数据结构,其结构的头部总是相对固定的。对于 db来说是在 system 固定位置。

 

    开机流程如下:

        1. 系统启动的时候根据control file的信息, 得到各个数据文件的位置.
        2. 根据file# = 1 (system tablespace的第一个数据文件)的文件头的信息得到root dba的地址(此处为file_id = 1 ,block_id = 417
        3. 根据root dba的信息, 得到bootstrap$对应的segment的存储位置, (此处为file_id = 1, block_id = 377) 得到系统启动的那只母鸡
        4. 根据bootstrap$表中的信息, 得到系统中系统表的创建信息, 完成母鸡生下主要的小鸡的过程..
        5.处理主要表生成之后的进一步处理, 生成主要的数据字典信息, 以及启动相关的undo segment(rollback segments).
        6. 数据库启动完毕

 

    数据库是个逻辑概念,但它是通过磁盘的物理存储实现的,那么在逻辑和物理之间怎么联系起来,那么就需要一个钩子,把二者挂在一起,其实,系统字典等在数据库创建后就存在了,数据库之所以逻辑化,就是为了好理解,好使用,在数据库启动的过程中,就需要把逻辑数据库和物理存储通过钩子挂起来,这就是BOOTSTRAP$,至于它的起始地址,在数据库创建的时候就确定了,我想可能是写在了磁盘的某个地方,不同的数据库可以不同.在OPEN前只所以创建了一些字典表,那是因为那些表并不需要读取表空间或数据文件里的信息,而是从其他地方获取,比如:初始化参数或控制文件,整个启动过程,就是把物理存储抽象成一个逻辑数据库的过程。


    原文地址: http://blog.csdn.net/linwaterbin/article/details/7986097


原创粉丝点击