DSI 401 读书笔记

http://www.oracleblog.org/study-note/dsi-401-study-notes/

最近重拾了DSI 401,根据章节,大致做个笔记吧,以备后续的翻看。由于是断断续续的看的,所以下面的笔记的思路可能会有些跳跃。

第一、二章的dump,crash,corruption主要介绍的是数据库hang住,loop,还有crash的一些诊断。
loop和hang最大的区别就是loop消耗cpu,你可能会看到cpu使用率100%的情况,而hang的情况你会看到数据库基本没有压力。我个人觉得latch属于loop的情况,会不断的sleep/wake up,而且出现latch的时候,往往cpu中的user%部分会比较高。而hang的情况往往是数据库中的dml锁,前一个session的执行完成之后锁没释放,后一个session就只能等在那里了。
进行故障诊断的时候,我们可以查alertlog,trace file,application的log,coredump,syslog等等。
其中一个很重要的工具是oradebug hanganalyze,一般使用level 3进行分析。注意LEAF和LEAF_NW的节点。
dump systemstates可以用ass.awk来辅助分析trace文件。
下面是systemstates的tracefile中的几个解释:
通常情况下,一个process下是一个session,一个session开一个transaction。如果一个process下有多个session,一般是shared server模式或者OCI应用等等。因此在trace file中大致看到的也是这样的结构。最外层的时候process SO(SO:states objects,是SGA中的结构),里面是session的信息,再里面一层是transaction信息。
来看一个systemstate dump:
先看一个process states objects:

  1. PROCESS 17:
  2.   ----------------------------------------
  3.   SO: 700000025e5ef20, type: 2, owner: 0, flag: INIT/-/-/0x00
  4.   (process) Oracle pid=17, calls cur/top: 70000002267efb0/700000025f9edc0, flag: (0) -
  5.             int error: 0, call error: 0, sess error: 0, txn error 0
  6.   (post info) last post received: 0 0 0
  7.               last post received-location: No post
  8.               last process to post me: none
  9.               last post sent: 0 0 24
  10.               last post sent-location: ksasnd
  11.               last process posted by me: 700000025e59880 1 6
  12.     (latch info) wait_event=0 bits=20
  13.       holding    (efd=33) 7000000239479a0 Child library cache level=5 child#=3
  14.         Location from where latch is held: kglLockCursor:
  15.         Context saved from call: 2
  16.         state=busy, wlstate=free
  17.           waiters [orapid (seconds since: put on list, posted, alive check)]:
  18.            15 (4311, 1304283076, 3)
  19.            26 (4293, 1304283076, 3)
  20.            16 (4263, 1304283076, 3)
  21.            8 (4179, 1304283076, 3)
  22.            18 (3153, 1304283076, 3)
  23.            25 (3019, 1304283076, 3)
  24.            28 (2811, 1304283076, 3)
  25.            29 (1770, 1304283076, 3)
  26.            30 (1770, 1304283076, 3)
  27.            31 (390, 1304283076, 3)
  28.            32 (390, 1304283076, 3)
  29.            waiter count=11
  30.     Process Group: DEFAULT, pseudo proc: 700000025ea17a8
  31.     O/S info: user: oracle1, term: UNKNOWN, ospid: 2592926
  32.     OSD pid info: Unix process pid: 2592926, image: oracle@sg2as059 (J000)
  33. ......

上述第3行SO: 700000025e5ef20 表示state object ID为700000025e5ef20 ,
第4行表示该Oracle pid为17
第5行表示是否有相关的ora-nnnn的报错。
第6~11行显示inter-process的信息。
第12行,latch信息
第31~32行os的一些信息.

再看一个session states objects:

  1. SO: 700000025f61ca0, type: 4, owner: 700000025e63de0, flag: INIT/-/-/0x00
  2.     (session) sid: 143 trans: 0, creator: 700000025e63de0, flag: (51) USR/- BSY/-/-/-/-/-
  3.               DID: 0000-0000-00000000, short-term DID: 0000-0000-00000000
  4.               txn branch: 0
  5.               oct: 0, prv: 0, sql: 0, psql: 0, user: 0/SYS
  6.     waiting for 'Streams AQ: qmn slave idle wait' blocking sess=0x0 seq=1 wait_time=0 seconds since wait started=4329
  7.                 =0, =0, =0
  8.     Dumping Session Wait History
  9.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=15874499
  10.                 =0, =0, =0
  11.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=27343911
  12.                 =0, =0, =0
  13.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=27343900
  14.                 =0, =0, =0
  15.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=27343909
  16.                 =0, =0, =0
  17.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=27343900
  18.                 =0, =0, =0
  19.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=27343886
  20.                 =0, =0, =0
  21.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=27343897
  22.                 =0, =0, =0
  23.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=27343896
  24.                 =0, =0, =0
  25.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=27343929
  26.                 =0, =0, =0
  27.      for 'Streams AQ: qmn slave idle wait' count=1 wait_time=27343921
  28.                 =0, =0, =0
  29.     temporary object counter: 0
  30. ......

