[20171228]關於資料塊轉儲的問題.txt

lfree發表於2017-12-28

[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

--//其中細節你自己看吧.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2149428/,如需轉載,請註明出處,否則將追究法律責任。

相關文章