ORACLE SGA与共享内存的联系

SGA与共享内存

SGA的设置在linux/unix上和一个操作系统内核参数有关,这个参数是shmmax.
不同的操作系统中这个参数据设置的地方一样.在solaris上,这个参数是由
/etc/system文件中的shmsys:shminfo_shmmax来定义的.在linux上,该参数
由/proc/sys/kernel/shmmax参数定义.

shmmax内核参数的作用是系统允许的单个共享内存段的最大值.如果该参数
设置小于oracle sga的大小,那么sga仍然可以创建成功,但是会被分配成多
个共享内存段.通常建议通过调整shmmax的大小来使用sga限制在一个共享
内存段.

在windows系统中,由于系统采用多线程服务器(实际上所有的oracle server procees
都是一个进程中的线程),所以不存在共享内存的问题.无需进行特殊设置.

以32位linux平台为例,来看shmmax参数于数据库的影响.linux上该参数据的缺省值
一般是32M

[root@jingyong ~]# more /proc/sys/kernel/shmmax
33554432

操作系统的版本

[root@jingyong ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.4 (Tikanga)

通过ipcs命令可以查看在shmmax参数为缺省情况下共享内存的分配情况.
可以看到oracle分配了多个共享内存段来满足sga的设置要求:

[root@jingyong ~]# ipcs -sa

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x289516a4 32768      oracle    640        33554432  18
0x289516a4 32778      oracle    640        33554432  18
0x289516a4 32779      oracle    640        33554432  18
0x289516a4 32781      oracle    640        33554432  18
0x289516a4 32784      oracle    640        33554432  18
0x289516a4 32784      oracle    640        4194304  18
0x00000000 65537      gdm       600        393216     2          dest

------ Semaphore Arrays --------
key        semid      owner      perms      nsems
0x0bbc1610 98304      oracle    640        154

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

从上面可以看到sga为160M(171966464字节)被分成了6个共享内存段.

对于每一个后台进程,使用pmap工具可以看到每个共享内存段的地址空间:

[root@jingyong ~]# ps -ef|grep dbw
oracle    2220     1  0 Dec26 ?        00:00:02 ora_dbw0_jingyong
root      3390  3309  0 02:39 pts/2    00:00:00 grep dbw

[root@jingyong ~]# pmap 2220
2220:   ora_dbw0_jingyong
00110000    344K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libocrutl10.so
00166000     16K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libocrutl10.so
0016a000      4K rwx--    [ anon ]
0016b000   1904K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libnnz10.so
00347000    152K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libnnz10.so
0036d000    432K rwx--    [ anon ]
003d9000     36K r-x--  /lib/libnss_files-2.5.so
003e2000      4K r-x--  /lib/libnss_files-2.5.so
003e3000      4K rwx--  /lib/libnss_files-2.5.so
00458000      4K r-x--    [ anon ]
00459000   1276K r-x--  /lib/libc-2.5.so
00598000      4K --x--  /lib/libc-2.5.so
00599000      8K r-x--  /lib/libc-2.5.so
0059b000      4K rwx--  /lib/libc-2.5.so
0059c000     12K rwx--    [ anon ]
005b4000    436K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libocr10.so
00621000      4K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libocr10.so
00622000   1032K rwx--    [ anon ]
00839000      4K rwx--    [ anon ]
0089f000    880K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libhasgen10.so
0097b000     20K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libhasgen10.so
00980000     12K rwx--    [ anon ]
0098f000      4K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libskgxn2.so
00990000      4K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libskgxn2.so
009fd000     36K rwx--    [ anon ]
00a5a000      4K rwx--    [ anon ]
00ab7000    128K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libskgxp10.so
00ad7000      8K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libskgxp10.so
00b01000     76K r-x--  /lib/libnsl-2.5.so
00b14000      4K r-x--  /lib/libnsl-2.5.so
00b15000      4K rwx--  /lib/libnsl-2.5.so
00b16000      8K rwx--    [ anon ]
00b36000     88K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libdbcfg10.so
00b4c000      8K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libdbcfg10.so
00bfd000    104K r-x--  /lib/ld-2.5.so
00c17000      4K r-x--  /lib/ld-2.5.so
00c18000      4K rwx--  /lib/ld-2.5.so
00c1b000      4K r-x--  /usr/lib/libaio.so.1.0.1
00c1c000      4K rwx--  /usr/lib/libaio.so.1.0.1
00cbc000     32K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libclsra10.so
00cc4000      4K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libclsra10.so
00d67000    148K r-x--  /lib/libm-2.5.so
00d8c000      4K r-x--  /lib/libm-2.5.so
00d8d000      4K rwx--  /lib/libm-2.5.so
00d90000      8K r-x--  /lib/libdl-2.5.so
00d92000      4K r-x--  /lib/libdl-2.5.so
00d93000      4K rwx--  /lib/libdl-2.5.so
00d96000     76K r-x--  /lib/libpthread-2.5.so
00da9000      4K r-x--  /lib/libpthread-2.5.so
00daa000      4K rwx--  /lib/libpthread-2.5.so
00dab000      8K rwx--    [ anon ]
00e33000    268K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libocrb10.so
00e76000      4K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libocrb10.so
00ee0000      4K rwx--    [ anon ]
00f07000      4K rwxs-  /u01/app/oracle/product/10.2.0/db/dbs/hc_jingyong.dat
00f76000      4K rwx--    [ anon ]
00f77000   7028K r-x--  /u01/app/oracle/product/10.2.0/db/lib/libjox10.so
01654000    260K rwx--  /u01/app/oracle/product/10.2.0/db/lib/libjox10.so
01695000      4K rwx--    [ anon ]
048b1000   1556K rwx--    [ anon ]
08048000  77032K r-x--  /u01/app/oracle/product/10.2.0/db/bin/oracle
0cb82000    324K rwx--  /u01/app/oracle/product/10.2.0/db/bin/oracle
0cbd3000    120K rwx--    [ anon ]
0e505000    456K rwx--    [ anon ]
20000000 167936K rwxs-    [ shmid=0x8000 ]
b7e6a000     64K rwx--  /dev/zero
b7e7a000     64K rwx--  /dev/zero
b7e8a000     64K rwx--  /dev/zero
b7e9a000     64K rwx--  /dev/zero
b7eaa000     64K rwx--  /dev/zero
b7eba000     64K rwx--  /dev/zero
b7eca000     64K rwx--  /dev/zero
b7eda000     64K --x--  /dev/zero
b7eea000     24K rwx--  /dev/zero
b7ef0000     64K rwx--  /dev/zero
b7f00000     64K rwx--  /dev/zero
b7f10000     64K rwx--  /dev/zero
b7f20000    128K rwx--  /dev/zero
b7f40000     64K rwx--  /dev/zero
b7f50000     64K rwx--  /dev/zero
b7f60000     40K rwx--  /dev/zero
bffb7000     84K rwx--    [ stack ]
 total   263492K

为了避免给sga分配多个共享内存段,可以修改shmmax内核参数,使用sga存在于一个
共享内存段中,可以通过修改/proc/sys/kernel/shmmax参数可以达到此目的

[root@jingyong ~]# echo 536870912> /proc/sys/kernel/shmmax
[root@jingyong ~]# more /proc/sys/kernel/shmmax
536870912

我修改了512M了,这里对于shmmax参数的修改不会永久的生效,在系统重新启动后
会失效.可以通过修改/etc/sysctl.conf文件来进行永久修改.
在/ect/sysctl.conf文件中增加以下一行这个更改在系统重启后仍然生效
kernel.shmmax=536870912

在修改shmmax参数后,重启数据库使更改生效
在重新启动数据库后我们再来查看共享内存的分配情况:

[root@jingyong ~]# ipcs -sa

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x289516a4 32768      oracle    640        171966464  18
0x00000000 65537      gdm       600        393216     2          dest

------ Semaphore Arrays --------
key        semid      owner      perms      nsems
0x0bbc1610 98304      oracle    640        154

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

可以看到共享内存分配只分配了一个共享内存段

如果没有修改shmmax参数,oracle在启动过程中就会在alert_.log文件中记录警告:

Starting ORACLE instance(normal)
Thu Nov 21 16:02;02 2012
WARNING:EINVAL creating segment of size 0x0000000033400000
fix shm parameter in /etc/system or equivalent

这是一个警告提示,是建议修改shmmax参数不是强制

ora_rowscn伪列的用途

ora_rowscn

对于每一行数据,ora_rowscn返回每一行最近被修改的大概时间.这对于判断一行数据
大概是在什么时间被修改的还是有用的.因oracle是通过事务提交对行所在数据块来
进行scn的跟踪的所以说它不精确.可以通过在创建表时使用行级别的依赖跟踪来获得
一个更加精确的scn.create table … norowdependencies|rowdependencies

在对视图进行查询时不能使用ora_rowscn.但对于视图的基表是可以使用ora_rowscn.
也能在update或delete语句中的where子句中使用ora_rowscn

ora_rowscn不能用于回闪查询,但是可以用回闪版本查询来代替ora_rowscn.

ora_rowscn也不能用于外部表

获取行被修改的大根的scn

SQL> select ora_rowscn,t.test_id from test_jy t;

ORA_ROWSCN               TEST_ID
---------- ---------------------
    625591                     3

通过scn来获取修改行记录大概的时间

SQL> select scn_to_timestamp(ora_rowscn),t.test_id from test_jy t;

SCN_TO_TIMESTAMP(ORA_ROWSCN)                                                                   TEST_ID
-------------------------------------------------------------------------------- ---------------------
20-12月-12 06.23.22.000000000 下午                                                                   3

也可以通过时间来获得scn

SQL> select timestamp_to_scn(scn_to_timestamp(ora_rowscn)),t.test_id from test_jy t;

TIMESTAMP_TO_SCN(SCN_TO_TIMEST               TEST_ID
------------------------------ ---------------------
                        625590                     3

Oracle dump函数的与utl_raw

函数式:

DUMP(expr[,return_fmt[,start_position][,length]])

基本参数时4个,最少可以填的参数是0个。当完全没有参数时,直接返回null。另外3个参数也都有各自的默认值:
expr:这个参数是要进行分析的表达式(数字或字符串等,可以是各个类型的值)
return_fmt:指返回参数的格式,有5种用法:
1)8:以8进制返回结果的值
2)10:以10进制返回结果的值(默认)
3)16:以16进制返回结果的值
4)17:以单字符的形式返回结果的值
5)1000:以上4种加上1000,表示在返回值中加上当前字符集
start_position:开始进行返回的字符位置
length:需要返回的字符长度