第1行:states objects id和owner
第2行:session的sid,已经一些flag信息,如:
USR表示是user session
BSY表示session is busy, it is in a call
DED表示session mark dead by user process
DEL表示session being delete(通过alter system kill session)
KIL表示session mark kill (通过alter system kill session)
第3行:resource id(DID)的一些信息。
第4行:事务的关系分支。
第5行:oct(oracle command tye),和prv(user privilege),和oracle user,这里显示是SYS。
第6行:session的等待事件。

另外查看hang或者loop的等待的时候,对于buffer热块,可以查x$kcbfwait;对于enqueue可以查x$ksqst。

第三章,memeory management和heap corruption。
oracle的内存分为heap-extents-chunks。
连续的extents组成heap,各种类型的chunks组成extents,类型分别有free,permanent,re-creatable等等。如果一个extents是从另一个heap延伸过来的,那么从延伸过来的那个heap叫父heap,当前的heap叫子heap。
当用户向heap申请free的chunk的时候,发现没有多余的space可供使用时,heap manager会去LRU中找unpinned(即re-createable)的chunks,使其释放。

一个granule最小为4M,而sga最小包含一个fix(含redo buffer),一个buffer cache,一个shared pool,所以一个sga最小为12M。

ora-600是heap中的一致性检验失败触发的。此外bug和存储损坏也会触发ora-600。
ora-7445一般是内存指针指向失败造成,比如指向内存越界的区域。此外,代码bug和内存地址计算错误也会触发ora-7445。

dump memory:
alter session|system set events ‘trace name heapdump|heapdump_addr|buffers|row_cache|library_cache level n;
或者
oradeug dump heapdump|heapdump_addr|buffers|row_cache|library_cache n;
其中上述的n,如果为1代表dump PGA,2为SGA,3为UGA,32为large pool。

heapdump能dump出:(1)内存描述符。(2)extents和chunks。(3)LRU,free list,permanent chunks等等。
heapdump_addr能dump出子heap,n为子heap的address。

查heap中的各项chunk信息,可以查x$ksmhp, 如果是sga中的信息,可以查x$ksmsp;如果是pga,可以查 x$ksmpp,如果是uga,可查x$ksmup;

第四章,data block dump.

data block分成3层结构:
cache layer
transaction layer
data layer(含footer)

rowid:格式,6363,oooooofffbbbbbbsss
常用:
dbms_rowid.ROWID_BLOCK_NUMBER
dbms_rowid.ROWID_CREATE
dbms_rowid.ROWID_RELATIVE_FNO

如何dump block:
1)用dd

E:\ora8i\oracle\oradata\ora8i>dd bs=8192 if=USERS01.DBF count=1 |od -xv >111.txt
1+0 records in
1+0 records out
 
