用vs读取oracle数据库数据(oracle实验--通过gdb工具研究数据库启动过程)

概述

分享下之前做的一个小实验,通过gdb工具来研究下oracle数据库启动过程。

用vs读取oracle数据库数据(oracle实验--通过gdb工具研究数据库启动过程)(1)


1、启动数据库到mount状态并获取进程spid

startup mount; select spid from v$process where addr in (select paddr from v$session where sid=(select distinct sid from v$mystat));

用vs读取oracle数据库数据(oracle实验--通过gdb工具研究数据库启动过程)(2)

这里注意窗口不要关闭。

2、通过gdb跟踪这个进程

$ gdb $ORACLE_HOME/bin/oracle 3135 #跟踪两个内部指令 (gdb) break kcrf_commit_force (gdb) break kqlobjlod

用vs读取oracle数据库数据(oracle实验--通过gdb工具研究数据库启动过程)(3)

3、此时执行数据库open操作会被挂起

alter database open;

用vs读取oracle数据库数据(oracle实验--通过gdb工具研究数据库启动过程)(4)

4、重开一个sqlplus进程,查询此时数据库加载的rowcache对象

SQL> select parameter,count,gets from v$rowcache where count!=0;

no rows selected

用vs读取oracle数据库数据(oracle实验--通过gdb工具研究数据库启动过程)(5)

5、继续执行,在第三个步骤后,数据库加载了一个rowcache对象

(gdb) c Continuing. Breakpoint 1, 0x00000000096cf564 in kcrf_commit_force () (gdb) c Continuing. Breakpoint 1, 0x00000000096cf564 in kcrf_commit_force () (gdb) c Continuing. Breakpoint 2, 0x0000000001c4995e in kqlobjlod () SQL> select parameter,count,gets from v$rowcache where count!=0; PARAMETER COUNT GETS -------------------------------- ---------- ---------- dc_objects 1 1

6、这个rowcache对象是什么呢?

SQL> select address,cache_name,existent,lock_mode,saddr,substr(key,1,40) keystr from v$rowcache_parent;

解析其key值,正是bootstrap$,这就是数据库初始化时加载的第一个对象

SQL> select dump(BOOTSTRAP$,16) from dual; DUMP(BOOTSTRAP$,16) -------------------------------------------- Typ=96 Len=10: 42,4f,4f,54,53,54,52,41,50,24

7、数据库递归查询bootstrap$对象中的数据,向内存加载其他对象。

(gdb) c Continuing. Breakpoint 2, 0x00000001006c78b4 in kqlobjlod () address CACHE_NAME E LOCK_MODE SADDR KEYSTR ---------------- ----------------------- ---------------------------------------- 00000001942E30D8 dc_tablespaces N 0 00 0000000000000000000000000000000000000000 00000001942DE9B8 dc_rollback_segments Y 0 00 0000000000000000000000000000000000000000 00000001942E9080 dc_objects Y 0 00 000000000A00424F4F5453545241502400000000 00000001942DE2D0 dc_objects N 3 0000000194782EB0 000000000600435F4F424A230000000000000000 00000001942E3340 dc_object_ids Y 0 00 3800000000000000000000000000000000000000

这里可以看到数据库加载了回滚段信息,首先加载的是system的回滚段,转储row cache信息之后,就可以看到这些详细内容

ALTER SESSION SET EVENTS immediate trace name row_cache level 10;

这里得到的bucket 37包含了回滚段信息

BUCKET 37: row cache parent object: address=0x1942de9b8 cid=3(dc_rollback_segments) hash=5fed2a24 typ=9 transaction=0x0 flags=000000a6 own=0x1942dea88[0x1942dea88,0x1942dea88] wat=0x1942dea98[0x1942dea98,0x1942dea98] mode=N status=VALID/INSERT/-/FIXED/-/-/-/-/- data= 00000000 00000000 00000001 00000009 59530006 4d455453 00000000 00000000 00000000 00000000 00000000 00000000 00000003 00000000 00000000 00000000 00000000 00000000 00000000 00000000 BUCKET 37 total object count=1 ROW CACHE HASH TABLE: cid=4 ht=0x192b2e8a8 size=256 其中 53595354454d 正是system回滚段 SQL> select dump(SYSTEM,16) from dual; DUMP(SYSTEM,16) ------------------------------- Typ=96 Len=6: 53,59,53,54,45,4d

另一个bucket正是bootstrap$对象

BUCKET 43170: row cache parent object: address=0x1942e9080 cid=8(dc_objects) hash=f3d1a8a1 typ=11 transaction=0x0 flags=000000a6 own=0x1942e9150[0x1942e9150,0x1942e9150] wat=0x1942e9160[0x1942e9160,0x1942e9160] mode=N status=VALID/INSERT/-/FIXED/-/-/-/-/- set=0, complete=TRUE data= 00000000 4f42000a 5453544f 24504152 00000000 00000000 00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000038 00000001 00000038 066f7802 030d1411 11066f78 78030d14 1411066f 0001030d 00000000 00000000 00000000 00000000 00000000 00000000 BUCKET 43170 total object count=1


总结:

以上是用gdb跟踪数据库启动时bootstrap$的加载与引导过程,从上面我们可以知道bootstrap$的重要性,如果bootstrap$发生损坏,数据库将无法启动。大家有空也可以测试一下。

后面会分享更多DBA方面的内容,感兴趣的朋友可以关注下!!

用vs读取oracle数据库数据(oracle实验--通过gdb工具研究数据库启动过程)(6)

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。