bootstrap$ is the most core table for database. It contains defination for oracle most critical dictinary tables such as: obj$, tab$, ts$ etc.
During an startup, oracle will read bootstrap$ to build dictionary for whole DB.
Any modification on bootstrap$ may destroy your database, and oracle support won't help anything on that.
Below is bootstrap$ structure and one row in it:
SYS @ geded > select count(*) from bootstrap$;
COUNT(*)
----------
60
SYS @ geded > select * from bootstrap$ where line#=18;
LINE# OBJ#
---------- ----------
SQL_TEXT
-------------------------------------------------------------------------------------
18 18
CREATE TABLE OBJ$("OBJ#" NUMBER NOT NULL,"DATAOBJ#" NUMBER,"OWNER#" NUMBER NOT NULL,"NAME" VARCHAR2(30) NOT NULL,"NAMESPACE" NUMBER NOT NULL,"SUBNAME" VARCHAR2(30),"TYPE#" NUMBER NOT NULL,"C
TIME" DATE NOT NULL,"MTIME" DATE NOT NULL,"STIME" DATE NOT NULL,"STATUS" NUMBER NOT NULL,"REMOTEOWNER" VARCHAR2(30),"LINKNAME" VARCHAR2(128),"FLAGS" NUMBER,"OID$" RAW(16),"SPARE1" NUMBER,"SP
ARE2" NUMBER,"SPARE3" NUMBER,"SPARE4" VARCHAR2(1000),"SPARE5" VARCHAR2(1000),"SPARE6" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE ( INITIAL 16K NEXT 104K MINEXTENTS 1 MAXEXT
ENTS 2147483645 PCTINCREASE 0 OBJNO 18 EXTENTS (FILE 1 BLOCK 240))
SYS @ geded > desc bootstrap$;
Name Null? Type
-------------- ---------- ---------------
LINE# NOT NULL NUMBER
OBJ# NOT NULL NUMBER
SQL_TEXT NOT NULL VARCHAR2(4000)
Below is one possible error for bootstrap$ failure during startup:
ORA-01092: ORACLE instance terminated. Disconnection forced ORA-00704: bootstrap process failure.
Today, let's hack the bootstrap$, even replace it with our own table:
Kevin.Zhang > select count(*) from bootstrap$;
COUNT(*)
----------
60
Kevin.Zhang > shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
Kevin.Zhang > startup upgrade;
ORACLE instance started.
Total System Global Area 730714112 bytes
Fixed Size 2230080 bytes
Variable Size 318769344 bytes
Database Buffers 322961408 bytes
Redo Buffers 86753280 bytes
Database mounted.
Database opened.
Kevin.Zhang > create table KILLBOOT as select * from bootstrap$;
Table created.
Kevin.Zhang > delete from KILLBOOT where LINE#=59;
1 row deleted.
Kevin.Zhang > commit;
Commit complete.
Kevin.Zhang > delete from bootstrap$;
60 rows deleted.
Kevin.Zhang > commit;
Commit complete.
Here we use an internal package DBMS_DDL_INTERNAL.SWAP_BOOTSTRAP to swap bootstrap$ to our new table KILLBOOT.
Infact package DBMS_DDL_INTERNAL.SWAP_BOOTSTRAP only do one thing, to update kcvfhrdb in super block(file 1 block 1):
Kevin.Zhang > exec DBMS_DDL_INTERNAL.SWAP_BOOTSTRAP('KILLBOOT');
PL/SQL procedure successfully completed.
Kevin.Zhang > update obj$ set name='BOOTSTRAP_DEL' where name='BOOTSTRAP$';
1 row updated.
Kevin.Zhang > commit;
Commit complete.
Kevin.Zhang > shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
Kevin.Zhang > startup;
ORACLE instance started.
Total System Global Area 730714112 bytes
Fixed Size 2230080 bytes
Variable Size 318769344 bytes
Database Buffers 322961408 bytes
Redo Buffers 86753280 bytes
Database mounted.
Database opened.
Kevin.Zhang > select count(*) from bootstrap$;
COUNT(*)
----------
59
Kevin.Zhang > select count(*) from bootstrap_del;
COUNT(*)
----------
0
Kevin.Zhang > select count(*) from KILLBOOT;
COUNT(*)
----------
59
We are done, let's prove that we have already succeeded in replacing bootstrap$ with our new table KILLBOOT:
Kevin.Zhang > select dbms_rowid.rowid_relative_fno(rowid) file_id,dbms_rowid.rowid_block_number(rowid) block_id from bootstrap$ where rownum<10;
FILE_ID BLOCK_ID
---------- ----------
1 60817
1 60817
1 60817
1 60817
1 60817
1 60817
1 60817
1 60817
1 60817
9 rows selected.
From the block_id we can clearly identify since this block belong to KILLBOOT table.
0 Comments:
Post a Comment