Oracle壞塊處理
有時Oracle資料檔案的損壞只是一小部分塊:檔案仍可用,但特定塊被損壞。這種情況下,檔案將保持聯機,終端使用者可能不知道存在的問題,直到讀取到壞塊時才會發現。如果一個會話命中一個壞塊,它將返回錯誤給使用者程式,同時將一條訊息寫入警報日誌。
一、壞塊的檢測
1、警告日誌可以看到壞塊
ORA-01578:壞塊錯誤
2、透過兩個初始化引數實時監測壞塊
db_block_checking:預設false,塊內資料的邏輯一致性檢查,效能負荷較大
show parameter db_block_checking;
true:讀寫時都檢查
flase:除system表空間塊外不檢查
low:改變的資料
medium:檢查索引組織表
full:全部檢查
db_block_checksum:預設typical,檢查記憶體和硬碟塊資料是否一致,效能負荷不大
show parameter db_block_checksum;
typical(true):DBWn寫盤時會計算一個稱為檢驗和checksum的值,儲存在block的頭部。讀取該塊時將校驗checksum值。
full:除typical外,在update/delete前校驗checksum,並在變化後重新計算checksum,另會計算記憶體中的塊損壞並阻止寫入磁碟。
off(false):正常情況下,Oracle會對每個日誌的block計算checksum,如果設為off,則只計算system表空間的checksum。
3、RMAN檢測壞塊
RMAN在執行備份操作時會自動檢測壞塊,預設當命中壞塊時立即終止備份操作。如果需要,可設定對壞塊容錯度的RMAN備份,則在備份過程中命中壞塊時將繼續備份,但會在其儲存庫中記錄發現的壞塊。以下示例將壞塊容錯度設為10,只要遇到的壞塊不超過10個,備份將繼續進行
RMAN> run {
set maxcorrupt for datafile 7 to 10;
backup datafile 7;
}
在正常執行中,將不使用set maxcorrupt關鍵字,遇到壞塊時,備份將失敗,使用者立即知道錯誤。然後用set maxcorrupt再次執行備份,完成後可查詢以下幾個檢視確定塊損壞範圍
v$database_block_corruption:記錄壞塊所在的位置,包括資料檔案號和塊編號等資訊。
v$backup_corruption:針對備份集備份遇到的壞塊統計。
v$copy_corruption:針對映像副本備份遇到的壞塊統計。
預設情況下,RMAN總是檢查物理損壞,也就是非RMAN中的介質損壞。也可讓RMAN檢查邏輯損壞,即軟體損壞。要改寫備份的預設值,可使用nochecksum和check logical關鍵字。
不檢查資料檔案物理損壞的備份
RMAN> backup nochecksum datafile 4;
檢查資料檔案邏輯損壞(包括物理損壞)的備份
RMAN> backup check logical datafile 4;
若使用validate關鍵字,則可在要進行的備份物件上執行塊損壞檢查,但不會執行實際的備份操作。
檢查資料檔案的物理損壞
RMAN> backup validate datafile 4;
檢查資料檔案物理損壞和邏輯損壞
RMAN> backup validate check logical datafile 4;
4、dbverify工具檢測壞塊
針對資料檔案檢查壞塊,無論檔案聯機或離線,資料庫開啟或關閉都可以,預設塊大小8192
dbv file=/home/oracle/app/oracle/oradata/mes/cmes01.dbf [blocksize=...]
5、其它工具檢查
備份工具exp或expdp在做資料匯出時會檢查是否存在壞塊,遭遇壞塊時匯出會終止,並提示ORA-01578錯誤。如果損壞的塊是索引,通常可以透過重建索引來解決。如果損壞的塊是資料,可以透過設定如下內部事件使exp操作跳過壞塊
alter system set events='10231 trace name context forever,level 10';
之後重新執行匯出命令,匯出相關的表,然後執行drop table命令將表刪除,再重建表並匯入資料。
禁用壞塊跳過
alter system set events='10231 trace name context off';
analyze命令也會對錶和索引的物理儲存執行檢查,該指令更新表或索引的後設資料,同時也可以進行壞塊的檢查,但不會將已損壞的塊標記為corrupt,檢測結果輸出在user_dump_dest目錄下的使用者trace檔案中。如:
analyze table tablename validate structure cascade;
analyze index indexname validate structure;
Oracle提供的PL/SQL程式包dbms_repair也可以檢查和處理表和索引中出現的壞塊問題,包括標記和跳過壞塊。
二、RMAN塊介質恢復
塊介質恢復(BMR,Block Media Recovery)將還原和恢復操作的粒度從資料檔案改為塊。與檔案還原和恢復相比,檔案不必離線,正常DML可以繼續,恢復的時間也大大減少,因為操作只涉及到受損的塊,而不是整個檔案。
BMR機制給RMAN提供一個需要恢復的一個或多個塊的列表。RMAN將從備份集或映像副本中提取這些塊的備份並寫入資料檔案。然後,RMAN將遍歷自備份後生成的歸檔日誌,提取與還原塊相關的重做記錄並應用它們。恢復將是完整的,邏輯上不可能執行不完整恢復,只對一個塊進行不完整恢復將使資料庫處於不一致的狀態。如果使用者會話在BMR過程完成之前命中到壞塊,將仍會接收到ORA-01578的壞塊錯誤,但也可能BMR操作將在使用者發現問題前完成。
RMAN使用blockrecover命令來進行塊介質恢復。以下命令將指定要還原和恢復的一個或多個塊的列表
RMAN> blockrecover datafile 7 block 5;
可以同時指定多個資料檔案和多個塊
RMAN> blockrecover datafile 7 block 5, 6, 7 datafile 9 block 21, 25;
可能會有對備份本身完整性的懷疑,那麼可明確指示RMAN從已知是好的備份中還原和恢復塊。如指定要提取的備份集編號,或者指定TAG標記
RMAN> blockrecover datafile 7 block 5 from backupset 12;
RMAN> blockrecover datafile 7 block 5 from tag TAG20151114T173349;
如果損壞範圍較大,BMR的另外兩個選項可簡化此過程:
其一,假定已在RMAN備份過程中透過設定maxcorrupt最大壞塊數量填充了檢視v$database_block_corruption,那麼使用corruption list選項將指示RMAN還原和恢復檢視中的每一個塊
RMAN> blockrecover corruption list;
其二,使用until選項可指定要還原的備份來自於發生損壞前的一個時間點。如以下將指示RMAN從至少一週前的備份中還原和恢復在前一次備份時發現的每個壞塊
RMAN> blockrecover corruption list until time sysdate - 7;
另外還有透過指定損壞資料塊的DBA(data block address)來恢復
blockrecover tablespace blocktbs dba 41943172;
塊地址根據檔案號和塊號可以查詢得到
select dbms_utility.make_data_block_address(file#, block#) from dual;
反過來根據資料塊地址也能查詢到檔案號和塊號
select dbms_utility.data_block_address_file(dba#) file#, dbms_utility.data_block_address_block(dba#) block# from dual;
執行完blockrecover塊恢復命令後,在開啟資料庫前可能還需要對資料檔案進行介質恢復
recover datafile 7;
三、壞塊恢復實驗
恢復是建立在歸檔日誌模式且有備份的前提下的,因此實驗前應確認當前為歸檔模式
archive log list;
建表空間
create tablespace blocktbs datafile '/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf' size 4m;
建測試使用者
create user u1 identified by u1 default tablespace blocktbs;
grant connect, resource to u1;
建表
create table u1.blocktab(a number, b varchar2(30));
插入模擬資料
declare
len number;
begin
for i in 1..1000 loop
len:=trunc(dbms_random.value(1, 30));
insert into u1.blocktab values(i, dbms_random.string('a', len));
end loop;
commit;
end;
/
檢視錶所在的檔案和資料塊
select distinct dbms_rowid.rowid_relative_fno(rowid) file#, dbms_rowid.rowid_block_number(rowid) block# from u1.blocktab order by 2;
FILE# BLOCK#
---------- ----------
10 132
10 133
10 134
10 135
檢視每個資料塊擁有的記錄數
select dbms_rowid.rowid_block_number(rowid) block#, count(*) block_records from u1.blocktab group by dbms_rowid.rowid_block_number(rowid) order by 1;
BLOCK# BLOCK_RECORDS
---------- -------------
132 304
133 287
134 295
135 114
以上操作顯示,表blocktab中插入了1000條測試資料,共佔用4個資料塊,每個資料塊填滿(保持pctfree空閒)大約容納近300條記錄。
備份資料檔案
rman target /
backup datafile 10;
計算第132號資料塊的大概位置
show parameters db_block_size;
NAME TYPE VALUE
--------------------------------- --------- ----------
db_block_size integer 8192
select to_char(132*8192,'xxxxxx') from dual;
TO_CHAR(132*8192,'XXX
---------------------
108000
用二進位制文字編輯器開啟10#檔案,找到地址108000位置後的資料,手動編輯修改,模擬壞塊
vim -b /home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
檔案將以二進位制形式開啟,用:%!xxd指令可顯示為十六進位制狀態,編輯後可用:%!xxd -r指令回到二進位制顯示狀態,最後用:wq儲存。
也可以用dd命令向指定塊寫入資料來模擬壞塊
dd if=/dev/zero of=/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf bs=8192 count=1 seek=132 conv=notrunc
重新整理資料庫快取
alter system flush buffer_cache;
再次查詢表
select count(*) from u1.blocktab;
提示壞塊錯誤
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 10, block # 132)
ORA-01110: data file 10: '/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf'
用RMAN檢查此檔案壞塊
RMAN> backup validate check logical datafile 10;
Starting backup at 05-MAY-18
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=6 device type=DISK
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00010 name=/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
10 FAILED 0 377 512 3433950
File Name: /home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 4
Index 0 0
Other 1 131
validate found one or more corrupt blocks
See trace file /home/oracle/app/oracle/diag/rdbms/mes/mes/trace/mes_ora_7842.trc for details
Finished backup at 05-MAY-18
根據塊損壞情況,若提示檔案壞已不能訪問,則v$database_block_corruption中沒有記錄,如果RMAN還能夠訪問並檢查,則會在該檢視中列出壞塊資訊。
select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTION_TYPE
---------- ---------- ---------- ------------------ ---------------------------
10 132 1 0 ALL ZERO
檢視損壞塊所涉及的資料庫物件
col tablespace_name for a20
col segment_name for a20
col segment_type for a20
col owner for a10
select tablespace_name, segment_type, owner, segment_name from dba_extents where file_id=10 and 132 between block_id and block_id+blocks-1;
TABLESPACE_NAME SEGMENT_TYPE OWNER SEGMENT_NAME
-------------------- -------------------- ---------- --------------------
BLOCKTBS TABLE U1 BLOCKTAB
查詢10#資料檔案的RMAN備份
RMAN> list backup of datafile 10;
List of Backup Sets
===================
BS Key Type LV Size Device Type Elapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ ---------------
91 Full 1.10M DISK 00:00:00 05-MAY-18
BP Key: 91 Status: AVAILABLE Compressed: NO Tag: TAG20180505T182704
Piece Name: /home/oracle/app/oracle/flash_recovery_area/MES/backupset/2018_05_05/o1_mf_nnndf_TAG20180505T182704_fgv1qrdp_.bkp
List of Datafiles in backup set 91
File LV Type Ckp SCN Ckp Time Name
---- -- ---- ---------- --------- ----
10 Full 3434217 05-MAY-18 /home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
備份的SCN是3434217,查詢該SCN之後的歸檔日誌備份
RMAN> list backup of archivelog from scn 3434217;
specification does not match any backup in the repository
表示此SCN之後的歸檔日誌沒有備份。
檢視此SCN之後的歸檔日誌是否存在
RMAN> list archivelog from scn 3434217;
查詢列出了在此SCN之後有三個歸檔日誌
Key Thrd Seq S Low Time
------- ---- ------- - ---------
1 1 32 A 05-MAY-18
Name: /home/oracle/app/oracle/flash_recovery_area/MES/archivelog/2018_05_05/o1_mf_1_32_d1070kob_.arc
2 1 33 A 05-MAY-18
Name: /home/oracle/app/oracle/flash_recovery_area/MES/archivelog/2018_05_05/o1_mf_1_33_d10nob7p_.arc
3 1 34 A 05-MAY-18
Name: /home/oracle/app/oracle/flash_recovery_area/MES/archivelog/2018_05_05/o1_mf_1_34_d10oqlqv_.arc
資料塊當前日誌序列號
archive log list;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 33
Next log sequence to archive 35
Current log sequence 35
資料塊當前的日誌序列號為35,10#檔案的最新備份時的SCN之後的日誌檔案序列號為32、33、34、35都連續存在,因此可以判斷10#檔案的資料塊損壞可以恢復。另一種情況是備份時的SCN還處於當前聯機日誌中,當然也是可以恢復的。
執行RMAN的壞塊恢復
RMAN> blockrecover datafile 10 block 132;
Starting recover at 05-MAY-18
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=34 device type=DISK
channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00010
channel ORA_DISK_1: reading from backup piece /home/oracle/app/oracle/flash_recovery_area/MES/backupset/2018_05_05/o1_mf_nnndf_TAG20180505T182704_fgv1qrdp_.bkp
channel ORA_DISK_1: piece handle=/home/oracle/app/oracle/flash_recovery_area/MES/backupset/2018_05_05/o1_mf_nnndf_TAG20180505T182704_fgv1qrdp_.bkp tag=TAG20180505T182704
channel ORA_DISK_1: restored block(s) from backup piece 1
channel ORA_DISK_1: block restore complete, elapsed time: 00:00:01
starting media recovery
media recovery complete, elapsed time: 00:00:03
Finished recover at 05-MAY-18
再次用RMAN檢查檔案塊狀態,可以看到已沒有壞塊
RMAN> backup validate check logical datafile 10;
Starting backup at 05-MAY-18
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00010 name=/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
10 OK 0 377 512 3433950
File Name: /home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 5
Index 0 0
Other 0 130
用dbverify工具檢查也是完好的
[oracle@vm-ora11g-linux-6-1 桌面]$ dbv file=/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
DBVERIFY: Release 11.2.0.1.0 - Production on Sat May 5 20:19:27 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
DBVERIFY - Verification starting : FILE = /home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
DBVERIFY - Verification complete
Total Pages Examined : 512
Total Pages Processed (Data) : 5
Total Pages Failing (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing (Index): 0
Total Pages Processed (Other): 130
Total Pages Processed (Seg) : 0
Total Pages Failing (Seg) : 0
Total Pages Empty : 377
Total Pages Marked Corrupt : 0
Total Pages Influx : 0
Total Pages Encrypted : 0
Highest block SCN : 3433950 (0.3433950)
全表掃描資料已正常
select count(*) from u1.blocktab;
COUNT(*)
----------
1000
三、沒有備份情況下的塊恢復
在資料庫為非歸檔模式等沒有備份的情況下,壞塊的處理就是首先定位到有壞塊的表,透過設定10231事件跳過EXP匯出時的壞塊檢查,將能夠拯救的資料匯出,然後將損壞的表刪除,再透過IMP匯入將表和資料重新建立起來,以下舉例說明這一操作。
建表空間
create tablespace blocktbs datafile '/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf' size 4m;
建測試使用者
create user u1 identified by u1 default tablespace blocktbs;
grant connect, resource to u1;
建表
create table u1.blocktab(a number, b varchar2(30));
插入模擬資料
declare
len number;
begin
for i in 1..1000 loop
len:=trunc(dbms_random.value(1, 30));
insert into u1.blocktab values(i, dbms_random.string('a', len));
end loop;
commit;
end;
/
查詢表當前共有1000條記錄
select count(*) from u1.blocktab;
COUNT(*)
----------
1000
檢視錶所在的檔案和資料塊
select distinct dbms_rowid.rowid_relative_fno(rowid) file#, dbms_rowid.rowid_block_number(rowid) block# from u1.blocktab order by 2;
FILE# BLOCK#
---------- ----------
10 131
10 132
10 134
10 135
計算第131號資料塊的大概位置
show parameters db_block_size;
NAME TYPE VALUE
--------------------------------- --------- ----------
db_block_size integer 8192
select to_char(131*8192,'xxxxxx') from dual;
TO_CHAR(131*8192,'XXX
---------------------
106000
用二進位制文字編輯器開啟10#檔案,找到地址106000位置後的資料,手動編輯修改,模擬壞塊
vim -b /home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
檔案將以二進位制形式開啟,用:%!xxd指令可顯示為十六進位制狀態,編輯後可用:%!xxd -r指令回到二進位制顯示狀態,最後用:wq儲存。
也可以用dd命令向指定塊寫入資料來模擬壞塊
dd if=/dev/zero of=/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf bs=8192 count=1 seek=131 conv=notrunc
重新整理資料庫快取
alter system flush buffer_cache;
再次查詢表
select count(*) from u1.blocktab;
提示壞塊錯誤
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 10, block # 131)
ORA-01110: data file 10: '/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf'
用RMAN檢查此檔案壞塊
RMAN> backup validate check logical datafile 10;
Starting backup at 05-MAY-18
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=98 device type=DISK
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00010 name=/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
10 FAILED 0 377 512 3442072
File Name: /home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 4
Index 0 0
Other 1 131
validate found one or more corrupt blocks
See trace file /home/oracle/app/oracle/diag/rdbms/mes/mes/trace/mes_ora_48861.trc for details
Finished backup at 05-MAY-18
查詢RMAN檢查後存放壞塊資訊的檢視
select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTION_TYPE
---------- ---------- ---------- ------------------ ---------------------------
10 131 1 0 ALL ZERO
跟蹤檔案mes_ora_48861.trc中也記錄了壞塊資訊。警告日誌檔案alert_mes.log中同樣可以看到壞塊資訊。
用dbverify工具也可以提示壞塊資訊
[oracle@vm-ora11g-linux-6-1 桌面]$ dbv file=/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
DBVERIFY: Release 11.2.0.1.0 - Production on Sat May 5 22:02:28 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
DBVERIFY - Verification starting : FILE = /home/oracle/app/oracle/oradata/mes/blocktbs01.dbf
Page 131 is marked corrupt
Corrupt block relative dba: 0x02800083 (file 10, block 131)
Completely zero block found during dbv:
DBVERIFY - Verification complete
Total Pages Examined : 512
Total Pages Processed (Data) : 4
Total Pages Failing (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing (Index): 0
Total Pages Processed (Other): 130
Total Pages Processed (Seg) : 0
Total Pages Failing (Seg) : 0
Total Pages Empty : 377
Total Pages Marked Corrupt : 1
Total Pages Influx : 0
Total Pages Encrypted : 0
Highest block SCN : 3442072 (0.3442072)
檢視損壞塊所涉及的資料庫物件
col tablespace_name for a20
col segment_name for a20
col segment_type for a20
col owner for a10
select tablespace_name, segment_type, owner, segment_name from dba_extents where file_id=10 and 131 between block_id and block_id + blocks - 1;
TABLESPACE_NAME SEGMENT_TYPE OWNER SEGMENT_NAME
-------------------- -------------------- ---------- --------------------
BLOCKTBS TABLE U1 BLOCKTAB
此時是不允許exp匯出的,提示壞塊錯誤
[oracle@vm-ora11g-linux-6-1 桌面]$ exp \"sys/mesHz2 as sysdba\" file=/home/oracle/blocktab.dmp tables=u1.blocktab
Export: Release 11.2.0.1.0 - Production on Sat May 5 22:06:35 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in UTF8 character set and AL16UTF16 NCHAR character set
server uses ZHS16GBK character set (possible charset conversion)
About to export specified tables via Conventional Path ...
Current user changed to U1
. . exporting table BLOCKTAB
EXP-00056: ORACLE error 1578 encountered
ORA-01578: ORACLE data block corrupted (file # 10, block # 131)
ORA-01110: data file 10: '/home/oracle/app/oracle/oradata/mes/blocktbs01.dbf'
Export terminated successfully with warnings.
損壞的是資料,我們可以設定內部事件,使exp跳過這些損壞的塊
alter system set events='10231 trace name context forever,level 10';
重新執行匯出命令
[oracle@vm-ora11g-linux-6-1 桌面]$ exp \"sys/mesHz2 as sysdba\" file=/home/oracle/blocktab.dmp tables=u1.blocktab
Export: Release 11.2.0.1.0 - Production on Sat May 5 22:11:47 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in UTF8 character set and AL16UTF16 NCHAR character set
server uses ZHS16GBK character set (possible charset conversion)
About to export specified tables via Conventional Path ...
Current user changed to U1
. . exporting table BLOCKTAB 705 rows exported
EXP-00091: Exporting questionable statistics.
Export terminated successfully with warnings.
顯示成功匯出705條資料,這比原本1000條資料少了295條,因為沒有備份,這部分資料只能丟失了。
將表刪除
drop table u1.blocktab purge;
再重新imp匯入
[oracle@vm-ora11g-linux-6-1 桌面]$ imp \"sys/mesHz2 as sysdba\" file=/home/oracle/blocktab.dmp tables=blocktab fromuser=u1 touser=u1 ignore=y
Import: Release 11.2.0.1.0 - Production on Sat May 5 22:22:25 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export file created by EXPORT:V11.02.00 via conventional path
import done in UTF8 character set and AL16UTF16 NCHAR character set
import server uses ZHS16GBK character set (possible charset conversion)
. importing U1's objects into U1
. . importing table "BLOCKTAB" 705 rows imported
Import terminated successfully without warnings.
檢視錶,恢復了705行資料
select count(*) from u1.blocktab;
COUNT(*)
----------
705
重新禁用壞塊跳過
alter system set events='10231 trace name context off';
此後,用RMAN或DBV檢查資料檔案可能仍然會提示有壞塊,也就是說檔案的壞塊位置已被標記,但表所在的資料塊,可能已經不是以前的位置了。
四、使用dbms_repair檢測和跳過壞塊
以上是透過設定10231內部事件,用exp匯出表資料後將表刪除,並用imp重新匯入表的方法重建表來恢復的。下面用Oracle提供的PL/SQL程式包dbms_repair來檢查和處理表和索引中出現的壞塊問題,包括標記和跳過壞塊。
建表空間
create tablespace testtbs datafile '/home/oracle/app/oracle/oradata/mes/testtbs01.dbf' size 2m;
建測試使用者
create user u1 identified by u1 default tablespace testtbs;
grant connect, resource to u1;
建測試表
create table u1.t1 tablespace testtbs as select * from scott.emp;
連續插入一批資料
insert into u1.t1 select * from u1.t1;
/
commit;
select count(*) from u1.t1;
COUNT(*)
----------
896
建立索引
create index u1.idx_t1_ename on u1.t1(ename);
檢視錶所在的檔案和資料塊
select distinct dbms_rowid.rowid_relative_fno(rowid) file#, dbms_rowid.rowid_block_number(rowid) block# from u1.t1 order by 2;
FILE# BLOCK#
---------- ----------
10 131
10 132
10 133
10 134
10 135
10 136
10 137
檢視每個資料塊擁有的記錄數
select dbms_rowid.rowid_block_number(rowid) block#, count(*) block_records from u1.t1 group by dbms_rowid.rowid_block_number(rowid) order by 1;
BLOCK# BLOCK_RECORDS
---------- -------------
131 14
132 170
133 170
134 170
135 170
136 170
137 32
以上顯示錶u1.t1中包含896條測試資料,共佔用7個資料塊,每個資料塊填滿(保持pctfree空閒)大約容納170條記錄。
計算第135號資料塊的大概位置
show parameters db_block_size;
NAME TYPE VALUE
--------------------------------- --------- ----------
db_block_size integer 8192
select to_char(135 * 8192,'xxxxxx') from dual;
TO_CHAR
-------
10e000
用二進位制文字編輯器開啟10#檔案,找到地址10e000位置後的資料,手動編輯修改,模擬壞塊
vim -b /home/oracle/app/oracle/oradata/mes/testtbs01.dbf
檔案將以二進位制形式開啟,用:%!xxd指令可顯示為十六進位制狀態,編輯後可用:%!xxd -r指令回到二進位制顯示狀態,最後用:wq儲存。
也可以用dd命令向指定塊寫入資料來模擬壞塊
dd if=/dev/zero of=/home/oracle/app/oracle/oradata/mes/testtbs01.dbf bs=8192 count=1 seek=135 conv=notrunc
重新整理資料庫快取
alter system flush buffer_cache;
查詢表記錄
select count(*) from u1.t1;
COUNT(*)
----------
896
提示壞塊錯誤
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 10, block # 135)
ORA-01110: data file 10: '/home/oracle/app/oracle/oradata/mes/testtbs01.dbf'
使用dbms_repair包:
建立管理表,這裡表名不可用其它名稱
表資料
exec dbms_repair.admin_tables('REPAIR_TABLE', 1, 1, 'users');
索引資料
exec dbms_repair.admin_tables('ORPHAN_TABLE', 2, 1, 'users');
檢查壞塊
set serveroutput on
declare
cc number;
begin
dbms_repair.check_object(schema_name => 'U1', object_name => 'T1', corrupt_count => cc);
dbms_output.put_line(to_char(cc));
end;
/
1
檢查結果提示有一個壞塊。
檢查完之後,在我們剛在建立的REPAIR_TABLE中檢視塊損壞資訊
col object_name for a20
col corrupt_description for a30
col repair_description for a30
select object_name, relative_file_id, block_id, marked_corrupt, corrupt_description, repair_description, check_timestamp from repair_table;
OBJECT_NAME RELATIVE_FILE_ID BLOCK_ID MARKED_CORRUPT CORRUPT_DESCRIPTION REPAIR_DESCRIPTION CHECK_TIMESTAMP
-------------------- ---------------- ---------- ------------------------------ ------------------------------ ------------------------------ ---------------
T1 10 135 TRUE mark block software corrupt 05-MAY-18
用skip_corrupt_blocks跳過壞塊
exec dbms_repair.skip_corrupt_blocks(schema_name => 'U1', object_name => 'T1', flags => 1);
再次掃描表已經可查詢
select count(*) from u1.t1;
COUNT(*)
----------
726
但丟失了896 - 726 = 170行資料。
處理索引上的無效鍵值
declare
cc number;
begin
dbms_repair.dump_orphan_keys(schema_name => 'U1', object_name => 'IDX_T1_ENAME', object_type => 2, repair_table_name => 'REPAIR_TABLE', orphan_table_name => 'ORPHAN_TABLE', key_count => CC);
end;
/
select count(*) from orphan_table;
COUNT(*)
----------
170
有170行無效索引,和上面我們看到的損失資料吻合,根據這個結果可以考慮是否需要重建索引。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28974745/viewspace-2153867/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【BLOCK】Oracle壞塊處理命令參考BloCOracle
- 一次ORACLE資料庫undo壞塊處理Oracle資料庫
- Oracle資料庫處理壞塊問題常用命令Oracle資料庫
- 如何處理Oracle資料庫中的壞塊問題(轉)Oracle資料庫
- oracle壞塊(二)Oracle
- Oracle資料庫出現ORA-19566 LOB壞塊的處理記錄Oracle資料庫
- 一次壞塊的處理過程(一)
- 一次壞塊的處理過程(二)
- [20190718]12c壞塊處理一例.txt
- 一個簡單易用的資料庫壞塊處理方案資料庫
- Oracle日常問題-壞塊修復Oracle
- truncate操作消除ORACLE SEG壞塊解析Oracle
- Oracle 無備份情況下undo檔案損壞處理Oracle
- oracle redo各種狀態(inactive、active、current)損壞的處理方式Oracle Redo
- Oracle資料庫壞塊典型案例分析Oracle資料庫
- 控制檔案損壞處理
- Oracle SQL處理OracleSQL
- Oracle資料庫壞塊典型案例擴充Oracle資料庫
- [20190311]關於oracle物理與邏輯壞塊.txtOracle
- oracle 普通表空間資料檔案壞塊Oracle
- oracle異常處理Oracle
- RAC磁碟頭損壞問題處理
- oracle 高水位分析處理Oracle
- oracle高水位線處理Oracle
- oracle ORA-08104處理Oracle
- Oracle更新Opatch故障處理Oracle
- Oracle非法日期 處理方案Oracle
- Oracle TX鎖的處理Oracle
- Oracle密碼過期處理Oracle密碼
- Oracle異常錯誤處理Oracle
- ORACLE 異常錯誤處理Oracle
- Oracle 監聽異常處理Oracle
- 【SQL】Oracle SQL處理的流程SQLOracle
- MySQL資料庫InnoDB壞頁處理修復MySql資料庫
- oracle SP2-問題處理Oracle
- Oracle 10g RAC故障處理Oracle 10g
- oracle ora-00054錯誤處理Oracle
- oracle遊標批次處理資料Oracle