[20171228]关于数据块转储的问题.txt
--//昨天itpub上的问题,链接:http://www.itpub.net/thread-2095877-1-1.html
--//块dump,为何存储scn数据不需要考虑大小字节序来交换顺序,而数据部分需要呢?
--//实际上对于CPU是INTEL系列,要考虑大小头问题,内存上看到的数据与保存在磁盘上的数据是"不一样"的.
--//我以前也写过一些blog,做一些简单的测试来说明:
1.环境:
SCOTT@book> @ &r/ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
SCOTT@book> create table t as select 0 id,'abcd' name from dual;
Table created.
SCOTT@book> set numw 12
SCOTT@book> select rowid,ora_rowscn,t.* from t;
ROWID ORA_ROWSCN ID NAME
------------------ ------------ ------------ --------------------
AAAWEUAAEAAAAIjAAA 13276977886 0 abcd
SCOTT@book> @ &r/rowid AAAWEUAAEAAAAIjAAA
OBJECT FILE BLOCK ROW ROWID_DBA DBA TEXT
------------ ------------ ------------ ------------ -------------------- -------------------- ----------------------------------------
90388 4 547 0 0x1000223 4,547 alter system dump datafile 4 block 547 ;
select 13276977886,trunc(13276977886/power(2,32)) scn_wrap,mod(13276977886,power(2,32)) scn_base from dual
13276977886 SCN_WRAP SCN_BASE
------------ ------------ ------------
13276977886 3 392075998
SCOTT@book> @ &r/bbvi 4 547
BVI_COMMAND
----------------------------------------------------
bvi -b 4481024 -s 8192 /mnt/ramdisk/book/users01.dbf
SCOTT@book> alter system checkpoint;
System altered.
SCOTT@book> alter system checkpoint;
System altered.
--//保存写入磁盘.
2.首先看看内存上保存的数据:
SYS@book> @ &r/bh 4 547
HLADDR DBARFIL DBABLK CLASS CLASS_TYPE STATE TCH CR_SCN_BAS CR_SCN_WRP CR_UBA_FIL CR_UBA_BLK CR_UBA_SEQ BA OBJECT_NAME
---------------- ---------- ---------- ---------- ------------------ ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- --------------------
0000000084B15228 4 547 1 data block xcur 2 0 0 0 0 0 0000000072CB8000 T
--//BA=0000000072CB8000,数据块大小8K(0x2000),这样数据在0x72CBA000-0x10处.0x72CB9FFF0,通过oradebug peek观察:
SYS@book> oradebug setmypid
Statement processed.
SYS@book> oradebug peek 0x72CB9FF0 0x10
[072CB9FF0, 072CBA000) = 002C0000 04800102 64636261 9AE00602
--//注意看内存上保存的字符串 64636261,看到的"dcba".
SCOTT@book> @ &r/conv_c 64636261
old 1: select utl_raw.cast_to_varchar2(lower('&1')) c60 from dual
new 1: select utl_raw.cast_to_varchar2(lower('64636261')) c60 from dual
C60
-----
dcba
--//换一句话讲内存显示4个字节高字节在前,低字节在后.这样你看到的插入字符串就是反的.
--//btw:如果你插入5个字节,看起来有点晕...^_^.
--//这样转化看到就是磁盘保存的顺序:
$ echo 002C0000 04800102 64636261 9AE00602 | xxd -r -p | od -t x4
0000000 00002c00 02018004 61626364 0206e09a
0000020
--//对比bvi直接观察:执行bvi -b 4481024 -s 8192 /mnt/ramdisk/book/users01.dbf
$bvi -b 4481024 -s 8192 /mnt/ramdisk/book/users01.dbf
...
00447FB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00447FC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00447FD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00447FE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00447FF0 00 00 2C 00 02 01 80 04 61 62 63 64 02 06 E0 9A ..,.....abcd....
00448000
--//注意看后面16字节,这样在内存看到不同,4个字节反过来就一致的.也就是讲这样看内存中的scn号不用在颠倒了.
3.通过bbed观察:
BBED> p /d dba 4,547 ktbbh.ktbbhcsc
struct ktbbhcsc, 8 bytes @28
ub4 kscnbas @28 392075998
ub2 kscnwrp @32 3
BBED> p /x dba 4,547 ktbbh.ktbbhcsc
struct ktbbhcsc, 8 bytes @28
ub4 kscnbas @28 0x175e9ade
ub2 kscnwrp @32 0x0003
--//scn在块的偏移28字节处.dump看到就是反的.变成0xde9a5e17,也就是使用bbed修改块,要注意大小头问题,对于intel系列的cpu.
BBED> dump /v offset 28 count 8
File: /mnt/ramdisk/book/users01.dbf (4)
Block: 547 Offsets: 28 to 35 Dba:0x01000223
-----------------------------------------------------------------------------------------------------------
de9a5e17 03000000 l ..^.....
<32 bytes per line>
--//28=0x1c
SYS@book> @ &r/bh 4 547
HLADDR DBARFIL DBABLK CLASS CLASS_TYPE STATE TCH CR_SCN_BAS CR_SCN_WRP CR_UBA_FIL CR_UBA_BLK CR_UBA_SEQ BA OBJECT_NAME
---------------- ---------- ---------- ---------- ------------------ ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- --------------------
0000000084B15228 4 547 1 data block xcur 2 0 0 0 0 0 0000000072CB8000 T
SYS@book> oradebug peek 0x72CB801c 8
[072CB801C, 072CB8024) = 175E9ADE 00000003
--//通过oradebug peek看顺序就是一致的,不需要颠倒.换一句话如果你使用oradebug修改scn数据不需要颠倒,不需要考虑大小头问题,但
--//是数据部分就要考虑这个问题.不知道这样讲是否清楚.
4.做一个转储也很容易明白:
SCOTT@book> alter system dump datafile 4 block 547 ;
System altered.
--//转储的内容如下:
Block dump from disk:
buffer tsn: 4 rdba: 0x01000223 (4/547)
scn: 0x0003.175e9ae0 seq: 0x02 flg: 0x04 tail: 0x9ae00602
frmt: 0x02 chkval: 0x54c5 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007FF59D035A00 to 0x00007FF59D037A00
7FF59D035A00 0000A206 01000223 175E9AE0 04020003 [....#.....^.....]
7FF59D035A10 000054C5 00000001 00016114 175E9ADE [.T.......a....^.]
7FF59D035A20 00000003 00320003 01000220 0000FFFF [......2. .......]
7FF59D035A30 00000000 00000000 00000000 00038000 [................]
7FF59D035A40 175E9ADE 00000000 00000000 00000000 [..^.............]
7FF59D035A50 00000000 00000000 00000000 00000000 [................]
Repeat 1 times
7FF59D035A70 00000000 00000000 00000000 00010100 [................]
7FF59D035A80 0014FFFF 1F621F76 00001F62 1F760001 [....v.b.b.....v.]
7FF59D035A90 00000000 00000000 00000000 00000000 [................]
Repeat 501 times
7FF59D0379F0 002C0000 04800102 64636261 9AE00602 [..,.....abcd....]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Block header dump: 0x01000223
--//左边是内存dump,注意看"64636261"在内存中就是反了.而右边显示就是正的.
-//顺便讲一下如果使用od看该块磁盘内容必须使用参数-t x1,这样才与磁盘上保存顺序一致.
--//我贴出-t的4种显示风格:
$ od -j 4481024 -N 8192 -t x1 -v /mnt/ramdisk/book/users01.dbf | tail -2
21077760 00 00 2c 00 02 01 80 04 61 62 63 64 02 06 e0 9a
21100000
$ od -j 4481024 -N 8192 -t x2 -v /mnt/ramdisk/book/users01.dbf | tail -2
21077760 0000 002c 0102 0480 6261 6463 0602 9ae0
21100000
$ od -j 4481024 -N 8192 -t x4 -v /mnt/ramdisk/book/users01.dbf | tail -2
21077760 002c0000 04800102 64636261 9ae00602
21100000
$ od -j 4481024 -N 8192 -t x -v /mnt/ramdisk/book/users01.dbf | tail -2
21077760 002c0000 04800102 64636261 9ae00602
21100000
--//如果你仔细对比可以发现x1 是1个1个显示,中间空格隔开. x2 是2个2个显示, x4是4个4个显示. x风格与写x4一致.
--//不使用-t参数,显示的是8进制,是2个2个显示的.
$ od -j 4481024 -N 8192 -v /mnt/ramdisk/book/users01.dbf | tail -2
21077760 000000 000054 000402 002200 061141 062143 003002 115340
21100000
--//其中细节你自己看吧.