|
Brian Peasland, Raytheon at EROS Data Center
在网上看见这篇文章,我简单的翻译了一下。
Introduction 实际上,需要我们dump Oracle的数据块的CASE是很少见。这些块包括表、索引甚至是控制文件。当我们查询一个表的内容时候,我们可能会思考表的内部有什么奥秘,而不仅仅满足于查询返回的。本文将讨论如何dump数据块,解释dump出的内容。
Why Dump Blocks? 但我们还是要问,为什么要这样做呢?很大程度上,这是取决于你的好奇心。尤其是作为一个DBA,要具备强烈的好奇心。Oracle并没有的开放其数据块的内核,仅仅稍微透露的一些信息,这样更加让我们好奇。因而,大多数情况下,dump只是一种试验,不过也许在一些CASE中,我们也可以利用塔找到有价值的东西。总之,对我们来说,它是一种有意思的事情。
Trace File Information
本文所有的例子都是生成的trace文件,参考参数USER_DUMP_DEST用于找到它。通过下面的查询,可以确定trace文件的生成。
ORA9I SQL> select pa.value || '/' || i.instance_name || '_ora_' 2 || pr.spid || '.trc' as trace_file 3 from v$session s, v$process pr, v$parameter pa, v$instance i 4 where s.username = user and s.paddr = pr.addr 5* and pa.name='user_dump_dest';
TRACE_FILE ------------------------------------------------------------------------ /edcsns14/pkg/oracle/admin/ora9i/udump/ora9i_ora_25199.trc
这个查询显示我的会话的trace文件的完整路径和文件名,这个文本文件中将显示出我们dump的内容。
所有的trace文件头包含同样的基本信息:
Oracle9i Enterprise Edition Release 9.0.1.0.0 - Production With the Partitioning option JServer Release 9.0.1.0.0 - Production ORACLE_HOME = /edcsns14/pkg/oracle/9.0.1 System name: SunOS Node name: edcsns14 Release: 5.7 Version: Generic_106541-11 Machine: sun4u Instance name: ora9i Redo thread mounted by this instance: 1 Oracle process number: 11 Unix process pid: 653, image: oracle@edcsns14 (TNS V1-V3)
*** 2002-03-27 17:06:06.573 *** SESSION ID:(12.4240) 2002-03-27 17:06:06.535
每个trace文件头的输出都类似。这个输出显示数据库的版本,一些平台信息诸如主机名,OS等级,数据库实例名,会话的进程标识(Oracle和Unix)以及时间。这些信息我们简略介绍至此。
Dumping A Table Block 为了导出一个表的某一数据库,你需要知道文件号和块号。如果你已经知道了,那就准备就绪。
ORA9I SQL> select file_id,block_id,bytes,blocks 2 from dba_extents 3 where owner='PEASLAND' and segment_name='EMP';
FILE_ID BLOCK_ID BYTES BLOCKS ------- ---------- ---------------- -------- 3 9 65,536 8 这里,我查询了一个数据字典表用于查寻我的EMP表的物理位置。EMP表在3号文件中,起始数据块是9,然后它包含8个数据块。这个查寻对每个段将返回一行。如果这个对象是有很多盘区组成,我能检查表空间是否属于当前文件,通过以下查寻:
ORA9I SQL> select tablespace_name,file_name from dba_data_files 2 where relative_fno = 3;
TABLESPACE_NAME FILE_NAME ------------------------------ ----------------------------------------- USER_DATA /edcsns14/oradata3/ora9i/user_data01.dbf 正如我希望的一样,我的表在USER_DATE表空间中。
现在,让我们来dump一个块吧,操作如下:
ORA9I SQL> alter system dump datafile 3 block 10;
System altered.
你也可以导出一个范围的数据块:
ORA9I SQL> alter system dump datafile 3 block min 10 block max 12;
System altered.
下面我们来查看导出的内容:
Start dump data blocks tsn: 3 file#: 3 minblk 10 maxblk 10 buffer tsn: 3 rdba: 0x00c0000a (3/10) scn: 0x0000.00046911 seq: 0x02 flg: 0x04 tail: 0x69110602 frmt: 0x02 chkval: 0x579d type: 0x06=trans data Block header dump: 0x00c0000a Object id on Block? Y seg/obj: 0x6d9c csc: 0x00.46911 itc: 2 flg: O typ: 1 - DATA fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc 0x01 xid: 0x0005.02f.0000010c uba: 0x00806f10.00ca.28 C--- 0 scn 0x0000.00046900 0x02 xid: 0x0003.01c.00000101 uba: 0x00800033.0099.04 C--- 0 scn 0x0000.00046906
这是一个数据块dump信息的开始部分。第一行告诉我们,该块是来自是文件3,起始块是#10,终止块也是#10。我们也可以导出一个范围的块。数据块的地址是0x00c0000a。(3/10)指的文件3,第10号块。
第三行是数据块的SCN。在这个例子里,SCN是0x0000.00046911。而tail是由SCN的后两个byte(6911),再加上类型(06)和序列(02)。如果tail的分解和SCN不符合了,那么就需要恢复。这个tail的值是显示在dump信息的开头,但是它实际是存储在数据块的结尾的。
第四行是数据块的类型,请参考如下列表:
Type Meaning 0x02 undo block 0x06 table or index data block 0x0e undo segment header 0x10 data segment header block 0x17 bitmapped data segment header
“Object id on Block?” 这句话告诉我们这个对象是否在SYS.OBJ$里。从Oracle6开始,这里就一直是Y。继续看下一行,seg/obj的值告诉我们段的对象id(16进制)。我们能够用下面的查寻校验它是否属于我们的表。28060是转换后10进制的值。
ORA9I SQL> select owner,object_name from dba_objects 2 where object_id=28060;
OWNER OBJECT_NAME ---------- ------------------------------ PEASLAND EMP
Csc的值是清除SCN的值,这个值告诉我们块的清除是什么时候发生的。它和块的SCN是一致的。Itc的值是事务链表统计。在这个例子里,有两个事务访问这个块。这些事务是在我们的例子外执行的。我们能够看到它们的事务id(Xid)。这些事务标识起着和回滚段类似的作用。
Flag(flg)要么是“-”要么是“O”,用于表示这个块是否在freelist上。如果在,那么就是O。
好了,接下来有更多的信息等着我们的解读。
data_block_dump =============== tsiz: 0x1fa0 hsiz: 0x2e pbl: 0x024d015c bdba: 0x00c0000a flag=------------- ntab=1 nrow=14 frre=9 fsbo=0x2e fseo=0x1b18 avsp=0x1d8a tosp=0x1d8a 0xe:pti[0] nrow=14 offs=0 0x12:pri[0] offs=0x1c30 0x14:pri[1] offs=0x1f4f 0x16:pri[2] offs=0x1f24 0x18:pri[3] offs=0x1efb 0x1a:pri[4] offs=0x1ece 0x1c:pri[5] offs=0x1ea5 0x1e:pri[6] offs=0x1e7c 0x20:pri[7] offs=0x1e54 0x22:pri[8] offs=0x1e2e 0x24:pri[9] sfll=13 0x26:pri[10] offs=0x1ca4 0x28:pri[11] offs=0x1cf1 0x2a:pri[12] offs=0x1b18 0x2c:pri[13] sfll=-1 Tsiz值给我们显示了当前数据块的可用空间。这里,我们1fa0就是指8096个byte可用。另外在一个块里面,有一些空间是用于块头的。
Ntab值显示有多少个表存储在这个块里面。不过,除非这个块是一个集群表,否则它就是1.nrow显示有多少行,在这里有14行。
开始地址是‘0xe’,每一行都有一个目录。我们可用看见第一行(索引0)起始的offset address 是‘0x1c30’。块里面的每一行都按这样排列。这样,能够很快的找到某一行。在Oracle8+,ROWID是由O.F.B.R组(objectno,relativefno,blockno,rowno)
。
现在我们对数据块有一个初步认识,我们来看trace file 中剩余的部分。
block_row_dump: tab 0, row 0, @0x1c30 tl: 39 fb: --H-FL-- lb: 0x0 cc: 8 col 0: [ 3] c2 4a 46 col 1: [ 5] 53 4d 49 54 48 col 2: [ 5] 43 4c 45 52 4b col 3: [ 3] c2 50 03 col 4: [ 7] 77 b4 0c 11 01 01 01 col 5: [ 3] c2 09 19 col 6: *NULL* col 7: [ 2] c1 15 实际的行是从“block_row_dump:”开始出现的,也就是块中存储的实际数据。我们这里只列出了一行。我们可以看出这行属于table‘0’.
T1值告诉我们这个行有多少个byte,包含一些额外的开销。这一行占用39个byte。‘cc’的值表明有多少个字段。
Fb值是一个标记,H意思是我们在行的头部,F表明这是这行第一块,L表示是最后一块,那就意味着这行记录没有发生行迁移或者行链接。
其余的信息则是数据,例如在第一行,我们有一行ASCII字符编码“53 4d 49 54 48”,它的意思就是”SMITH”。如果你查询EMP表,你就知道SMITH是一个雇员的名字。另外,要注意column6是空,column4是data类型,它用7个byte来存储。
<未完待续>
|
一共有 0 条评论