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