[翻譯]-Detect And Repair Corruption in an Oracle Database

潇湘隐者發表於2024-06-20

本文是對這篇文章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]
參考資料
[1]

原文地址: 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

相關文章