E:\ora8i\oracle\oradata\ora8i>
E:\ora8i\oracle\oradata\ora8i>
E:\ora8i\oracle\oradata\ora8i>cat 111.txt
0000000000      0000    0000    1000    0000    6C00    0000    6C6D    6A6B
0000000020      0000    0000    0000    0000    0000    0000    0000    0000
……
0000007640      0000    0000    0000    0000    0000    0000    0000    0000
0000007660      0000    0000    0000    0000    0000    0000    0000    0000
0000007700      0000    0000    0000    0000    0000    0000    0000    0000
0000007720      0000    0000    0000    0000    0000    0000    0000    0000
0000007740      0000    0000    0000    0000    0000    0000    0000    0000
0000007760      0000    0000    0000    0000    0000    0000    0000    0000
0000010000      020B    0000    0001    00C0    0000    0000    0000    0401
0000010020      88C9    0000    5000    0800    0000    0800    EED9    0A46
0000010040      524F    3841    0049    0000    02C9    0000    6C00    0000
0000010060      1000    0000    0003    0003    0000    0000    0000    0000
0000010100      0000    0000    0000    0000    0000    0000    0000    0000
0000010120      0000    0000    0000    0000    0000    0000    0000    0000
0000010140      0000    0000    144B    0000    0000    0000    8136    2CBD
0000010160      8119    2CBD    0001    0000    0000    0000    0000    0000
0000010200      0000    0000    0000    0000    0000    0004    30FB    0002
……
0000017260      0000    0000    0000    0000    0000    0000    0000    0000
0000017300      0000    0000    0000    0000    0000    0000    0000    0000
0000017320      0000    0000    0000    0000    0000    0000    0000    0000
0000017340      0000    0000    0000    0000    0000    0000    0000    0000
0000017360      0000    0000    0000    0000    0000    0000    0000    0000
0000017400      0000    0000    0000    0000    0000    0000    0000    0000
0000017420      0000    0000    0000    0000    0000    0000    0000    0000
0000017440      0000    0000    0000    0000    0000    0000    0000    0000
0000017460      0000    0000    0000    0000    0000    0000    0000    0000
0000017500      0000    0000    0000    0000    0000    0000    0000    0000
0000017520      0000    0000    0000    0000    0000    0000    0000    0000
0000017540      0000    0000    0000    0000    0000    0000    0000    0000
0000017560      0000    0000    0000    0000    0000    0000    0000    0000
0000017600      0000    0000    0000    0000    0000    0000    0000    0000
0000017620      0000    0000    0000    0000    0000    0000    0000    0000
0000017640      0000    0000    0000    0000    0000    0000    0000    0000
0000017660      0000    0000    0000    0000    0000    0000    0000    0000
0000017700      0000    0000    0000    0000    0000    0000    0000    0000
0000017720      0000    0000    0000    0000    0000    0000    0000    0000
0000017740      0000    0000    0000    0000    0000    0000    0000    0000
0000017760      0000    0000    0000    0000    0000    0000    0B01    0000
0000020000
 
E:\ora8i\oracle\oradata\ora8i>

dd出来的block的格式:2248842244,2位type+2位format+4位为将来用+8位RDBA+8位scn base+4位scn wrap+2位seq+2位flag+4位chkval+4位将来用。
tail为scn base的后2位+type+seq

2) 用alter system dump datafile xx block xx;

Dump file E:\ora8i\oracle\admin\ora8i\udump\ORA07680.TRC
Wed Jul 06 22:11:51 2011
ORACLE V8.1.7.0.0 - Production vsnsta=0
vsnsql=e vsnxtr=3
Windows 2000 Version 5.1 Service Pack 3, CPU type 586
Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
With the Partitioning option
JServer Release 8.1.7.0.0 - Production
Windows 2000 Version 5.1 Service Pack 3, CPU type 586
Instance name: ora8i
 
Redo thread mounted by this instance: 1
 
Oracle process number: 9
 
Windows thread id: 7680, image: ORACLE.EXE
 
 
*** SESSION ID:(8.45) 2011-07-06 22:11:51.839
Start dump data blocks tsn: 2 file#: 3 minblk 35 maxblk 35
buffer tsn: 2 rdba: 0x00c00023 (3/35)
scn: 0x0000.00027f7e seq: 0x02 flg: 0x00 tail: 0x7f7e0602
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
 
Block header dump:  0x00c00023
 Object id on Block? Y
 seg/obj: 0xc78  csc: 0x00.27f7d  itc: 1  flg: -  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   xid:  0x0002.00e.00000073    uba: 0x00000000.0000.00  ----    0  fsc 0x0000.00000000
 
data_block_dump
===============
tsiz: 0xfb8
hsiz: 0x14
pbl: 0x0abc6c44
bdba: 0x00c00023
flag=-----------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0xf8a
avsp=0xf76
tosp=0xf76
0xe:pti[0]    nrow=1    offs=0
0x12:pri[0]    offs=0xf8a
block_row_dump:
tab 0, row 0, @0xf8a
tl: 46 fb: --H-FL-- lb: 0x0 cc: 9
col  0: [ 3]  53 59 53
col  1: [ 1]  80
col  2: [ 4]  4f 50 45 4e
col  3: *NULL*
col  4: *NULL*
col  5: [ 6]  53 59 53 54 45 4d
col  6: [ 4]  54 45 4d 50
col  7: [ 7]  78 6f 05 08 11 2a 09
col  8: [ 9]  53 59 53 5f 47 52 4f 55 50
end_of_block_dump
End dump data blocks tsn: 2 file#: 3 minblk 35 maxblk 35

