[20201218]資料檔案OS頭的修復.txt

lfree發表於2020-12-18

[20201218]資料檔案OS頭的修復.txt

--//昨天看了資料檔案頭部點陣圖block損壞怎麼辦,我自己以前也做過類似測試。
--//我把以前的測試看了一遍,自己感覺當時的測試非常混亂,概念也很混亂。決定重新學習,重複測試看看。

1.環境:

SCOTT@book> @ 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> alter system dump datafile 4 block 2;
System altered.

SCOTT@book> alter system dump datafile 4 block 3;
System altered.

SCOTT@book> alter system dump datafile 4 block 127;
System altered.

--//首先簡單說明一下,資料檔案第0塊就是os塊,如果建立資料檔案指定的大小10M,而實際上生產檔案大小是10+db_block_size,一般
--//選擇db_block_size=8192, 這樣實際檔案大小是10*1024*1024+8192.
--//資料檔案第1塊就是資料檔案頭,更新檢查點就是寫這塊資訊,比如執行alter system checkpoint;命令。
--//第2塊為type: 0x1d=KTFB Bitmapped File Space Header
--//第3塊為type: 0x1e=KTFB Bitmapped File Space Bitmap
...
--//第127塊為type: 0x1e=KTFB Bitmapped File Space Bitmap

--//說明幾點:10g與11g的情況有點不同,實際上10g如果如果資料檔案很大,可能在尾部還會出現點陣圖區。參考連結:
http://blog.itpub.net/267265/viewspace-2148389/ =>[20171206]點陣圖區一定在資料檔案開頭嗎.txt

--//另外我沒有考慮建立小資料檔案的情況,因為生產系統不會建立很小的資料檔案,比如你可以嘗試建立88k的大小,這種情況不在考
--//慮以及測試範圍。
--//可以參考http://blog.itpub.net/267265/viewspace-2127936/=>[20161107]關於資料檔案點陣圖區.txt
--//另外我個人認為這種破壞1,2個塊的情況很少出現,除非遇到oracle的bug,最大的可能前面1M的區域被覆蓋。
--//當然測試恢復給幾種情況單獨非常測試以及恢復。

2.本測試主要解決資料檔案OS頭的修復:

--//說明一點,os都,資料檔案頭是不能使用 alter system dump datafile轉儲的,執行成功並不能看到任何資訊。
SCOTT@book> alter system dump datafile 4 block 0;
System altered.

SCOTT@book> alter system dump datafile 4 block 1;
System altered.

*** 2020-12-18 09:56:43.069
End dump data blocks tsn: 4 file#: 4 minblk 2 maxblk 0
*** 2020-12-18 09:57:36.533
Start dump data blocks tsn: 4 file#:4 minblk 1 maxblk 1
Block 1 (file header) not dumped:use dump file header command
End dump data blocks tsn: 4 file#: 4 minblk 2 maxblk 1


SCOTT@book> @ bbvi 4 0
BVI_COMMAND
----------------------------------------------------------------------------------------------------
bvi -b 0 -s 8192 /mnt/ramdisk/book/users01.dbf
xxd -c16 -g 2 -s 0 -l 8192 /mnt/ramdisk/book/users01.dbf
dd if=/mnt/ramdisk/book/users01.dbf bs=8192 skip=0 count=1 of=4_0.dd conv=notrunc 2>/dev/null
od -j 0 -N 8192 -t x1 -v /mnt/ramdisk/book/users01.dbf
hexdump -s 0 -n 8192 -C -v /mnt/ramdisk/book/users01.dbf
alter system dump datafile '/mnt/ramdisk/book/users01.dbf' block 0;

alter session set events 'immediate trace name set_tsn_p1 level 5';
alter session set events 'immediate trace name buffer level 16777216';
9 rows selected.

$ od  -j 0 -N 8192 -t x1  /mnt/ramdisk/book/users01.dbf
0000000 00 a2 00 00 00 00 c0 ff 00 00 00 00 00 00 00 00
0000020 66 32 00 00 00 20 00 00 00 c8 00 00 7d 7c 7b 7a
0000040 a0 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0020000


$ ls -l /mnt/ramdisk/book/users01.dbf
-rw-r----- 1 oracle oinstall 419438592 2020-12-18 10:00:50 /mnt/ramdisk/book/users01.dbf

