[OCP學習筆記]043-07-處理資料庫損壞--模擬實驗(2)
4.使用工具進行修復
這裡,我們嘗試採用多種工具來對損壞的資料塊進行修復。前文中我構建了擁有4個壞塊的表空間test,資料檔案為test01.dbf,大小1MB。為了簡化操作,我們備份了他的一個副本test01.bak。以下操作可在每個實驗前獨立進行,以確保實驗樣本的一致性,且彼此之間不會產生衝突。
sys@STUDY> host copy test01.bak test01.dbf
sys@STUDY>alter tablespace test online;
Tablespace altered.
sys@STUDY>alter system flush buffer_cache;
System altered.
l 使用BlockRecover...corruption list進行修復
前文中,我們使用RMAN對修改前的正確的test表空間進行了備份,對出現壞塊後的test表空間進行了validate。
在做BMR之前,首先確定需要恢復的表空間是否有備份存在。
RMAN> list backup of tablespace "TEST";
List of Backup Sets
===================
BS Key Type LV Size Device Type Elapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ -------------------
35 Full 648.00K DISK 00:00:01 2010-06-05 21:15:56
BP Key: 32 Status: AVAILABLE Compressed: NO Tag: TAG20100605T211555
Piece Name: C:ORACLEPRODUCT10.2.0FLASH_RECOVERY_AREASTUDYBACKUPSET2010_06_05O1_MF_NNNDF_TAG20100605T211555_60NMJCWB_.BKP
List of Datafiles in backup set 35
File LV Type Ckp SCN Ckp Time Name
---- -- ---- ---------- ------------------- ----
14 Full 1921865 2010-06-05 21:15:55 C:ORACLEPRODUCT10.2.0ORADATASTUDYTEST01.DBF
其次,確認需要恢復的資料塊資訊已經記錄到V$BACKUP_CORRUPTION檢視中。
sys@STUDY>select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
14 28 1 0 CHECKSUM
14 20 1 0 FRACTURED
14 16 1 0 FRACTURED
執行BMR操作進行恢復。
RMAN> blockrecover corruption list;
Starting blockrecover at 2010-06-05 21:40:09
using channel ORA_DISK_1
channel ORA_DISK_1: restoring block(s) from datafile copy C:ORACLEPRODUCT10.2.0FLASH_RECOVERY_AREASTUDYDATAFILEO1_MF_TEST_60NML16T_.DBF
starting media recovery
media recovery complete, elapsed time: 00:00:03
Finished blockrecover at 2010-06-05 21:40:14
再次進行驗證
RMAN> backup validate tablespace "TEST";
Starting backup at 2010-06-05 21:43:14
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
input datafile fno=00014 name=C:ORACLEPRODUCT10.2.0ORADATASTUDYTEST01.DBF
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02
Finished backup at 2010-06-05 21:43:16
再次查詢V$DATABASE_BLOCK_CORRUPTION確定壞塊已經被修復。
sys@STUDY>select * from v$database_block_corruption;
no rows selected
類似的,大家可以嘗試使用映象來進行壞塊的恢復,兩者過程大致相同。
l 使用BlockRecover...File#...Block#進行恢復
RMAN> blockrecover datafile 14 block 16, 20, 24, 28;
Starting blockrecover at 2010-06-05 21:54:13
using channel ORA_DISK_1
channel ORA_DISK_1: restoring block(s) from datafile copy C:ORACLEPRODUCT10.2.0FLASH_RECOVERY_AREASTUDYDATAFILEO1_MF_TEST_60NML16T_.DBF
starting media recovery
media recovery complete, elapsed time: 00:00:07
Finished blockrecover at 2010-06-05 21:54:21
dbv file=test01.dbf
DBVERIFY: Release 10.2.0.1.0 - Production on Sat Jun 5 21:55:14 2010
Copyright (c) 1982, 2005, Oracle. All rights reserved.
DBVERIFY - Verification starting : FILE = test01.dbf
DBVERIFY - Verification complete
Total Pages Examined : 128
Total Pages Processed (Data) : 53
Total Pages Failing (Data) : 0
Total Pages Processed (Index): 8
Total Pages Failing (Index): 0
Total Pages Processed (Other): 17
Total Pages Processed (Seg) : 0
Total Pages Failing (Seg) : 0
Total Pages Empty : 50
Total Pages Marked Corrupt : 0
Total Pages Influx : 0
Highest block SCN : 1921792 (0.1921792)
修復完畢。
l 使用DBMS_REPAIR軟體包進行恢復
首先確定在16、20、24、28資料塊中存放記錄的數量。
sys@STUDY>select count(rowid) from t1 where dbms_rowid.rowid_block_number(rowid) in (16, 20, 24, 28);
COUNT(ROWID)
------------
130
建立repair_table和orphan_table,用於存放壞塊和索引中對應的孤鍵記錄。
BEGIN
DBMS_REPAIR.ADMIN_TABLES (
TABLE_NAME => 'REPAIR_TABLE',
TABLE_TYPE => dbms_repair.repair_table,
ACTION => dbms_repair.create_action,
TABLESPACE => 'TEST');
END;
/
BEGIN
DBMS_REPAIR.ADMIN_TABLES (
TABLE_NAME => 'ORPHAN_KEY_TABLE',
TABLE_TYPE => dbms_repair.orphan_table,
ACTION => dbms_repair.create_action,
TABLESPACE => 'TEST');
END;
/
使用CHECK_OBJECT過程檢測壞塊
SET SERVEROUTPUT ON
DECLARE
num_corrupt INT;
BEGIN
num_corrupt := 0;
DBMS_REPAIR.CHECK_OBJECT (
SCHEMA_NAME => 'SYS',
OBJECT_NAME => 'T1',
REPAIR_TABLE_NAME => 'REPAIR_TABLE',
CORRUPT_COUNT => num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt));
END;
/
查詢repair_table,檢視檢測到的壞塊的資訊:
sys@STUDY>select BLOCK_ID, CORRUPT_TYPE, MARKED_CORRUPT, REPAIR_DESCRIPTION from repair_table;
BLOCK_ID CORRUPT_TYPE MARKED_COR REPAIR_DESCRIPTION
---------- ------------ ---------- ------------------------------
16 6148 TRUE mark block software corrupt
20 6148 TRUE mark block software corrupt
24 6148 TRUE mark block software corrupt
28 6148 TRUE mark block software corrupt
這裡marked_corrupt被標記為true,應該是系統在執行CHECK_OBJECT過程中自動完成了FIX_CORRUPT_BLOCKS。如果被標記為flase,需要再執行FIX_CORRUPT_BLOCKS來完成壞塊的標記工作。
sys@STUDY>DECLARE
2 num_fix INT;
3 BEGIN
4 num_fix := 0;
5 DBMS_REPAIR.FIX_CORRUPT_BLOCKS (
6 SCHEMA_NAME => 'SYS',
7 OBJECT_NAME=> 'T1',
8 OBJECT_TYPE => dbms_repair.table_object,
9 REPAIR_TABLE_NAME => 'REPAIR_TABLE',
10 FIX_COUNT=> num_fix);
11 DBMS_OUTPUT.PUT_LINE('num fix: ' || TO_CHAR(num_fix));
12 END;
13 /
num fix: 0
PL/SQL procedure successfully completed.
標記了0個壞塊,說明CHECK_OBJECT完成了標記工作。
雖然我們對壞塊進行了標記,但由於索引並未損壞,因此透過索引來訪問資料表,仍然可能引發ORA-01578錯誤。
sys@STUDY>select * from t1 where table_name='REPCAT$_TEMPLATE_REFGROUPS';
select * from t1 where table_name='REPCAT$_TEMPLATE_REFGROUPS'
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 14, block # 28)
ORA-01110: data file 14: 'C:ORACLEPRODUCT10.2.0ORADATASTUDYTEST01.DBF'
"REPCAT$_TEMPLATE_REFGROUPS"對應的記錄存放在第28塊中,透過索引來訪問時,發生錯誤。
使用DUMP_ORPHAN_KEYS過程來儲存壞塊中的索引鍵值,存放到ORPHAN_KEY_TABLE中。
sys@STUDY> SET SERVEROUTPUT ON
1 DECLARE
2 num_orphans INT;
3 BEGIN
4 num_orphans := 0;
5 DBMS_REPAIR.DUMP_ORPHAN_KEYS (
6 SCHEMA_NAME => 'SYS',
7 OBJECT_NAME => 'ID_T1',
8 OBJECT_TYPE => dbms_repair.index_object,
9 REPAIR_TABLE_NAME => 'REPAIR_TABLE',
10 ORPHAN_TABLE_NAME=> 'ORPHAN_KEY_TABLE',
11 KEY_COUNT => num_orphans);
12 DBMS_OUTPUT.PUT_LINE('orphan key count: ' || TO_CHAR(num_orphans));
13 END;
14 /
PL/SQL procedure successfully completed.
注意:如果表有多個索引,需要為每個索引執行DUMP_ORPHAN_KEYS操作。
sys@STUDY>select count(*) from orphan_key_table;
COUNT(*)
----------
130
和存放在16、20、24、28這4個壞塊中的記錄數量相當。
如果表空間採用的是資料字典管理的話,空塊將被記錄在freelists連結串列中。如果壞塊發生在FREELIST列表中的中部,則FREELIST列表後面的塊都無法訪問。為此,我們需要執行REBUILD_FREELISTS過程來修改FREELISTS。
sys@STUDY>BEGIN
2 DBMS_REPAIR.REBUILD_FREELISTS (
3 SCHEMA_NAME => 'SYS',
4 OBJECT_NAME => 'T1',
5 OBJECT_TYPE => dbms_repair.table_object);
6 END;
7 /
BEGIN
*
ERROR at line 1:
ORA-10614: Operation not allowed on this segment
ORA-06512: at "SYS.DBMS_REPAIR", line 400
ORA-06512: at line 2
這裡我們採用的是ASSM來進行表空間管理,所以無需執行REBUILD_FREELISTS操作。
執行SKIP_CORRUPT_BLOCKS過程,是後續DML操作跳過壞塊
sys@STUDY>BEGIN
2 DBMS_REPAIR.SKIP_CORRUPT_BLOCKS (
3 SCHEMA_NAME => 'SYS',
4 OBJECT_NAME => 'T1',
5 OBJECT_TYPE => dbms_repair.table_object,
6 FLAGS => dbms_repair.skip_flag);
7 END;
8 /
PL/SQL procedure successfully completed.
由於資料和索引仍然存在不一致的問題,因此必須重建索引。
sys@STUDY>alter index id_t1 rebuild;
Index altered.
sys@STUDY>select table_name from t1 where table_name='REPCAT$_TEMPLATE_REFGROUPS';
TABLE_NAME
------------------------------
REPCAT$_TEMPLATE_REFGROUPS
注意一點,重建索引一點要先DROP,然後再CREATE,使用REBUILD的方式,重建的資料來源來自索引,仍然會導致問題的產生。
sys@STUDY>drop index id_t1;
Index dropped.
sys@STUDY>create index id_t1 on t1(table_name);
Index created.
sys@STUDY>select table_name from t1 where table_name='REPCAT$_TEMPLATE_REFGROUPS';
no rows selected
sys@STUDY>select count(*) from t1;
COUNT(*)
----------
1605
sys@STUDY>select count(*) from dba_tables;
COUNT(*)
----------
1738
我們發現在標識SKIP_CORRUPT_BLOCKS的過程中,一共少了133個記錄。然而,ORPHAN_KEY_TABLE中僅記錄了130條記錄。中間有3個記錄丟失了!
[@more@]《第07章 處理資料庫損壞》學習筆記.pdf來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/20162/viewspace-1034208/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【Pandas學習筆記02】處理資料實用操作筆記
- 機器學習筆記---資料預處理機器學習筆記
- MySQL資料庫INNODB表損壞修復處理過程分享MySql資料庫
- 使用 seed 命令建立模擬資料(學習筆記)筆記
- Python深度學習(處理文字資料)--學習筆記(十二)Python深度學習筆記
- YOLOv3學習筆記之資料處理YOLO筆記
- Proteus模擬學習筆記筆記
- 模擬退火學習筆記筆記
- 模擬退火 學習筆記筆記
- 資料庫學習筆記資料庫筆記
- 【Pandas學習筆記02】-資料處理高階用法筆記
- 控制檔案損壞處理
- 1029學習筆記 資料庫筆記資料庫
- MySQL資料庫學習筆記MySql資料庫筆記
- python學習筆記:資料庫Python筆記資料庫
- React學習筆記-事件處理React筆記事件
- 資料庫mysql學習筆記記錄資料庫MySql筆記
- MySQL資料庫InnoDB壞頁處理修復MySql資料庫
- Redis學習筆記(七) 資料庫Redis筆記資料庫
- 達夢資料庫學習筆記資料庫筆記
- OCP 複習筆記之PL/SQL (2)筆記SQL
- Vue學習筆記之事件處理Vue筆記事件
- 模擬積體電路學習筆記筆記
- 機器學習演算法筆記之6:資料預處理機器學習演算法筆記
- 一次ORACLE資料庫undo壞塊處理Oracle資料庫
- docker學習筆記(2)- 倉庫Docker筆記
- JSP筆記-XML 資料處理JS筆記XML
- swoft 學習筆記之資料庫操作筆記資料庫
- RAC磁碟頭損壞問題處理
- Oracle資料庫出現ORA-19566 LOB壞塊的處理記錄Oracle資料庫
- swoft 學習筆記之資料庫配置與實體定筆記資料庫
- vue學習筆記3-事件處理Vue筆記事件
- swoft 學習筆記之異常處理筆記
- Flutter學習筆記(32)--PointerEvent事件處理Flutter筆記事件
- 資料庫學習筆記1(資料管理歷史)資料庫筆記
- 學習筆記(1):Python零基礎入門到實戰-資料科學原理與資料處理流程筆記Python資料科學
- [PyTorch 學習筆記] 2.2 圖片預處理 transforms 模組機制PyTorch筆記ORM
- PostgreSQL資料庫toast表損壞解決SQL資料庫AST
- SQLite資料庫損壞及其修復探究SQLite資料庫