注意data这部分可以通过asc转十六进制来翻译:
col 0: [ 3] 53 59 53
即为: S Y S
col 1: [ 1] 80
即为: €
col 2: [ 4] 4f 50 45 4e
即为: O P E N
col 3: *NULL*
col 4: *NULL*
col 5: [ 6] 53 59 53 54 45 4d
即为: S Y S T E M
col 6: [ 4] 54 45 4d 50
即为 T E M P

ora-600逻辑坏块,如块的scn base,seq以及tpye和footer不一致。
ora-1578,物理坏块。

注意dbv只能用在datafile上,不能用在redolog上。

flash freeze,可以通过event事件驱动,freeze之后,所有的状态都被冻结。

exp不会涉及上高水位之上的数据块,不会检查index和temporary的对象。

一个很有用的event:10231,在fts的时候,skip corrupt块,可用于设置之后的exp导出。再重建table,在导入。

block修复利器:bbed
set/dump/f/x/modify/sum apply/p/verify

第五章,index block dump
index block也是三层结构:
cache & tnx layer,即block header;注意,在这一层里含ITL信息。
branch & leaf,即common header;
row piece info

我们现在来dump一个索引块看看。
1.通过treedump来看索引的树状结构:

--先查找object id:
sys@ORA8I(127.0.0.1)> select data_object_id,object_id from dba_objects where object_name='IDX_T1';
 
DATA_OBJECT_ID  OBJECT_ID
-------------- ----------
          3193       3193
 
已用时间:  00: 00: 00.25
 
--根据object id 进行treedump
sys@ORA8I(127.0.0.1)> alter session set events 'immediate trace name treedump level 3193';
 
会话已更改。
 
已用时间:  00: 00: 00.50
sys@ORA8I(127.0.0.1)> exit

以下是dump文件:

Dump file E:\ora8i\oracle\admin\ora8i\udump\ORA01852.TRC
Fri Jul 08 22:22:18 2011
ORACLE V8.1.7.0.0 - Production vsnsta=0
vsnsql=e vsnxtr=3
Windows 2000 Version 5.1 Service Pack 3, CPU type 586
Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
With the Partitioning option
JServer Release 8.1.7.0.0 - Production
Windows 2000 Version 5.1 Service Pack 3, CPU type 586
Instance name: ora8i
 
Redo thread mounted by this instance: 1
 
Oracle process number: 9
 
Windows thread id: 1852, image: ORACLE.EXE
 
 
*** 2011-07-08 22:22:18.973
*** SESSION ID:(8.167) 2011-07-08 22:22:18.910
----- begin tree dump
leaf: 0x40357e 4207998 (0: nrow: 1 rrow: 1)
Leaf block dump
===============
header address 1544966236=0x5c16505c
kdxcolev 0
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 1
kdxcofbo 38=0x26
kdxcofeo 3929=0xf59
kdxcoavs 3891
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 3940
row#0[3929] flag: -----, lock: 0
col 0; len 1; (1):  80
col 1; len 6; (6):  00 c0 00 23 00 00
----- end of leaf block dump -----
----- end tree dump

我们看到该索引只有一个节点,只有一层。leaf block即为branch block,该地址用十六进制是0x40357e,如果是十进制是4207998。
kdxcoopc 0×80表示oracle8i以上的block,如果是70表示是oracle7的block,10表示IOT表的block,20表示键值压缩;
kdxcolev 0表示leaf的level,0表示是叶子。
kdxlenxt 表示next leaf block的地址。
kdxleprv 表示上一个leaf block的地址。
kdxledsz 0 如果是0表示非唯一索引,如果是非0表示唯一索引。

另外我们还可以用dump datafile block的方式dump出来:

sys@ORA8I(127.0.0.1)> SELECT DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(4207998),
  2  DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(4207998)
  3  FROM dual;
--注意我们这里使用的4207998是我们之前dump出来leaf block的十进制地址。
 
DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(4207998) DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(4207998)
--------------------------------------------- ----------------------------------------------
                                            1                                          13694
 
已用时间:  00: 00: 00.32
sys@ORA8I(127.0.0.1)>
 
--其实我们还可以根据dba的格式来转换也行:
--4207998=>转换成二进制
--10000000011010101111110=>前面补零成32位
--00000000010000000011010101111110=>分割成前10位和后22位
--0000000001.0000000011010101111110=>前十位是file id,后22是block id
--1.13694
--同样可得file id是1,block id是13694。
 
