修復損壞的資料塊

楊奇龍發表於2010-06-10

 

bbed就是英文block browse block edit的縮寫,用來直接檢視和修改資料檔案資料的一個工具

在windows上提供工具dbv,在linux上面有,需要編譯:
make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
然後把$ORACLE_HOME/rdbms/lib加到環境變數的PATH裡面,就可以直接在命令中bbed了。
編譯好了就可以使用了,不過有個預設的口令blockedit。
執行bbed之前先要自己寫幾個配置檔案:
這裡有2個 a.txt par.bbd
[oracle@vm1 oracle]$ ls
a.txt bifile.bbd Desktop log.bbd par.bbd
[oracle@vm1 oracle]$ more a.txt
6 /u01/oracle/oradata/test/users01.dbf 26222592
2 /u01/oracle/oradata/test/users01.dbf.bak 26222592
[oracle@vm1 oracle]$ more par.bbd
blocksize=8192
listfile=a.txt
mode=edit


編好了就可以執行bbed了
[oracle@vm1 oracle]$ bbed parfile=par.bbd
Password: --這裡的密碼 blockedit
BBED: Release 2.0.0.0.0 - Limited Production on Wed Sep 14 16:18:31 200
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************

BBED>
先看看幫助,有那些命令:


BBED> help
HELP [ | ALL ]
BBED> help ALL
SET DBA [ dba | file#, block# ]
SET FILENAME 'filename'
SET FILE file#
SET BLOCK [+/-]block#
SET OFFSET [ [+/-]byte offset | symbol | *symbol ]
SET BLOCKSIZE bytes
SET LIST[FILE] 'filename'
SET WIDTH character_count
SET COUNT bytes_to_display
SET IBASE [ HEX | OCT | DEC ]
SET OBASE [ HEX | OCT | DEC ]
SET MODE [ BROWSE | EDIT ]
SET SPOOL [ Y | N ]
SHOW [ | ALL ]
INFO
MAP[/v] [ DBA | FILENAME | FILE | BLOCK ]
DUMP[/v] [ DBA | FILENAME | FILE | BLOCK | OFFSET | COUNT ]
PRINT[/x|d|u|o|c] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
EXAMINE[/Nuf] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
:
N - a number which specifies a repeat count.
u - a letter which specifies a unit size:
b - b1, ub1 (byte)
h - b2, ub2 (half-word)
w - b4, ub4(word)
r - Oracle table/index row
f - a letter which specifies a display format:
x - hexadecimal
d - decimal
u - unsigned decimal
o - octal
c - character (native)
n - Oracle number
t - Oracle date
i - Oracle rowid

FIND[/x|d|u|o|c] numeric/character string [ TOP | CURR ]
COPY [ DBA | FILE | FILENAME | BLOCK ] TO [ DBA | FILE | FILENAME | BLOCK ]
MODIFY[/x|d|u|o|c] numeric/character string
[ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
ASSIGN[/x|d|u|o] =
: [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
: [ value | ]
SUM [ DBA | FILE | FILENAME | BLOCK ] [ APPLY ]
PUSH [ DBA | FILE | FILENAME | BLOCK | OFFSET ]
POP [ALL]
REVERT [ DBA | FILE | FILENAME | BLOCK ]
UNDO
HELP [ | ALL ]
VERIFY [ DBA | FILE | FILENAME | BLOCK ]
CORRUPT [ DBA | FILE | FILENAME | BLOCK ]
BBED>
<source>
<source>


還真不少,下面是幾個常用的:

set 設定當前的環境。
show 檢視當前的環境引數,跟sqlplus的同名命令類似。
dump 列出指定block的內容
find 在指定的block中查詢指定的字串,結果是顯示出字串,及其偏移量--offset,偏移量就是在block中的位元組數
modify 修改指定block的指定偏移量的值,可以線上修改。
copy 把一個block的內容copy到另一個block中
verify 檢查當前環境是否有壞塊
sum 計算block的checksum,modify之後block就被標識為壞塊,current checksum與reqired checksum不一致,sum命令可以計算出新的checksum並應用到當前塊。
undo 回滾當前的修改操作,如果手誤做錯了,undo一下就ok了,回到原來的狀態。
revert 回滾所有之前的修改操作,意思就是 undo all

下面做些實驗:

先建個表,插入1條資料。
[oracle@vm1 oracle]$ sqlplus
SQL*Plus: Release 9.2.0.4.0 - Production on Wed Sep 14 16:46:15 2005
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Enter user-name: / as sysdba
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
Wit the Partitioning option
JServer Release 9.2.0.4.0 - Production
SQL> create table haocp ( a varchar2(10)) tablespace users;
Table created.
SQL> insert into haocp values('a');
1 row created.
SQL> commit;
Commit complete.
SQL> select segment_name,file_id,block_id,blocks from dba_extents where segment_name = 'HAOCP';
SEGMENT_NAME        FILE_ID BLOCK_ID BLOCKS
----------------  ---------- ---------- ----------
HAOCP                 6       33       8

表存放在file 6 block 33 - 33+8 上面,這時先關閉資料庫,對users資料檔案作個cp。
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> SQL> exit
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production
[oracle@vm1 oracle]$
[oracle@vm1 test]$ pwd
/u01/oracle/oradata/test
[oracle@vm1 test]$ cp users01.dbf users01.dbf.bak
[oracle@vm1 test]$ sqlplus
SQL*Plus: Release 9.2.0.4.0 - Production on Wed Sep 14 16:56:30 2005
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Enter user-name: / as sysdba
Connected to an idle instance.
SQL> startup

ORACLE instance started.
Total System Global Area 185668648 bytes
Fixed Size 451624 bytes
Variable Size 117440512 bytes
Database Buffers 67108864 bytes
Redo Buffers 667648 bytes
Database mounted.
Database opened.
SQL>

重新啟動完資料庫,進入bbed
[oracle@vm1 oracle]$ ls

a.txt bifile.bbd Desktop log.bbd par.bbd
[oracle@vm1 oracle]$ pwd
/home/oracle
[oracle@vm1 oracle]$ bbed parfile=par.bbd
Password:
BBED: Release 2.0.0.0.0 - Limited Production on Wed Sep 14 17:06:24 2005
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED> set file 6
FILE# 6
BBED> show  FILE# 6  BLOCK# 1  OFFSET 0
DBA 0x01800001 (25165825 6,1)
FILENAME /u01/oracle/oradata/test/users01.dbf
BIFILE bifile.bbd
LISTFILE a.txt
BLOCKSIZE 8192
MODE Edit
EDIT Unrecoverable
IBASE Dec
OBASE Dec
WIDTH 80
COUNT 512
LOGFILE log.bbd
SPOOL No
BBED>
剛才建立的haocp表在file 6 blcok 33 - 33+8上面,用bbed看看36的內容
BBED> dump file 6 block 36
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 0 to 511 Dba:0x01800024
------------------------------------------------------------------------
06020000 24008001 9dcc0300 00000106 d3aa0000 01000000 4f190000 9bcc0300
00000000 02003200 21008001 07000a00 54000000 84238000 17000b00 01200000
9dcc0300 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00010100 ffff1400 931f7b1f 7b1f0000 0100931f 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<32 bytes per line>

BBED>
offset 偏移量 從 0 到 511 單位是位元組,資料塊是8k的,想看完全就要擴大offset的範圍
BBED> dump file 6 block 36 count 8200
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 0 to 8191 Dba:0x01800024
------------------------------------------------------------------------
06020000 24008001 9dcc0300 00000106 d3aa0000 01000000 4f190000 9bcc0300
00000000 02003200 21008001 07000a00 54000000 84238000 17000b00 01200000
9dcc0300 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00010100 ffff1400 931f7b1f 7b1f0000 0100931f 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
之間略
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 0000002c 01010161 01069dcc
<32 bytes per line>
BBED>
Offsets: 0 to 8191 1024 * 8 = 8192個位元組,正好8K。注意最後的幾個位元組中,有個61,這個就是表中的那條資料,驗證一下。
SQL> select * from haocp;
A
----------
a

SQL> select dump(a,1016) from haocp;

DUMP(A,1016)
--------------------------------------------------------------------------------
Typ=1 Len=1 CharacterSet=ZHS16GBK: 61
字元a對應的16進位制編碼是61。如果資料量大的話,可以用find命令查詢
BBED> help find
FIND[/x|d|u|o|c] numeric/character string [ TOP | CURR ]
BBED> set file 6
FILE# 6
BBED> set block 36  BLOCK# 36
BBED> find 97 curr
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
------------------------------------------------------------------------
6101069d cc
<32 bytes per line>
BBED> find /x 61 curr
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
-----------------------------------------------------------------------
6101069d cc
<32 bytes per line>
在find之前先設定想要查詢的 file 和 block,預設是十進位制的ascii編碼,/x 表示16進位制,find的結果顯示出offset,即字元出現的位置。
下面試試修改他,把a改成b。
BBED> help modify
MODIFY[/x|d|u|o|c] numeric/character string
[ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
BBED> modify 98 file 6 block 36 offset 8187
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
----------------------------------------------------------------------
6201069d cc
<32 bytes per line>
修改完了以後,由61變成62了,不過這時資料塊是損壞狀態,試一下。
BBED> verify
DBVERIFY - Verification starting
FILE = /u01/oracle/oradata/test/users01.dbf
BLOCK = 36
Block 36 is corrupt
***
Corrupt block relative dba: 0x01800024 (file 0, block 36)
Bad check value found during verification
Data in bad block -
type: 6 format: 2 rdba: 0x01800024
last change scn: 0x0000.0003cc9d seq: 0x1 flg: 0x06
consistency value in tail: 0xcc9d0601
check value in block header: 0xaad3, computed block checksum: 0x300
spare1: 0x0, spare2: 0x0, spare3: 0x0
***
DBVERIFY - Verification complete
Total Blocks Examined : 1
Total Blocks Processed (Data) : 0
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 1
Total Blocks Influx : 0
Total Blocks Marked Corrupt : 1
有1個塊被標識為損壞,從剛才備份的那個檔案覆蓋它。
BBED> copy file 2 block 36 to file 6 block 36
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 0 to 511 Dba:0x01800024
------------------------------------------------------------------------
06020000 24008001 9dcc0300 00000106 d3aa0000 01000000 4f190000 9bcc0300
00000000 02003200 21008001 07000a00 54000000 84238000 17000b00 01200000
9dcc0300 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00010100 ffff1400 931f7b1f 7b1f0000 0100931f 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<32 bytes per line>
從剛才關閉資料庫時cp的檔案中複製第36個塊來覆蓋當前的塊,覆蓋完了再檢查一下。
BBED> verify
DBVERIFY - Verification starting
FILE = /u01/oracle/oradata/test/users01.dbf
BLOCK = 36
DBVERIFY - Verification complete
Total Blocks Examined : 1
Total Blocks Processed (Data) : 1
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 0
Total Blocks Influx : 0
好了,看看8187的情況
BBED> dump file 6 block 36 offset 8187
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
------------------------------------------------------------------------
6101069d cc
<32 bytes per line>
是原來的61,也就是字元 a 。再次改過來,試試回滾的命令。
BBED> modify /x 62 file 6 block 36 offset 8187
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
----------------------------------------------------------------------
6201069d cc
<32 bytes per line>
BBED> undo
BBED> modify /x 61 filename '/u01/oracle/oradata/test/users01.dbf' block 36. offset 8187.
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024------------------------------------
6101069d cc
<32 bytes per line>
undo就相當於sqlplus裡面的 rollback 不過是回滾上一步,而不是所有操作。
下面試試revert,不過要重新登陸,因為revert是回滾這次登陸以來所有的操作。
BBED> dump file 6 block 36 offset 8187
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
------------------------------------------------------------------------
6101069d cc
<32 bytes per line>
BBED> modify /x 62 file 6 block 36 offset 8187
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
------------------------------------------------------------------------
6201069d cc
<32 bytes per line>
BBED> revert
All changes made in this session will be rolled back. Proceed? (Y/N) y
Reverted file '/u01/oracle/oradata/test/users01.dbf', block 36
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
BBED> dump file 6 block 36 offset 8187
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
------------------------------------------------------------------------
6101069d cc
<32 bytes per line>
個人感覺bbed主要用在資料庫恢復的時候,比如由於誤操作把資料庫的字典表的資訊改錯了,導致資料庫不能啟動了,此時用bbed在離線的情況下把字典表的值再改回來。使資料庫open。
用modify改完資料之後,block處於corrupt狀態,所以要透過sum命令計算並應用checksum值,使block狀態恢復正常。
SQL> select * from haocp;
A
----------
a
BBED> dump file 6 block 36 offset 8187
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
------------------------------------------------------------------------
6101069d cc
32 bytes per line>
BBED> modify /x 62 file 6 block 36 offset 8187
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /u01/oracle/oradata/test/users01.dbf (6)
Block: 36 Offsets: 8187 to 8191 Dba:0x01800024
------------------------------------------------------------------------
6201069d cc
<32 bytes per line>
BBED> verify
DBVERIFY - Verification starting
FILE = /u01/oracle/oradata/test/users01.dbf
BLOCK = 36
Block 36 is corrupt
***
Corrupt block relative dba: 0x01800024 (file 0, block 36)
Bad check value found during verification
Data in bad block -
type: 6 format: 2 rdba: 0x01800024
last change scn: 0x0000.0003cc9d seq: 0x1 flg: 0x06
consistency value in tail: 0xcc9d0601
check value in block header: 0xaad3, computed block checksum: 0x300
spare1: 0x0, spare2: 0x0, spare3: 0x0
***
DBVERIFY - Verification complete
Total Blocks Examined : 1
Total Blocks Processed (Data) : 0
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 1
Total Blocks Influx : 0
修改完之後block的狀態是corrupt的。用sum命令使之有效。
BBED> help sum
SUM [ DBA | FILE | FILENAME | BLOCK ] [ APPLY ]
BBED> sum file 6 block 36
Check value for File 6, Block 36:
current = 0xaad3, required = 0xa9d3
此時 current checksum 是0xaad3,required checksum 是 0xa9d3
BBED> sum file 6 block 36 apply
Check value for File 6, Block 36:
current = 0xa9d3, required = 0xa9d3
加上apply引數,使checksum一致。此時block狀態恢復正常。
BBED> verify
DBVERIFY - Verification starting
FILE = /u01/oracle/oradata/test/users01.dbf
BLOCK = 36
DBVERIFY - Verification complet
Total Blocks Examined : 1
Total Blocks Processed (Data) : 1
Total Blocks Failing (Data) : 0
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 0
Total Blocks Influx : 0
看看資料庫的資料
SQL> select * from haocp;
A
----------
a

還是 a ,重啟一下。

SQL> startup force
ORACLE instance started.
Total System Global Area 185668648 bytes
Fixed Size 451624 bytes
Variable Size 117440512 bytes
Database Buffers 67108864 bytes
Redo Buffers 667648 bytes
Database mounted.
Database opened.
SQL> select * from haocp;
A
----------
b

 

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

相關文章