-- 1. DBV 離線檢查 (需關閉資料庫或檔案離線)
dbv file=/u01/oradata/db/users01.dbf blocksize=8192
-- 2. 觸發掃描定位 (全表掃描)
SELECT count(*) FROM corrupted_table; -- 回傳 ORA-01578
-- 3. 精確定位損壞物件
SELECT tablespace_name, segment_type, owner, segment_name
FROM dba_extents
WHERE file_id = 4
AND 35 BETWEEN block_id AND block_id + blocks - 1;
ALTER INDEX idx REBUILD (最快、零資料遺失)-- 1. 驗證備份集完整性並掃描壞塊
RMAN> BACKUP VALIDATE DATAFILE 4;
-- 2. 查詢壞塊清單
RMAN> SELECT * FROM v$database_block_corruption WHERE file# = 4;
-- 3. 執行區塊恢復 (自動從備份集讀取好塊覆寫)
RMAN> BLOCKRECOVER DATAFILE 4 BLOCK 35 FROM BACKUPSET;
-- 4. 驗證恢復結果
RMAN> BACKUP VALIDATE DATAFILE 4; -- 應無壞塊回報
優點:資料庫線上執行、僅恢復損壞區塊、無資料遺失。
前提:ArchiveLog 模式 + 近期 RMAN 備份集。
-- 1. 設定 Session 事件跳過壞塊
ALTER SESSION SET EVENTS '10231 TRACE NAME CONTEXT FOREVER, LEVEL 10';
-- 2. 匯出受影響表 (會跳過壞塊行)
EXP userid=system/password FILE=tab.dmp TABLES=corrupted_table
-- 3. 重建表
DROP TABLE corrupted_table;
CREATE TABLE corrupted_table AS SELECT * FROM corrupted_table@dblink; -- 或從 DDL 重建
-- 4. 匯入資料
IMP userid=system/password FILE=tab.dmp TABLES=corrupted_table IGNORE=Y
壞塊所在列永久遺失,僅能恢復好塊資料。適用於非關鍵表或無備份環境。
-- 1. 建立修復表
EXEC DBMS_REPAIR.ADMIN_TABLES(TABLE_NAME => 'REPAIR_TABLE', ACTION => DBMS_REPAIR.CREATE_ACTION);
-- 2. 檢測並標記壞塊
EXEC DBMS_REPAIR.CHECK_OBJECT(
SCHEMA_NAME => 'SCOTT', OBJECT_NAME => 'CORRUPTED_TABLE',
REPAIR_TABLE_NAME => 'REPAIR_TABLE');
-- 3. 修復 (標記壞塊為軟刪除,後續存取跳過)
EXEC DBMS_REPAIR.FIX_CORRUPT_BLOCKS(
SCHEMA_NAME => 'SCOTT', OBJECT_NAME => 'CORRUPTED_TABLE',
REPAIR_TABLE_NAME => 'REPAIR_TABLE');
$ORACLE_HOME/bin/bbed (Linux 需編譯 make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed)blockedit (僅供 Oracle 內部使用,不提供技術支援)警告:BBED 操作錯誤會導致資料庫徹底不可用。僅在 Oracle Support 指導下使用,並務必先完整複製資料檔備份。
ALTER SYSTEM SET db_block_checksum = FULL SCOPE=SPFILE; (11g+ 預設 TYPICAL)ALTER SYSTEM SET db_block_checking = MEDIUM SCOPE=SPFILE; (效能影響 < 5%)BACKUP VALIDATE DATABASE 主動發現壞塊