ORA-01578 壞塊原因模擬及解決方法
原創轉載起註明出處
我們可能有時候會遇到如下錯誤
一、錯誤展示
SQL> select * from test123;
select * from test123
ORA-01578: ORACLE data block corrupted (file # 1, block # 61658)
ORA-01110: data file 1: '/oracle_ocfs/oradata/pprac/system01.dbf'
二、原因
這樣的情況下可能是因為底層的硬體問題引起的,在進行讀物理磁碟資料塊的時候會進行物理一致性校驗,也就是會計算上次寫入磁碟的
時候的校驗和和這次讀取時候的校驗和是否相同,不同則出現錯誤1578,引數db_block_checksum來控制這個功能10G預設是TRUE也就是對
所有檔案進行校驗如果設定為FALSE就是隻對SYSTEM檔案進行校驗。當然還涉及到邏輯檢驗,但是這個錯誤是物理檢驗出錯引起的。
三、校驗工具
而我們有那些方法進行資料檔案進行壞塊校驗哪?
1、DBV工具
命令和結果如下
[oracle@b000-vmracdb1 lib]$ dbv file=/oracle_ocfs/oradata/pprac/system01.dbf
DBVERIFY: Release 10.2.0.1.0 - Production on Mon Aug 9 16:43:53 2010
Copyright (c) 1982, 2005, Oracle. All rights reserved.
DBVERIFY - Verification starting : FILE = /oracle_ocfs/oradata/pprac/system01.dbf
Page 61658 is marked corrupt
Corrupt block relative dba: 0x0040f0da (file 1, block 61658)
Bad check value found during dbv:
Data in bad block:
type: 6 format: 2 rdba: 0x0040f0da
last change scn: 0x0000.00d056c1 seq: 0x1 flg: 0x06
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0x56c10601
check value in block header: 0x6988
computed block checksum: 0xde02
DBVERIFY - Verification complete
Total Pages Examined : 64000
Total Pages Processed (Data) : 38268
Total Pages Failing (Data) : 0
Total Pages Processed (Index): 7142
Total Pages Failing (Index): 0
Total Pages Processed (Other): 1901
Total Pages Processed (Seg) : 0
Total Pages Failing (Seg) : 0
Total Pages Empty : 16688
Total Pages Marked Corrupt : 1
Total Pages Influx : 0
Highest block SCN : 13691243 (0.13691243)
這裡Total Pages Marked Corrupt : 1說明有了壞塊
2、RMAN工具
使用命令
backup check logical validate database;
同時對物理和邏輯進行校驗
然後我們可以檢視檢視v$database_block_corruption,結果如下
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTION_TYPE
---------- ---------- ---------- ------------------ ---------------
1 61658 1 0 CHECKSUM
3、ANALYZE命令
命令是:ANALYZE TABLE TEST123 VALIDATE STRUCTURE CASCADE ONLINE;
四、模擬錯誤
為了試驗我們使用BBED工具進行模擬,千萬不要用這個工具在生產上玩哦。同時要建立一個表如下:
create table test123
(id number,name char(2000));
然後插入資料我的資料如下:
ID NAME
---------- --------------------------------------------------------------------------------
1 test
2 test2
3 test3
4 test4
5 test5
6 test6
7 test7
8 test8
9 test9
10 test10
然後確定檔案號和資料塊好如下:
SQL> select dbms_rowid.rowid_relative_fno(rowid) file_num,
2 dbms_rowid.rowid_block_number(rowid) block_num,id,name from test123;
FILE_NUM BLOCK_NUM ID NAME
---------- ---------- ---------- --------------------------------------------------------------------------------
1 61658 1 test
1 61658 2 test2
1 61658 3 test3
1 61659 4 test4
1 61659 5 test5
1 61659 6 test6
1 61660 7 test7
1 61660 8 test8
1 61660 9 test9
1 61661 10 test10
這裡我準備用1,61658來試驗
下面使用BBED來進行模擬錯誤:
(1)安裝BBED目錄在$ORACLE_HOME/rdbms/lib下面使用make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed來進行編譯
(2)編寫引數檔案bbed.par如下:
[oracle@b000-vmracdb1 lib]$ more bbed.par
blocksize=8192
listfile=list
mode=edit
(3)編寫list檔案,裡面放資料檔案列表如下:
[oracle@b000-vmracdb1 lib]$ more list
1 /oracle_ocfs/oradata/pprac/system01.dbf
2 /oracle_ocfs/oradata/pprac/undotbs01.dbf
3 /oracle_ocfs/oradata/pprac/sysaux01.dbf
4 /oracle_ocfs/oradata/pprac/users01.dbf
5 /oracle_ocfs/oradata/pprac/example01.dbf
6 /oracle_ocfs/oradata/pprac/undotbs02.dbf
(4)進入BBED使用命令
bbed parfile=bbed.par 密碼就是blockedit
[oracle@b000-vmracdb1 lib]$ /home/oracle/product/database/rdbms/lib/bbed parfile=bbed.par
Password:
BBED: Release 2.0.0.0.0 - Limited Production on Mon Aug 9 16:52:31 2010
Copyright (c) 1982, 2005, Oracle. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED>
(5)找到塊命令SET
BBED> set dba 1,61658
DBA 0x0040f0da (4255962 1,61658)
(6)我們來找到以test為開頭的記錄
BBED> find /c test
File: /oracle_ocfs/oradata/pprac/system01.dbf (1)
Block: 61658 Offsets: 2170 to 2681 Dba:0x0040f0da
------------------------------------------------------------------------
74657374 33202020 20202020 20202020 20202020 20202020 20202020 20202020
20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020
20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020
。。。。。。
這裡看到了第一個test偏移量2170,這個也就是說相對整個塊的一個位置,我也沒有深究。
然後找到他
BBED> dump /v dba 1,61658 offset 2170 count 64
File: /oracle_ocfs/oradata/pprac/system01.dbf (1)
Block: 61658 Offsets: 2170 to 2233 Dba:0x0040f0da
-------------------------------------------------------
74657374 33202020 20202020 20202020 l test3
20202020 20202020 20202020 20202020 l
20202020 20202020 20202020 20202020 l
20202020 20202020 20202020 20202020 l
<16 bytes="" per="" line="">
看到了是test123
然後找下一個
BBED> f
File: /oracle_ocfs/oradata/pprac/system01.dbf (1)
Block: 61658 Offsets: 4179 to 4242 Dba:0x0040f0da
------------------------------------------------------------------------
74657374 32202020 20202020 20202020 20202020 20202020 20202020 20202020
20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020
<32 bytes="" per="" line="">
偏移量4179
BBED> dump /v dba 1,61658 offset 4179 count 64
File: /oracle_ocfs/oradata/pprac/system01.dbf (1)
Block: 61658 Offsets: 4179 to 4242 Dba:0x0040f0da
-------------------------------------------------------
74657374 32202020 20202020 20202020 l test2
20202020 20202020 20202020 20202020 l
20202020 20202020 20202020 20202020 l
20202020 20202020 20202020 20202020 l
同樣也找到了
在往下還有test能找到,但是我這裡已經被我修改了,找不到了。
然後我們修改,弄壞資料塊
modify 1000 dba 1,61658 這裡是修改的偏移量就是最後找到的TEST*的偏移量我改是test
修改完成後這個塊就壞了。
但是這裡注意由於DB_CACHE_BUFFER的原因會快取資料塊,即使修改了讀取的時候從SGA讀出來的話也不報錯
需要清空BUFFER或者重啟下,不要讓資料庫快取記憶體快取資料塊。
然後我們
SQL> select * from test123 where id=1;
ID NAME
---------- --------------------------------------------------------------------------------
1 test
SQL> select * from test123;
select * from test123
ORA-01578: ORACLE data block corrupted (file # 1, block # 61658)
ORA-01110: data file 1: '/oracle_ocfs/oradata/pprac/system01.dbf'
錯誤就出來了。
五、如何解決
然後我們就是來解決這個問題,說實話如果是表的資料塊壞了真的沒有太多的辦法,只能先解救我們沒有
損壞塊的資料方法如下:
---有RMAN備份和歸檔的情況下:
這個比較簡單,使用命令
blockrecover datafile 1 block 61658;
就可以了,無需進行不完全恢復。
----沒RMAN備份和歸檔的情況下:
1、設定SKIP
SQL> begin
2 dbms_repair.skip_corrupt_blocks(schema_name => 'SYS',object_name => 'TEST123',object_type => DBMS_REPAIR.TABLE_OBJECT,flags => DBMS_REPAIR.SKIP_FLAG);
3 END;
4 /
也就是跳過損壞的塊。
2、檢視下是否是SKIP
SQL> select table_name,skip_corrupt from dba_tables where table_name='TEST123';
TABLE_NAME SKIP_CORRUPT
------------------------------ ------------
TEST123 ENABLED
3、再次檢視
SQL> select * from test123;
ID NAME
---------- --------------------------------------------------------------------------------
4 test4
5 test5
6 test6
7 test7
8 test8
9 test9
10 test10
木有了壞塊的資料已經沒有了。如果想恢復失去的資料,找找ORACLE SUPPORT,或者資料探勘,反正都是很麻煩的事情,而且不一定行。
當然如果是索引的壞就重建吧,這個沒事。
如下僅僅記錄一下處理壞塊需要的技術
未標記損壞塊時,未損壞的記錄還能透過RIWID讀出
backup validate database;
select * from v$database_block_corruption;
SELECT e.owner, e.segment_type, e.segment_name, e.partition_name, c.file#
, greatest(e.block_id, c.block#) corr_start_block#
, least(e.block_id+e.blocks-1, c.block#+c.blocks-1) corr_end_block#
, least(e.block_id+e.blocks-1, c.block#+c.blocks-1)
- greatest(e.block_id, c.block#) + 1 blocks_corrupted
, corruption_type description
FROM dba_extents e, v$database_block_corruption c
WHERE e.file_id = c.file#
AND e.block_id <= c.block# + c.blocks - 1
AND e.block_id + e.blocks - 1 >= c.block#
UNION
SELECT s.owner, s.segment_type, s.segment_name, s.partition_name, c.file#
, header_block corr_start_block#
, header_block corr_end_block#
, 1 blocks_corrupted
, corruption_type||' Segment Header' description
FROM dba_segments s, v$database_block_corruption c
WHERE s.header_file = c.file#
AND s.header_block between c.block# and c.block# + c.blocks - 1
UNION
SELECT null owner, null segment_type, null segment_name, null partition_name, c.file#
, greatest(f.block_id, c.block#) corr_start_block#
, least(f.block_id+f.blocks-1, c.block#+c.blocks-1) corr_end_block#
, least(f.block_id+f.blocks-1, c.block#+c.blocks-1)
- greatest(f.block_id, c.block#) + 1 blocks_corrupted
, 'Free Block' description
FROM dba_free_space f, v$database_block_corruption c
WHERE f.file_id = c.file#
AND f.block_id <= c.block# + c.blocks - 1
AND f.block_id + f.blocks - 1 >= c.block#
order by file#, corr_start_block#;
execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('SYS','TESTER',flags=>dbms_repair.skip_flag);
execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('SYS','TESTER',flags=>dbms_repair.noskip_flag);
11GR2
backup validate database;
RECOVER CORRUPTION LIST;
DRA 11G
backup validate database;
list failure;
advise failure;
repair failure preview;
repair failure;
可以使用下面語法代替RECOVER CORRUPTION LIST;11R2以前
run {blockrecover corruption list;}
修復單塊
blockrecover datafile 1 block 61658;
ROWID_CREATE函式
function ROWID_CREATE(rowid_type IN number,
object_number IN number,
relative_fno IN number,
block_number IN number,
row_number IN number)
return ROWID;
如果是LOB塊的錯誤需要另外的處理的方式
http://blog.itpub.net/7728585/viewspace-1580285/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-670597/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ORA-01578壞塊解決方法
- EXP匯出ORA-01578(資料塊損壞)錯誤解決方法
- ORACLE壞塊(ORA-01578)處理方法Oracle
- ORACLE壞塊(ORA-01578)處理方法(zt)Oracle
- ORA-01578(資料塊損壞)跳過壞塊
- ANR原因及解決方法
- oracle壞塊模擬處理(筆記)Oracle筆記
- oracle 壞塊問題 ora-01578Oracle
- oracle壞塊問題及解決辦法Oracle
- ORA-01578(資料塊損壞)跳過壞塊處理辦法
- Oracle中模擬修復資料塊損壞Oracle
- DVR常見故障原因及解決方法VR
- 模擬oracle裡的各種型別的壞塊Oracle型別
- Windows變慢原因分析及解決方法(轉)Windows
- 壓敏電阻燒壞的原因後果及解決辦法
- 模擬壞塊故障並搶救資料(一.普通表)
- oracle壞塊問題的解決Oracle
- No input file specified 出現的原因及解決方法
- 執行期間丟擲NoSuchMethodError模擬及原因分析Error
- ORA-01578錯誤的解決方法 ( 二)
- [20150811]模擬壞塊處理.txt
- 網站內頁不收錄的原因及解決方法網站
- node版本升級npm命令警告原因及解決方法NPM
- DNS故障的幾種常見原因及解決方法DNS
- impdp操作產生大量UNDO的原因及解決方法
- CPU佔用100%原因及解決方法 轉載
- enq: TM - contention TM 等待事件的原因及模擬ENQ事件
- Linux中產生zombie的原因詳解及解決方法!Linux
- ORA-01578和ORA-26040--NOLOGGING操作引起的壞塊-錯誤解釋和解決方案
- 撥號VPS中691的可能原因及解決方法?
- axios傳送兩次請求原因及解決方法iOS
- 技術分享 | DNS解析不生效的原因及解決方法DNS
- u盤複製速度慢的原因及解決方法
- 資料庫連線失敗的原因及解決方法資料庫
- 資料庫連線錯誤的原因及解決方法資料庫
- 資料庫壞塊解決案例一則資料庫
- ORA-01114錯誤原因及解決方法(臨時表空間壞掉、或者滿了)
- Oracle 9i資料壞塊的處理(ORA-01578) ztOracle