示例

sql> select dump('abc') from dual;

DUMP('ABC')
----------------------
Typ=96 Len=3: 97,98,99

sql> select dump('abc',16) from dual;

DUMP('ABC',16)
----------------------
Typ=96 Len=3: 61,62,63

sql> select dump('abc',1016) from dual;

DUMP('ABC',1016)
--------------------------------------------
Typ=96 Len=3 CharacterSet=ZHS16GBK: 61,62,63

sql> select dump('abc',17,2,2) from dual;

DUMP('ABC',17,2,2
-----------------
Typ=96 Len=3: b,c

结果的格式一般都是类似:Typ=96 Len=3 [CharacterSet=ZHS16GBK]: 61,62,63

type

typ表示当前的expr值的类型。如:2表示NUMBER,96表示CHAR。

CODE TYP
----- ------------------------------
1     VARCHAR2
2     NUMBER
8     LONG
12    DATE
23    RAW
24    LONG RAW
69    ROWID
96    CHAR
112   CLOB
113   BLOB
114   BFILE
180   TIMESTAMP
181   TIMESTAMP WITH TIMEZONE
182   INTERVAL YEAR TO MONTH
183   INTERVAL DAY TO SECOND
208   UROWID
231   TIMESTAMP WITH LOCAL TIMEZONE

len
len表示该值所占用的字节数。
对于汉字,ZHS16GBK编码一个汉字需要2个字节,UTF8需要3个字节。

Value
具体的存储值。返回的数值就是Oracle在自己内部对前面的这个expr值得存储形式。对于非汉字的普通字符串,可以理解为就是它的ASCII码。

SQL>  select to_number('3230','xxxx')from dual;

TO_NUMBER('3230','XXXX')
------------------------
                   12848
SQL>   select to_number('3430','xxxx')from dual;

TO_NUMBER('3430','XXXX')
------------------------
                   13360
SQL>      select to_number('3036','xxxx')from dual;

TO_NUMBER('3036','XXXX')
------------------------
                   12342

SQL>
SQL>      select chr(12848)from dual;

CHR(12848)
----------
20
SQL>       select chr(13360)from dual;

CHR(13360)
----------
40
SQL>      select chr(12342)from dual;

CHR(12342)
----------
06

将CHR(12848)+CHR(13360)+CHR(12342)=204006

utl_raw.cast_to_xxx()作为dump的逆函数

sql>select dump('201201',16) from dual;
dump('201201',16)
---------------------------------------------------------
Typ=96 Len=6: 32,30,31,32,30,31

sql>select utl_raw.cast_to_varchar2('323031323031') value from dual
201201

Oracle 数据类型CHAR, NCHAR, VARCHAR2, NVARCHAR2

CHAR与VARCHAR2

字符数据通常是以单字节存储在数据库字符集中:
CHAR
–固定长度的字符串最长可达2000个字节
–内部代码:96
VARCHAR@
–可变长的字符串最长可达4000个字节
–内部代码:1

CHAR
在一个类型为char的列中,所有空字节都会用空格来补充(字符32)
它的长度是固定的

SQL> select gr03,dump(gr03) from wb02 where gr03< '4307050000000097';

GR03             DUMP(GR03)
---------------- ---------------------------------------------------------------
4307050000000091 Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,49
4307050000000092 Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,50
430705000000093  Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,51
4307050000000094 Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,52
43070500000095   Typ=96 Len=16: 52,51,48,55,48,53,48,48,48,48,48,48,48,48,57,53

从上面的输出typ=96,len=16,可以看出char的内部代码是96,长度是16

varchar2
在一个类型为varchar2的列中,oracle不会使用空格来进行补位
它的长度是可变的

SQL> select dw02,dump(dw02) from wb01 where dw01< '0012';

DW02                       DUMP(DW02)
-------------------------- --------------------------------------------------------------------------------
灵活人员                   Typ=1 Len=8: 193,233,187,238,200,203,212,177
灵活就业人员               Typ=1 Len=12: 193,233,187,238,190,205,210,181,200,203,212,177
西湖区委、区管委           Typ=1 Len=16: 206,247,186,254,199,248,206,175,161,162,199,248,185,220,206,175
西湖区委、区管委办公室     Typ=1 Len=22: 206,247,186,254,199,248,206,175,161,162,199,248,185,220,206,175,17
西湖管理区政治部           Typ=1 Len=16: 206,247,186,254,185,220,192,237,199,248,213,254,214,206,178,191
西湖管理区监察局           Typ=1 Len=16: 206,247,186,254,185,220,192,237,199,248,188,224,178,236,190,214
西湖管理区财政局           Typ=1 Len=16: 206,247,186,254,185,220,192,237,199,248,178,198,213,254,190,214

从上面的输出typ=1可以看出varchar2的内部代码是1,它的长度不是固定的

nchar与nvarchar2
字符数据也可以存储在国际(多字节)字符集中
nchar
--固定长度的字符串最大可达2000个字节
--内部代码:96

nvarchar2
--可变长度的字符串最大可达4000个字节
--内部代码:1

nchar
在一个类型为nchar的列中,所有空字节都会用空格来补充(字符32)
它的长度是固定的

SQL> desc wb02_jy
Name Type      Nullable Default Comments
---- --------- -------- ------- --------
GR03 NCHAR(18) Y

SQL> select gr03,dump(gr03) from wb02_jy;

GR03                                 DUMP(GR03)
----------------------------- --------------------------------------------------------------------------------
4307050000000091              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,
4307050000000092              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,
4307050000000093              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,
4307050000000094              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,
4307050000000095              Typ=96 Len=36: 0,52,0,51,0,48,0,55,0,48,0,53,0,48,0,48,0,48,0,48,0,48,0,48,0,48,

如上输出一样gr03定义为nchar(18),但是它是双字节所以长度len=36是18的2倍,内部代码还是与char一样96

nvarchar2
在一个类型为nvarchar2的列中,oracle不会使用空格来进行补位
它的长度是可变的

SQL> select dw02,dump(dw02) from wb01_jy;

DW02                            DUMP(DW02)
----------------------------- --------------------------------------------------------------------------------
灵活人员                      Typ=1 Len=8: 112,117,109,59,78,186,84,88
灵活就业人员                  Typ=1 Len=12: 112,117,109,59,92,49,78,26,78,186,84,88
西湖区委、区管委              Typ=1 Len=16: 137,127,110,86,83,58,89,212,48,1,83,58,123,161,89,212
西湖区委、区管委办公室        Typ=1 Len=22: 137,127,110,86,83,58,89,212,48,1,83,58,123,161,89,212,82,158,81,10
西湖管理区政治部              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,101,63,108,187,144,232
西湖管理区监察局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,118,209,91,223,92,64
西湖管理区财政局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,141,34,101,63,92,64
西湖管理区劳动保障局          Typ=1 Len=20: 137,127,110,86,123,161,116,6,83,58,82,179,82,168,79,221,150,156,92
西湖管理区农村经济开发局      Typ=1 Len=24: 137,127,110,86,123,161,116,6,83,58,81,156,103,81,126,207,109,78,95
西湖管理区卫生局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,83,107,117,31,92,64
西湖管理区国土局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,86,253,87,31,92,64
西湖管理区移民开发局          Typ=1 Len=20: 137,127,110,86,123,161,116,6,83,58,121,251,108,17,95,0,83,209,92,6
西湖管理区经贸局              Typ=1 Len=16: 137,127,110,86,123,161,116,6,83,58,126,207,141,56,92,64

从上面的输出typ=1可以看出nvarchar2的内部代码是1,它的长度不是固定的

dump表的数据块

dump表的数据块

dump一个表的数据块要知道这个块所在的位置(数据文件的编号和数据块的编号)
例如我要dump表aes1的数据块

SQL> select a.file_id,a.block_id,a.bytes,a.blocks from dba_extents a
  2  where a.owner='INSUR_CHANGDE' and a.segment_name='AES1';

   FILE_ID   BLOCK_ID      BYTES     BLOCKS
---------- ---------- ---------- ----------
         5         57      65536          8

在这里,可以找到表aes1所在的文件编号是5,数据块是从64开始的。

例如我要dump表aes1中的特定数据块

SQL> select rowid,a.* from aes1 a where a.aae002 between '201201' and '201212';

ROWID              AAE002
------------------ ------
AAAM7rAAFAAAABAAEI 201201
AAAM7rAAFAAAABAAEJ 201202
AAAM7rAAFAAAABAAEK 201203
AAAM7rAAFAAAABAAEL 201204
AAAM7rAAFAAAABAAEM 201205
AAAM7rAAFAAAABAAEN 201206
AAAM7rAAFAAAABAAEO 201207
AAAM7rAAFAAAABAAEP 201208
AAAM7rAAFAAAABAAEQ 201209
AAAM7rAAFAAAABAAER 201210
AAAM7rAAFAAAABAAES 201211
AAAM7rAAFAAAABAAET 201212

dump表aes1中aae002=201210这一条记录所在的数据块

SQL> SELECT dbms_rowid.rowid_object('AAAM7rAAFAAAABAAER') data_object_id#,
  2             dbms_rowid.rowid_relative_fno('AAAM7rAAFAAAABAAER') rfile#,
  3             dbms_rowid.rowid_block_number('AAAM7rAAFAAAABAAER') block#,
  4             dbms_rowid.rowid_row_number('AAAM7rAAFAAAABAAER') row#
  5        FROM dual;

DATA_OBJECT_ID#     RFILE#     BLOCK#       ROW#
--------------- ---------- ---------- ----------
          52971          5         64        273

执行dump命令

sql>alter system dump datafile 5 block min 57 block max 64;

打开所对应的trace文件看dump出来的内容

Start dump data blocks tsn: 6 file#: 5 minblk 57 maxblk 64
buffer tsn: 6 rdba: 0x01400039 (5/57)
scn: 0x0000.00b8ba77 seq: 0x05 flg: 0x04 tail: 0xba772005
frmt: 0x02 chkval: 0x0c48 type: 0x20=FIRST LEVEL BITMAP BLOCK
Hex dump of block: st=0, typ_found=1

file#: 5 minblk 57 maxblk 64
可以看到我们dump的是文件编号是5,开始的block号为57(minblk),结束的block号为64(maxblk)。
可以从这里看出来

rdba: 0x01400039 (5/57)
rdba: relative database address of the block相对数据块地址0x01400039

可以看到(5/57),其实意思就是file# 5, block# 57。

scn: 0x0000.00b8ba77 seq: 0x05 flg: 0x04 tail: 0xba772005
SCN是最后变化的scn,在上面的例子中SCN是0x0000.00b8ba77。
tail是由SCN的后4位(ba77)、type(20)以及sequence(05)组成,即ba772005。
如果Tail与SCN的后4位(ba77)、type(20)以及sequence(05)这三个值不一致,
那么这个块就存在问题,需要恢复或者回滚。

frmt: 0x02 chkval: 0x0c48 type: 0x20=FIRST LEVEL BITMAP BLOCK

type具体意思可以看以下列表:

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

Block header dump:  0x0140003c
 Object id on Block? Y
 seg/obj: 0xceeb  csc: 0x00.b8ba76  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x1400039 ver: 0x01 opc: 0
     inc: 0  exflg: 0

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0008.02c.000010ee  0x00800c28.0310.0a  --U-  127  fsc 0x0000.00b8ba78
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

“Object id on Block?”告知我们对象是否存在于SYS.OBJ$。从oracle 6开始,这里一般都是”Y”。
seg/obj的值是16进制的segment的对象编号。上面的数值是0xceeb,16进制是ceeb。
使用oracle转化为10进制数:

SQL> select to_number('ceeb','xxxx') from dual;

TO_NUMBER('CEEB','XXXX')
------------------------
                   52971


SQL> select owner,object_name from dba_objects  where object_id=52971;

OWNER                          OBJECT_NAME
------------------------------ ------------------------------------------
INSUR_CHANGDE                  AES1

正如我们所想那样的信息。
csc值(Cleanout System Change number)与SCN值相同时该块会被清除。
itc值(Interested Transaction List Count)表示ITL的数量,在上面的例子中
itc的值为2表示有这个数据块上有两个相关的事务.这些事务id(Xid)显示有两
个事务.这些事务的id值与回滚段相关联被用来处理我们的事务
flag(flg)中”-“或者”O”表示是否在自由列表中,”0″则在,”-“则不在。估计E也是不在的意思。
如果在自由列表的话会出现:
fsl(ITL freelist slot)表示ITL自由列表的开始位置。
fnx(Next freelist block)表示segment自由列表中下一个block的RDBA地址。

Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0008.02c.000010ee  0x00800c28.0310.0a  --U-  127  fsc 0x0000.00b8ba78
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

Xid:事务id,在回滚段事务表中有一条记录和这个事务对应。
Xid组成:Undo Segment Number +Transaction Table Slot Number+ Wrap。
Uba:回滚段地址,该事务对应的回滚段地址。
Uba组成:回滚块地址(undo文件号和数据块号)+回滚序列号+回滚记录号。

Flag:这里可以看下面列表:

Value  Meaning
----  transaction is active, or committed pending cleanout
C---  transaction has been committed and locks cleaned out
B---  this undo record contains the undo for this ITL entry
U---  transaction committed (maybe long ago); SCN is an upper bound
T---  transaction was still active at block cleanout SCN




data_block_dump,data header at 0x8628464
===============
tsiz: 0x1f98
hsiz: 0x110
pbl: 0x08628464
bdba: 0x0140003c
     76543210
flag=--------
ntab=1
nrow=127
frre=-1
fsbo=0x110
fseo=0x1aa2
avsp=0x1992
tosp=0x1992
0xe:pti[0] nrow=127 offs=0
0x12:pri[0] offs=0x1aa2
0x14:pri[1] offs=0x1aac
0x16:pri[2] offs=0x1ab6
0x18:pri[3] offs=0x1ac0
0x1a:pri[4] offs=0x1aca
0x1c:pri[5] offs=0x1ad4
.......

上面的tsiz值显示了在数据块中还可以使用的空间大小,将1f98
转换成十进制为8088字节

ntab的值告诉我们在这个数据块中存储有多少个表,除非这个数据块
属于一个集簇,否则这个值将会是1.

nrow的值告诉我有多少行数据存储在数据块中.上面显示这个数据块
有127行数据

从地址0xe开始,我们得到每一行的一个目录.我们可以看到第一行是从
数据块的偏移地址为’0x1aa2′.用这种方式可以快速找到数据行.
rowid是唯一指示每一行数据的它的格式是(对象编号+相关文件号+块号+行号)


block_row_dump:
tab 0, row 0, @0x1aa2
tl: 10 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 6]  32 30 34 30 30 36
tab 0, row 1, @0x1aac
tl: 10 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 6]  32 30 34 30 30 37
tab 0, row 2, @0x1ab6
tl: 10 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 6]  32 30 34 30 30 38
tab 0, row 3, @0x1ac0
tl: 10 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 6]  32 30 34 30 30 39
tab 0, row 4, @0x1aca
tl: 10 fb: --H-FL-- lb: 0x1  cc: 1