--//419438592-8192 = 419430400
--//419430400/1024/1024 = 400,資料檔案大小400M。

419430400/8192 = 51200
51200 = 0xc800

--//對比另外的檔案:
$ ls -l /mnt/ramdisk/book/tea01.dbf
-rw-r----- 1 oracle oinstall 41951232 2020-12-18 08:46:21 /mnt/ramdisk/book/tea01.dbf
--//40*1024*1024+8192 = 41951232,建立資料檔案大小40M。

$ od  -j 0 -N 8192 -t x1  /mnt/ramdisk/book/tea01.dbf
0000000 00 a2 00 00 00 00 c0 ff 00 00 00 00 00 00 00 00
0000020 66 ee 00 00 00 20 00 00 00 14 00 00 7d 7c 7b 7a
                                ~~~~~~~~~~~
0000040 a0 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0020000

$ od  -A d -j 0 -N 8192 -t x1  /mnt/ramdisk/book/tea01.dbf
0000000 00 a2 00 00 00 00 c0 ff 00 00 00 00 00 00 00 00
0000016 66 ee 00 00 00 20 00 00 00 14 00 00 7d 7c 7b 7a
0000032 a0 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0008192

--//40*1024*1024/8192 = 5120
--//5120 = 0x1400
--//對比大概就可以知道主要差異就是在這裡,偏移在下劃線位置0x24-0x27.
--// 8192 = 0x2000,可以猜測0x20-0x21
--//0x16-0x17是校驗和。
--//0x28-0x31是用來標識資料檔案的特殊串,我自己這樣認為的。

--//實際上這些並不重要,如果os檔案頭損壞,很簡單你只要建立相同大小的資料檔案塊大小選擇一致,使用它覆蓋原來的os頭就ok了。

3.嘗試建立一個資料檔案看看。
--//抽取資料檔案的定義。
CREATE TABLESPACE TEA DATAFILE
  '/mnt/ramdisk/book/tea01.dbf' SIZE 40M AUTOEXTEND ON NEXT 1M MAXSIZE UNLIMITED
LOGGING
ONLINE
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT MANUAL
FLASHBACK ON;

--//建立一個類似的資料檔案大小一樣就ok了。我特意建立大小一樣塊大小一樣,其它引數不一致的情況。
CREATE TABLESPACE sugar DATAFILE
  '/mnt/ramdisk/book/sugar01.dbf' SIZE 40M AUTOEXTEND ON NEXT 2M MAXSIZE 80M
LOGGING
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT AUTO
FLASHBACK ON;

SCOTT@book> select * from v$dbfile;
     FILE# NAME
---------- ----------------------------------------
         6 /mnt/ramdisk/book/tea01.dbf
         5 /mnt/ramdisk/book/example01.dbf
         4 /mnt/ramdisk/book/users01.dbf
         3 /mnt/ramdisk/book/undotbs01.dbf
         2 /mnt/ramdisk/book/sysaux01.dbf
         1 /mnt/ramdisk/book/system01.dbf
         7 /mnt/ramdisk/book/sugar01.dbf
7 rows selected.

$ od  -A d -j 0 -N 8192 -t x1  /mnt/ramdisk/book/sugar01.dbf
0000000 00 a2 00 00 00 00 c0 ff 00 00 00 00 00 00 00 00
0000016 66 ee 00 00 00 20 00 00 00 14 00 00 7d 7c 7b 7a
0000032 a0 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0008192

$ od  -A d -j 0 -N 8192 -t x1  /mnt/ramdisk/book/tea01.dbf
0000000 00 a2 00 00 00 00 c0 ff 00 00 00 00 00 00 00 00
0000016 66 ee 00 00 00 20 00 00 00 14 00 00 7d 7c 7b 7a
0000032 a0 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0008192

--//對比完成一致。

$ diff -Nur <(od  -A d -j 0 -N 8192 -t x1  /mnt/ramdisk/book/tea01.dbf )  <(od  -A d -j 0 -N 8192 -t x1  /mnt/ramdisk/book/sugar01.dbf )
--//diff對比就可以說明問題。

4.這樣修復os頭非常簡單,這樣使用新建立的資料檔案os頭覆蓋原來的位置就ok了。