sys@ORA8I(127.0.0.1)> alter system dump datafile 1 block 13694;
 
系统已更改。
 
已用时间:  00: 00: 00.56
sys@ORA8I(127.0.0.1)> exit
Dump file E:\ora8i\oracle\admin\ora8i\udump\ORA09916.TRC
Fri Jul 08 22:33:15 2011
ORACLE V8.1.7.0.0 - Production vsnsta=0
vsnsql=e vsnxtr=3
Windows 2000 Version 5.1 Service Pack 3, CPU type 586
Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
With the Partitioning option
JServer Release 8.1.7.0.0 - Production
Windows 2000 Version 5.1 Service Pack 3, CPU type 586
Instance name: ora8i
 
Redo thread mounted by this instance: 1
 
Oracle process number: 9
 
Windows thread id: 9916, image: ORACLE.EXE
 
 
*** 2011-07-08 22:33:15.156
*** SESSION ID:(8.170) 2011-07-08 22:33:15.094
Start dump data blocks tsn: 0 file#: 1 minblk 13694 maxblk 13694
buffer tsn: 0 rdba: 0x0040357e (1/13694)
scn: 0x0000.00027f91 seq: 0x01 flg: 0x04 tail: 0x7f910601
frmt: 0x02 chkval: 0xa0c9 type: 0x06=trans data
 
Block header dump:  0x0040357e
 Object id on Block? Y
 seg/obj: 0xc79  csc: 0x00.27f8f  itc: 2  flg: -  typ: 2 - INDEX
     fsl: 0  fnx: 0x0 ver: 0x01
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   xid:  0x0000.000.00000000    uba: 0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x02   xid:  0x0001.01a.0000006e    uba: 0x00000000.0000.00  ----    0  fsc 0x0000.00000000
 
Leaf block dump
===============
header address 180120668=0xabc6c5c
kdxcolev 0
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 1
kdxcofbo 38=0x26
kdxcofeo 3929=0xf59
kdxcoavs 3891
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 3940
row#0[3929] flag: -----, lock: 0
col 0; len 1; (1):  80
col 1; len 6; (6):  00 c0 00 23 00 00
----- end of leaf block dump -----
End dump data blocks tsn: 0 file#: 1 minblk 13694 maxblk 13694

我也可以看到了类似的leaf block的信息,我们还看到了leaf block有2个ITL。

event 10233能在索引进行rang scan操作时,skip掉逻辑损坏的索引块。

第六章,rollback segment corruption
说起事务,transaction,它的发生关系到2种segment,data segment和rollback segment。
data segment中有ITL和data row(注,ITL是在进行DML的那个data row的同一个数据块中),rollback segment头上有txn table(注,txn table中包含指向undo record的指针),后面有undo record(即原数据的镜像)。
txn id的组成为usn.tnx slot id+scn wrap

当data segment发生变化的时候,rollback segment中undo record也会对应的产生。

读一致(CR)的概念:当某session读取某个block的时候(这个block可能是在buffer中的),发现该block的ITL是被使用的,通过ITL找到rollback segment头中的txn table还是active状态,于是去读txn table中所指向的undo record。

锁的产生:DML后,未commit,则ITL为open状态,此时txn table还是active状态,所以就会等待。

当commit后,将tnx table 标记成inactive;注意此时data segment中的block未必会马上更新,即ITL还是open状态;直到这个block下次被读取的时候,ITL的状态才会被改成close。(即延时块清除)。使用延时块清除主要为了节省IO消耗(是指buffer中修改过的块,刷回到disk上,此部分消耗的IO)。

如果是rollback,则会undo原来的事务(从最近的开始,到最早的。),并且将ITL至于clear状态。rollback不存在延时块清除。注意在rollback的过程中会产生新的redo。会访问ITL,data block,rollback segment的header(因为有tnx table在那里),undo record。

当某个进程crash掉的时候,PMON会立即检测到,且开始回滚操作。

当数据库crash掉的时候,当再次open数据库的时候,开始做前滚。在system rollback segment中的事务会被立即回滚,在其他rollback segment中的事务会被mark成dead。
可以用x$ktxue.KTUXECFL=’DEAD’查询,另外,alter system dump undo header xxx的话,在trace文件中也能看到cflag也是0×10(即为DEAD)。

有2个隐含参数常常用于打开undo有问题的数据库:_corrupted_rollback_segment,_offline_rollback_segment。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值