oracle实验--通过gdb工具研究数据库启动过程

概述

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

oracle实验--通过gdb工具研究数据库启动过程


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));

oracle实验--通过gdb工具研究数据库启动过程

这里注意窗口不要关闭。

2、通过gdb跟踪这个进程

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

oracle实验--通过gdb工具研究数据库启动过程

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

alter database open;

oracle实验--通过gdb工具研究数据库启动过程

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

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

no rows selected

oracle实验--通过gdb工具研究数据库启动过程

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方面的内容,感兴趣的朋友可以关注下!!

oracle实验--通过gdb工具研究数据库启动过程

相关推荐