真实的行数据是从”block_row_dump”开始的.
然后给出一个行数据。只在这里显示的一行数据,其余的是类似的。
我们可以看到,这行属于表’ 0 ‘(标签)我们的集簇。由于没有集簇在我们的例子中,
我们不会有一个以上的表,这个值将是零。我们还可以看到,这是行’ 0 ‘和那一行的地址
这个地址必须与我们上面提到第一行数据是从数据块的偏移地址为’0x1aa2’
而在上面显示的row 0, @0x1aa2中的0x1aa2是相匹配的

t1说明这一行数据的总的字节数包含任何开销.我们可以看到这一行是有10字节
cc说明这一行有多少列,上面显示的是1列.
fb显示了行的标记.H是行头,F是行的第一个片段,L是行的最后一个片段.
如果显示为这一行的第一个和最后一个行片段说明行没有发生链接.因此
行头和行不会迁移

tab 0, row 0, @0x1aa2
tl: 10 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 6]  32 30 34 30 30 36

第一行第一列显示为 32 30 34 30 30 36是字符型
那进行转换

SQL>  select to_number('3230','xxxx')from dual;

TO_NUMBER('3230','XXXX')
------------------------
                   12848
SQL>   select to_number('3430','xxxx')from dual;

TO_NUMBER('3430','XXXX')
------------------------
                   13360
SQL>      select to_number('3036','xxxx')from dual;

TO_NUMBER('3036','XXXX')
------------------------
                   12342

SQL>
SQL>      select chr(12848)from dual;

CHR(12848)
----------
20
SQL>       select chr(13360)from dual;

CHR(13360)
----------
40
SQL>      select chr(12342)from dual;

CHR(12342)
----------
06

将CHR(12848)+CHR(13360)+CHR(12342=204006

Proudly powered by WordPress | Indrajeet by Sus Hill.