處理一個數據庫壞塊的問題,處理過程紀錄如下:
1.根據報錯的信息,用dbv確認一下,是否真的文件有壞塊了,如果有,那繼續,用下面的SQL查詢出壞塊爲index還是數據,如果是索引,刪除重建即可,如果是數據,那麻煩了,還要進行下一步動作。
SELECT SEGMENT_NAME, SEGMENT_TYPE FROM DBA_EXTENTS
WHERE FILE_ID = <file_number> and <block_number> BETWEEN BLOCK_ID
AND BLOCK_ID + BLOCKS - 1
2.在做這一步之前,先對數據所在的表進行備份,比如exp或者create newtable等等方法,注意第二種方法要把索引,約束等都備份出來。如果運氣好的話,數據可以全部備份出來,那就簡單了,將原表刪除,重建,把數據弄進來即可;運氣不好的話,某些數據還在壞區上不能導出,那就要使用事件10231跳過壞區,把好的數據先弄出來。SQL如下:
ALTER SYSTEM SET EVENTS ‘10231 trace name context forever,level 10’
然後再create new table或者exp來導出數據,注意導出完畢後用下列SQL把這個診斷事件關閉。
ALTER SYSTEM SET EVENTS ''10231 trace name context off ''
3.步驟2運氣不好就有可能會丟失數據,要保證數據不丟失,有三個辦法:
A. 如果數據庫的archive是全的,那就拿出表所在的數據文件最近一次的備份,用dbv檢查一下,確認無壞塊後,用它來恢復正式庫的數據。步驟是"alter database datafile <file_name> offline"-->把壞的數據文件copy走-->拷貝備份文件過來-->"recover datafile <file_name>"-->"alter database datafile <file_name> online"。
B. 就是找負責AP的人員,根據表之間的數據關聯關係來把丟失的數據拼出來。
C. 如果你是9i的數據庫,用rman做的備份,rman中提供了一個指令,也可以從rman的備份中來恢復壞塊,恢復時數據庫可以是online的狀態。指令如下:
blockrecover datafile <file_number> block <block_number> from backupset;
4.其實上面的恢復動作也可作爲system表空間的恢復,如果是undo某一個段壞掉了,可以使用下面的步驟:
A. 先備份建立rollbacksegment 的腳本(特別是Dictionary方式),把監聽器停掉,所有的session斷開,看看v$transaction裏面有沒有活動的,如果有也刪除掉。
B. 把數據庫開在restrict模式下進行恢復,方法是嘗試重新建立undo表空間和回滾段,建立完成,把回滾段online。
C. 確定數據庫可以正常開啓後,把舊的回滾段offline掉,舊的表空間刪除。
如果說數據庫都打不開了,那就要使用備份的undo文件進行恢復,這樣丟失數據最小。另外oracle提供了一個隱含參數"_corrupted_rollback_segments=(被損壞的段名)",強制性的把數據庫打開,不過這時數據庫是在不一致的狀態下,打開後趕快做一個數據庫exp,重建數據庫並imp進去,否則這樣恢復的數據庫要使用的話會存在很大的風險。
寫了這麼多,我發現怎麼講壞塊給講到數據庫恢復裏面去了。其實說起來壞塊的處理只要備份工作做得好,還是挺容易解決的。大不了從備份中恢復一份出來,如果沒有備份,那就要看運氣了。
附: DBVERIFY工具的使用說明
DBVERIFY工具的主要目的是爲了檢查數據文件的物理結構,包括數據文件是否損壞,是否存在邏輯壞塊,以及數據文件中包含何種類型的數據。
DBVERIFY工具可以驗證ONLINE或OFFLINE的數據文件。不管數據庫是否打開,都可以訪問數據文件。
1.可以使用幫助查看dbv的命令參數
C:/>dbv help=y
DBVERIFY: Release 11.1.0.7.0 - Production on 星期二 12月 15 23:35:24 2009
Copyright (c) 1982, 2007, Oracle. All rights reserved.
關鍵字 說明 (默認值)
----------------------------------------------------
FILE 要驗證的文件 (無)
START 起始塊 (文件的第一個塊)
END 結束塊 (文件的最後一個塊)
BLOCKSIZE 邏輯塊大小 (8192)
LOGFILE 輸出日誌 (無)
FEEDBACK 顯示進度 (0)
PARFILE 參數文件 (無)
USERID 用戶名/口令 (無)
SEGMENT_ID 段 ID (tsn.relfile.block) (無)
HIGH_SCN 要驗證的最高塊 SCN (無)
(scn_wrap.scn_base 或 scn)
2.具體使用說明
DBVERIFY 驗證數據文件
FILE 輸入文件名
START 開始塊地址
END 結束塊地址
BLOCKSIZE 指定BLOCKSIZE尺寸
LOGFILE 指定LOG文件
FEEDBACK 進度顯示
HELP 幫助
PARFILE 參數文件
3. 簡單語法
3.1 dbv FILE=t_db1.dbf FEEDBACK=100
E:/app/Administrator/oradata/orcl>dbv file=users01.dbf blocksize=8192
DBVERIFY: Release 11.1.0.7.0 - Production on 星期二 12月 15 23:54:55 2009
Copyright (c) 1982, 2007, Oracle. All rights reserved.
DBVERIFY - 開始驗證: FILE = E:/app/Administrator/oradata/orcl/users01.dbf
DBVERIFY - 驗證完成
檢查的頁總數: 640
處理的頁總數 (數據): 91
失敗的頁總數 (數據): 0
處理的頁總數 (索引): 33
失敗的頁總數 (索引): 0
處理的頁總數 (其它): 496
處理的總頁數 (段) : 0
失敗的總頁數 (段) : 0
空的頁總數: 20
標記爲損壞的總頁數: 0
流入的頁總數: 0
加密的總頁數 : 0
最高塊 SCN : 904088 (0.904088)
注意目錄,要進入數據文件的存放目錄後在運行該命令,不然會報找不到數據文件。
3.2 DBV工具還有一種在數據庫打開的情況下使用的,驗證指定段的用法:
dbv USERID=username/password SEGMENT_ID=tsn.relfile.block
DBVERIFY驗證段
USERID 指定用戶名和密碼
SEGMENT_ID 指定驗證的段
LOGFILE 指定LOG文件
FEEDBACK 進度顯示
HELP 幫助
PARFILE 參數文件
這種方法需要查詢表空間ID、段頭所在的數據文件ID和以及段頭所在表空間ID,要獲取這個信息可以通過SYS用戶查詢SYS_DBA_SEGS視圖。需要注意的是,Oracle文檔給出的SYS_USER_SEGS視圖只能查詢SYS用戶的段,要查詢普通用戶的段信息,需要訪問SYS_DBA_SEGS。
ITPUB個人空間|*Ed
--------------------------------------------------------------------------------
B+pNj)_
SQL> create table DAVE (ID number);
表已創建。
SQL> SELECT TABLESPACE_ID, HEADER_FILE, HEADER_BLOCK FROM SYS_DBA_SEGS WHERE SEGMENT_NAME = 'DAVE';
TABLESPACE_ID HEADER_FILE HEADER_BLOCK
------------- ----------- ------------
0 1 89976
E:/app/Administrator/oradata/orcl>dbv userid=system/admin segment_id=0.1.89976
DBVERIFY: Release 11.1.0.7.0 - Production on 星期三 12月 16 00:19:02 2009
Copyright (c) 1982, 2007, Oracle. All rights reserved.
DBVERIFY - 開始驗證: SEGMENT_ID = 0.1.89976
DBVERIFY - 驗證完成
檢查的頁總數: 9
處理的頁總數 (數據): 0
失敗的頁總數 (數據): 0
處理的頁總數 (索引): 0
失敗的頁總數 (索引): 0
處理的頁總數 (其它): 9
處理的總頁數 (段) : 0
失敗的總頁數 (段) : 0
空的頁總數: 0
標記爲損壞的總頁數: 0
流入的頁總數: 0
加密的總頁數 : 0
最高塊 SCN : 912858 (0.912858)
注:這種方式要求數據庫處於打開的狀態。
4. 驗證數據拷貝
由於dbv可以在實例關閉情況下驗證數據文件,因此dbv也可以驗證數據文件的拷貝。這個拷貝指的是通過RMAN的COPY命令或者操作系統命令cp拷貝的數據文件,而不是RMAN生成的備份集格式。
--------------------------------------------------------------------------------
E:/app/Administrator/oradata/orcl>dbv file= USERS01bak.DBF blocksize=8192
DBVERIFY: Release 11.1.0.7.0 - Production on 星期三 12月 16 00:30:17 2009
Copyright (c) 1982, 2007, Oracle. All rights reserved.
DBVERIFY - 開始驗證: FILE = E:/app/Administrator/oradata/orcl/USERS01bak.DBF
DBVERIFY - 驗證完成
檢查的頁總數: 640
處理的頁總數 (數據): 91
失敗的頁總數 (數據): 0
處理的頁總數 (索引): 33
失敗的頁總數 (索引): 0
處理的頁總數 (其它): 496
處理的總頁數 (段) : 0
失敗的總頁數 (段) : 0
空的頁總數: 20
標記爲損壞的總頁數: 0
流入的頁總數: 0
加密的總頁數 : 0
最高塊 SCN : 904088 (0.904088)
一些注意事項:
1. 對於DBVERIFY工具,高版本可以自動識別低版本數據庫,比如11g的dbv訪問9i的數據庫,但是低版本的dbv訪問高版本會報如下之類的錯誤:
DBVERIFY -驗證正在開始: FILE = e:/oracle/oradata/Dave/test01.dbf
匯入的頁1 -可能是介質損壞
2. 查看數據壞塊所在數據文件號及塊號可以對錶進行一次全表掃描,如:
select count(*) from tablename;
如果有壞塊, 在掃描的時候就會報錯