本文是對這篇文章Detect And Repair Corruption in an Oracle Database[1]的翻譯,翻譯如有不當的地方,敬請諒解,請尊重原創和翻譯勞動成果,轉載的時候請註明出處。謝謝! Oracle資料庫提供了多種方法檢測和修複數據文件中的壞塊。主要有下麵一些方法: R ...
本文是對這篇文章Detect And Repair Corruption in an Oracle Database[1]的翻譯,翻譯如有不當的地方,敬請諒解,請尊重原創和翻譯勞動成果,轉載的時候請註明出處。謝謝!
Oracle資料庫提供了多種方法檢測和修複數據文件中的壞塊。主要有下麵一些方法:
RMAN (BACKUP VALIDATE, RESTORE VALIDATE, VALIDATE) Multitenant : RMAN VALIDATE DBVerify ANALYZE .. VALIDATE STRUCTURE DB_BLOCK_CHECKING Block Media Recovery (BMR) DBMS_REPAIR Other Repair Methods
RMAN (BACKUP VALIDATE, RESTORE VALIDATE, VALIDATE)
Oracle Recovery Manager (RMAN) 可以使用 BACKUP VALIDATE命令檢測驗證資料庫
RMAN> BACKUP VALIDATE DATABASE ARCHIVELOG ALL;
該過程輸出的信息與備份期間看到的信息相同,但是不會創建備份。任何塊損壞都會在V$DATABASE_BLOCK_CORRUPTION 視圖以及 RMAN 輸出信息中見到。
預設情況下,該命令僅檢查物理損壞/壞塊。添加CHECK LOGICAL選項可以包含對邏輯損壞的檢查。
RMAN> BACKUP VALIDATE CHECK LOGICAL DATABASE ARCHIVELOG ALL;
RMAN可以使用RESTORE VALIDATE命令驗證備份文件內容。
RMAN> RESTORE DATABASE VALIDATE;
RMAN> RESTORE ARCHIVELOG ALL VALIDATE;
與命令BACKUP VALIDATE類似,命令RESTORE VALIDATE模擬恢復過程,但實際上並不執行恢復。
在Oracle 11g之前,VALIDATE命令只能直接用於驗證備份相關文件。在 Oracle 11g及更高版本中,該VALIDATE命令還可以驗證數據文件、表空間或整個資料庫,因此您可以使用它來代替BACKUP VALIDATE命令。
RMAN> VALIDATE DATAFILE 1;
RMAN> VALIDATE DATAFILE '/u01/app/oracle/oradata/ORCL/system01.dbf';
RMAN> VALIDATE CHECK LOGICAL DATAFILE 1;
RMAN> VALIDATE CHECK LOGICAL DATAFILE '/u01/app/oracle/oradata/ORCL/system01.dbf';
RMAN> VALIDATE TABLESPACE users;
RMAN> VALIDATE CHECK LOGICAL TABLESPACE users;
RMAN> VALIDATE DATABASE;
RMAN> VALIDATE CHECK LOGICAL DATABASE;
任何損壞的塊都可以從V$DATABASE_BLOCK_CORRUPTION視圖中找到。您可以使用類似這樣的查詢來識別包含損壞塊的對象。
COLUMN owner FORMAT A20
COLUMN segment_name FORMAT A30
SELECT DISTINCT owner, segment_name
FROM v$database_block_corruption dbc
JOIN dba_extents e ON dbc.file# = e.file_id AND dbc.block# BETWEEN e.block_id and e.block_id+e.blocks-1
ORDER BY 1,2;
更多的語法例子可以從這個鏈接[2]查看
Multitenant : RMAN VALIDATE
主實例(main instance)的許多RMAN命令也可以用於可插拔資料庫(PDB) 或根容器。例如,當連接到根容器時,您可以執行以下操作。
rman target=/
# Everything.
VALIDATE DATABASE;
VALIDATE CHECK LOGICAL DATABASE;
# Just the root container.
VALIDATE DATABASE ROOT;
VALIDATE CHECK LOGICAL DATABASE ROOT;
# Just the specified PDB, or comma-separated list.
VALIDATE PLUGGABLE DATABASE pdb1;
VALIDATE CHECK LOGICAL PLUGGABLE DATABASE pdb1;
如果您直接連接到 PDB,則可以使用下麵命令。
rman target=sys/SysPassword1@pdb1
# Just the specified PDB.
VALIDATE DATABASE;
VALIDATE CHECK LOGICAL DATABASE;
DBVerify
DBVerify是一個外部應用程式,可用於驗證離線和線上數據文件。除了離線數據文件外,它還可用於檢查備份數據文件的有效性。
C:\>dbv file=C:\Oracle\oradata\TSH1\system01.dbf feedback=10000 blocksize=8192
這個工具通常不用於驗證控制文件或重做日誌,但在MOS Doc ID 1949795.1中有一個將其與控制文件一起使用的示例。
ANALYZE .. VALIDATE STRUCTURE
ANALYZE命令可用於驗證所分析對象中的每個數據塊。如果檢測到任何損壞,則會將行添加到INVALID_ROWS表中。
-- Create the INVALID_ROWS table
SQL> @C:\Oracle\901\rdbms\admin\UTLVALID.SQL
-- Validate the table structure.
SQL> ANALYZE TABLE scott.emp VALIDATE STRUCTURE;
-- Validate the table structure along with all it's indexes.
SQL> ANALYZE TABLE scott.emp VALIDATE STRUCTURE CASCADE;
-- Validate the index structure.
SQL> ANALYZE INDEX scott.pk_emp VALIDATE STRUCTURE;
DB_BLOCK_CHECKING
當DB_BLOCK_CHECKING參數設置為[TRUE|HIGH]時,Oracle會遍歷塊中的數據以檢查其是否自洽(self-consistent.)。不幸的是,塊檢查會給伺服器增加1%到10%的開銷。如果開銷可以接受,Oracle 建議將此參數設置為[TRUE|HIGH]。
允許的值包括 [OFF|FALSE]、LOW、MEDIUM、[HIGH|TRUE]。請在此處閱讀定義。
Block Media Recovery (BMR)
塊介質恢復 (BMR) 允許在不影響整個數據文件的情況下恢復指定塊。它僅用於已知且有限數量的塊受到影響的情況。這可以縮短平均恢復時間 (MTTR) 並提高可用性,因為在操作期間只有受影響的塊處於離線狀態。BMR只能通過 RMAN 使用命令執行BLOCKRECOVER。
塊介質恢復是企業版的一項功能。
可以使用以下方法識別損壞的塊:
錯誤消息 alert日誌 跟蹤文件 ANALYZE [TABLE | INDEX]命令 dbverify工具 VCOPY_CORRUPTION視圖列出了備份中的損壞塊,而不是資料庫本身。 V$DATABASE_BLOCK_CORRUPTION列出了在各種 RMAN 操作期間檢測到的資料庫中損壞的塊。恢復的塊仍將列出,直到執行下一次備份為止。
一旦檢測到損壞的塊,可以單獨恢復。或者可以使用CORRUPTION LIST選項恢復視圖V$DATABASE_BLOCK_CORRUPTION中列出的所有塊。可以使用 UNTIL 選項限制此列表
BLOCKRECOVER DATAFILE 3 BLOCK 121;
BLOCKRECOVER CORRUPTION LIST RESTORE UNTIL TIME 'SYSDATE - 7';
DBMS_REPAIR
與前面討論的方法不同,DBMS_REPAIR 包允許您檢測和修複損壞。該過程需要兩個管理表來保存損壞塊的列表以及指向這些塊的索引鍵。這些創建如下。
BEGIN
DBMS_REPAIR.admin_tables (
table_name => 'REPAIR_TABLE',
table_type => DBMS_REPAIR.repair_table,
action => DBMS_REPAIR.create_action,
tablespace => 'USERS');
DBMS_REPAIR.admin_tables (
table_name => 'ORPHAN_KEY_TABLE',
table_type => DBMS_REPAIR.orphan_table,
action => DBMS_REPAIR.create_action,
tablespace => 'USERS');
END;
/
建立管理表後,我們能夠使用 CHECK_OBJECT 過程檢查感興趣的表。
SET SERVEROUTPUT ON
DECLARE
v_num_corrupt INT;
BEGIN
v_num_corrupt := 0;
DBMS_REPAIR.check_object (
schema_name => 'SCOTT',
object_name => 'DEPT',
repair_table_name => 'REPAIR_TABLE',
corrupt_count => v_num_corrupt);
DBMS_OUTPUT.put_line('number corrupt: ' || TO_CHAR (v_num_corrupt));
END;
/
假設損壞塊的數量大於 0,則可以使用 REPAIR_TABLE 的 CORRUPTION_DESCRIPTION 和 REPAIR_DESCRIPTION 列獲取更多有關損壞的信息。
此時,損壞塊已被檢測到,但尚未標記為損壞。可以使用 FIX_CORRUPT_BLOCKS存粹過程將塊標記為損壞,一旦表處於正確模式,DML 就可以跳過它們。
SET SERVEROUTPUT ON
DECLARE
v_num_fix INT;
BEGIN
v_num_fix := 0;
DBMS_REPAIR.fix_corrupt_blocks (
schema_name => 'SCOTT',
object_name => 'DEPT',
object_type => Dbms_Repair.table_object,
repair_table_name => 'REPAIR_TABLE',
fix_count => v_num_fix);
DBMS_OUTPUT.put_line('num fix: ' || TO_CHAR(v_num_fix));
END;
/
一旦找到並標記了表中損壞的塊,就必須檢查所有索引,查看其中是否有任何鍵條目指向損壞的塊。這是使用 DUMP_ORPHAN_KEYS 過程完成的。
SET SERVEROUTPUT ON
DECLARE
v_num_orphans INT;
BEGIN
v_num_orphans := 0;
DBMS_REPAIR.dump_orphan_keys (
schema_name => 'SCOTT',
object_name => 'PK_DEPT',
object_type => DBMS_REPAIR.index_object,
repair_table_name => 'REPAIR_TABLE',
orphan_table_name => 'ORPHAN_KEY_TABLE',
key_count => v_num_orphans);
DBMS_OUTPUT.put_line('orphan key count: ' || TO_CHAR(v_num_orphans));
END;
/
如果孤立鍵(orphan key)數量大於 0,則應重建索引。
將表塊標記為損壞的過程會自動將其從空閑列表中刪除。這可以防止空閑列表訪問損壞塊之後的所有塊。要糾正此問題,必須使用 REBUILD_FREELISTS 過程重建空閑列表。
BEGIN
DBMS_REPAIR.rebuild_freelists (
schema_name => 'SCOTT',
object_name => 'DEPT',
object_type => DBMS_REPAIR.table_object);
END;
/
該過程的最後一步是確保所有 DML 語句忽略標記為損壞的數據塊。這是用 SKIP_CORRUPT_BLOCKS 過程完成的。
BEGIN
DBMS_REPAIR.skip_corrupt_blocks (
schema_name => 'SCOTT',
object_name => 'DEPT',
object_type => DBMS_REPAIR.table_object,
flags => DBMS_REPAIR.skip_flag);
END;
/
視圖DBA_TABLES中的SKIP_CORRUPT列表示此操作是否成功。
此時表可以再次使用,但您必須採取措施糾正與丟失塊相關的任何數據丟失。
Other Repair Methods
修複壞塊的其他方法包括:
完整資料庫恢復(Full database recovery)。 單個數據文件恢復。 使用命令CREATE TABLE .. AS SELECT 重新創建表,註意通過限制查詢的 where 子句來避免損壞的塊。 刪除表並從之前的導出的dump文件中恢復。這可能需要一些手動操作來替換丟失的數據。
更多信息請參閱:
DBVERIFY: Offline Database Verification Utility[3] DBMS_REPAIR[4] Handling Oracle Block Corruptions in Oracle7/8/8i/9i/10g/11g[5] Master Note for Handling Oracle Database Corruption Issues [ID 1088018.1][6]
原文地址: https://oracle-base.com/articles/misc/detect-and-correct-corruption
[2]2: https://oracle-base.com/articles/11g/data-recovery-advisor-11gr1#validate
[3]3: http://docs.oracle.com/cd/E11882_01/server.112/e22490/dbverify.htm
[4]4: http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_repair.htm
[5]5: https://support.oracle.com/epmos/faces/DocContentDisplay?id=28814.1
[6]6: https://support.oracle.com/epmos/faces/DocContentDisplay?id=1088018.1