--//測試:
$ dd if=/dev/zero of=/mnt/ramdisk/book/users01.dbf count=1 bs=8192  conv=notrunc
1+0 records in
1+0 records out
8192 bytes (8.2 kB) copied, 3.8125e-05 seconds, 215 MB/s

--//再次說明,測試使用dd要小心小心再小心,輸入輸出檔案不要搞錯,另外特別注意要加上 conv=notrunc,不然
--//mnt/ramdisk/book/users01.dbf檔案會被截斷。
--//另外注意我並沒有選擇/mnt/ramdisk/book/tea01.dbf作為測試物件!!這樣主要目的是為了驗證不同與原來的os頭會出現什麼情況。

SYS@book> shutdown abort
ORACLE instance shut down.

SYS@book> startup
ORACLE instance started.

Total System Global Area  643084288 bytes
Fixed Size                  2255872 bytes
Variable Size             205521920 bytes
Database Buffers          427819008 bytes
Redo Buffers                7487488 bytes
Database mounted.
ORA-01157: cannot identify/lock data file 4 - see DBWR trace file
ORA-01110: data file 4: '/mnt/ramdisk/book/users01.dbf'

--//檢視對應轉儲檔案:
DDE: Problem Key 'ORA 1110' was flood controlled (0x1) (no incident)
ORA-01110: data file 4: '/mnt/ramdisk/book/users01.dbf'
ORA-01157: cannot identify/lock data file 4 - see DBWR trace file
ORA-01110: data file 4: '/mnt/ramdisk/book/users01.dbf'

$ dbv file=/mnt/ramdisk/book/users01.dbf
DBVERIFY: Release 11.2.0.4.0 - Production on Fri Dec 18 10:50:14 2020
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
DBV-00107: Unknown header format (0) (0)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SYS@book> alter database datafile 4 offline ;
Database altered.

$ dd if=/mnt/ramdisk/book/sugar01.dbf of=/mnt/ramdisk/book/users01.dbf count=1 bs=8192  conv=notrunc
1+0 records in
1+0 records out
8192 bytes (8.2 kB) copied, 3.989e-05 seconds, 205 MB/s
--//再次提醒使用dd要小心。注意檔案大小不一致。

$ dbv file=/mnt/ramdisk/book/users01.dbf
DBVERIFY: Release 11.2.0.4.0 - Production on Fri Dec 18 10:52:39 2020
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
DBVERIFY - Verification starting : FILE = /mnt/ramdisk/book/users01.dbf
DBVERIFY - Verification complete
Total Pages Examined         : 5120
Total Pages Processed (Data) : 3782
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 739
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 582
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 17
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Total Pages Encrypted        : 0
Highest block SCN            : 423619826 (3.423619826)

SYS@book> alter database open ;
alter database open
*
ERROR at line 1:
ORA-01113: file 4 needs media recovery
ORA-01110: data file 4: '/mnt/ramdisk/book/users01.dbf'

SYS@book> recover datafile 4;
Media recovery complete.

SYS@book> alter database open ;
Database altered.

SYS@book> select * from scott.dept where rownum=1;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
--//可以發現並沒有出現問題,注意現在os頭看到的大小是40M。

$ od  -A d -j 0 -N 8192 -t x1  /mnt/ramdisk/book/users01.dbf
0000000 00 a2 00 00 00 00 c0 ff 00 00 00 00 00 00 00 00
0000016 66 ee 00 00 00 20 00 00 00 14 00 00 7d 7c 7b 7a
0000032 a0 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0008192

SYS@book> alter database datafile '/mnt/ramdisk/book/users01.dbf' resize 300m;
Database altered.

$ od  -A d -j 0 -N 8192 -t x1  /mnt/ramdisk/book/users01.dbf
0000000 00 a2 00 00 00 00 c0 ff 00 00 00 00 00 00 00 00
0000016 66 6c 00 00 00 20 00 00 00 96 00 00 7d 7c 7b 7a
0000032 a0 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0008192

--//300*1024*1024/8192 = 38400
--//38400 = 0x9600,大小可以對上。

5.總結:
--//OS頭恢復相對容易,就是使用dd要小心,如果害怕錯誤,使用bvi直接修改就不錯的選擇,因為改動並不是很多。

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

相關文章