数据库的初始化
通过sql_trace跟踪启动过程来分析
跟踪数据文件如何到内存初始化过程
startup mount;
select value from v$diag_info;
alter session set sql_trace=true;
alter database open;
查看trc文件,发现首先执行的是创建boostrap$表
实际上oracle在这一步在内存中创建bootstrap$结构,从数据文件中读取数据到内存中,完成第一次初始化
vi /app/oracle/diag/rdbms/bird/BIRD/trace/BIRD_ora_2709.trc
PARSING IN CURSOR #139890881969600 len=19 dep=0 uid=0 oct=35 lid=0 tim=1419988959901073 hv=1907384048 ad='8a8a5bd8' sqlid='a01hp0psv0rrh'
alter database open
END OF STMT
PARSE #139890881969600:c=999,e=642,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=1419988959901071
*** 2014-12-31 09:22:40.947
=====================
PARSING IN CURSOR #139890881953072 len=188 dep=1 uid=0 oct=1 lid=0 tim=1419988960947229 hv=4006182593 ad='8a893890' sqlid='32r4f1brckzq1'
create table bootstrap$ (
END OF STMT
PARSE #139890881953072:c=1000,e=921,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=1419988960947227
EXEC #139890881953072:c=0,e=183,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=0,tim=1419988960947486
CLOSE #139890881953072:c=0,e=5,dep=1,type=0,tim=1419988960947551
=====================
PARSING IN CURSOR #139890881953072 len=55 dep=1 uid=0 oct=3 lid=0 tim=1419988960947948 hv=2111436465 ad='8a891f30' sqlid='6apq2rjyxmxpj'
select line#, sql_text from bootstrap$ where obj# != :1
END OF STMT
PARSE #139890881953072:c=0,e=375,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=1419988960947946
EXEC #139890881953072:c=0,e=538,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=867914364,tim=1419988960948589
FETCH #139890881953072:c=0,e=277,p=4,cr=3,cu=0,mis=0,r=1,dep=1,og=4,plh=867914364,tim=1419988960948900
FETCH #139890881953072:c=0,e=14,p=0,cr=1,cu=0,mis=0,r=1,dep=1,og=4,plh=867914364,tim=1419988960948948
FETCH #139890881953072:c=0,e=8,p=0,cr=1,cu=0,mis=0,r=1,dep=1,og=4,plh=867914364,tim=1419988960948977
FETCH #139890881953072:c=0,e=7,p=0,cr=1,cu=0,mis=0,r=1,dep=1,og=4,plh=867914364,tim=1419988960949004
格式化trc文件,查看
********************************************************************************
SQL ID: a01hp0psv0rrh Plan Hash: 0
alter database open
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.17 1.31 19 37 59 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.17 1.31 19 37 59 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
********************************************************************************
SQL ID: 32r4f1brckzq1 Plan Hash: 0
create table bootstrap$ (
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 0 0 0
Misses in library cache during parse: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 1)
********************************************************************************
SQL ID: 6apq2rjyxmxpj Plan Hash: 867914364
select line#, sql_text
from
bootstrap$ where obj# != :1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 60 0.00 0.00 4 61 0 59
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 62 0.00 0.00 4 61 0 59
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 1)
Number of plan statistics captured: 1
通过数据库的创建脚本sql.bsq的文件中,可以查看在create database过程中执行的脚本,从而也可以找出bootstrap$的创建过程
cd $ORACLE_HOME/rdbms/admin
cat sql.bsq
rem Whenever new column is created to store internal, user or kernel column
rem number, be sure to update the structure adtDT in atb.c so that those
rem columns will be updated properly during drop column.
rem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
rem
dcore.bsq
dsqlddl.bsq
dmanage.bsq
dplsql.bsq
dtxnspc.bsq
dfmap.bsq
denv.bsq
drac.bsq
dsec.bsq
doptim.bsq
dobj.bsq
djava.bsq
dpart.bsq
drep.bsq
daw.bsq
dsummgt.bsq
dtools.bsq
dexttab.bsq
ddm.bsq
dlmnr.bsq
ddst.bsq
从脚本内容看,先执行了dcore.bsq,然后执行了dsqlddl.bsq
查看dcore.bsq,找到bootstap$的创建过程
vi dcore.bsq
[oracle@oracle01 admin]$ vi dcore.bsq
/........ --省略了一些创建索引的信息
create index i_cdef4 on cdef$(enabled)
/
create index i_ccol1 on ccol$(con#, col#)
/
create unique index i_ccol2 on ccol$(con#, intcol#)
- /
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 */
可以看到,先创建了一些索引,然后看到bootstrap$的创建过程了,要详细研究数据库的启动过程,则可以分别分析上述的脚本
通过启动的trc文件,当create table bootstrap$之后,可以看出执行了select line#, sql_text from bootstrap$ where obj# != :1
在创建并从数据文件中读取bootstrap$视图的数据之后,oracle开始递归的从该表中读取信息,加载数据
查看bootstrap$表的内容
SQL> desc bootstrap$
Name Null? Type
----------------------------------------- -------- ----------------------------
LINE# NOT NULL NUMBER
OBJ# NOT NULL NUMBER
SQL_TEXT NOT NULL VARCHAR2(4000)
select * from bootstrap$; --可以看到,当中存放了一些sql语句,在数据库启动的过程中,递归的执行这些语句。
bootstrap$表中实际上记录的是一些数据库系统的基本对象的创建语句。oracle通过bootstrap$的引导,进一步创建相关的数据库对象,从而启动数据库。
在create database的过程中,其实是隐含调用了$ORACLE_HOME/rdbms/admin/sql.bsq的脚本,用于创建相关的数据字典。这个文件的位置由一个隐含参数 _init_sql_file 来控制的。
在创建数据库的过程中,若oracle无法找到sql.bsq文件,则数据库的创建将会报错的。
bootstrap$的定位
数据库的引导过程中定位bootstrap$的方式
system表空间和root dba
SYSTEM表空间是数据库最重要的表空间,其中包含了数据库的元数据,永远不能被offline。
如果system出现故障,则需要介质恢复。
在数据库的启动过程中,oracle也需要system表空间的引导
在system表空间的文件头上存储了一个结构root dba, root dba仅在system表空间中存在,用于定位数据库的bootstrap$信息。
通过转储数据文件头分析
alter session set events 'immediate trace name file_hdrs level 10';
Foreign creation scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
Foreign checkpoint scn/timescn: 0x0000.00000000 01/01/1988 00:00:00
Online move state: 0
V10 STYLE FILE HEADER:
Compatibility Vsn = 186647552=0xb200400
Db ID=2435714078=0x912e0c1e, Db Name='BIRD'
Activation ID=0=0x0
Control Seq=31345=0x7a71, File size=97280=0x17c00
File Number=1, Blksiz=8192, File Type=3 DATA
Tablespace #0 - SYSTEM rel_fn:1
Creation at scn: 0x0000.00000007 08/24/2013 11:37:33
Backup taken at scn: 0x0000.002f978d 12/29/2014 13:17:47 thread:1
reset logs count:0x337a194b scn: 0x0000.00142c38
prev reset logs count:0x336f8d1e scn: 0x0000.000e2006
recovered at 12/30/2014 13:58:45
status:0x2004 root dba:0x00400208 chkpt cnt: 283 ctl cnt:282
begin-hot-backup file size: 97280
Checkpointed at scn: 0x0000.003111ef 12/31/2014 09:22:40
thread:1 rba:(0x7b.169d.10)
root dba仅在system表空间文件头中存在,用于定位数据库引导的bootstrap$信息。root dba存储的是用十六进制表示的二进制数,其中包含10位的文件号和22位的数据块号,将root dba:0x00400208 转换为二进制
SQL> variable file# number;
SQL> exec :file# := dbms_utility.data_block_address_file(to_number('400208','xxxxxxx'));
PL/SQL procedure successfully completed.
SQL> variable block# number;
SQL> exec :block# := dbms_utility.data_block_address_block(to_number('400208','xxxxxxx'));
PL/SQL procedure successfully completed.
SQL> print file#
FILE#
----------
1
SQL> print block#
BLOCK#
----------
520
则可以分析 root dba结构 存在于1号数据文件的第520个block上。
查看1号数据文件的block 520的存放的内容
SQL> col owner for a4
SQL> col segment_name for a15
SQL> col segment_type for a6
SQL> col tablespace_name for a10
select t.owner,
t.segment_name,
t.segment_type,
t.tablespace_name
--t.header_file
--t.header_block
--t.bytes,
--t.blocks
from dba_segments t
where t.header_block = 520
and t.header_file = 1;
OWNE SEGMENT_NAME SEGMEN TABLESPACE
---- --------------- ------ ----------
SYS BOOTSTRAP$ TABLE SYSTEM
可以看到在file# 1 ,block# 520上存放的正好是bootstrap$的表
系统对象和bootstrap$
系统对象的移动和变更会导致问题,面而bootstrap$表中记录的系统对象的移动和变更会导致数据库不能启动,非常危险
bootstrap@内数据库启动依赖的对象是不能被修改或变更的,另外在启动过程中Recursive SQL所依赖的对象也是不能被修改和变更的。
注明:本文参照网络技术大拿(链接忘记了)相关步骤,自已测试实验步骤,如涉侵权,请联系博主删除。