| Lesson 4 | Repairing corrupted blocks |
| Objective | Detect and repair a corrupted block. |
A corruption incident begins with a practical question: can the database recover the original data, or can it only make the undamaged portion accessible? That distinction determines the response. RMAN block media recovery restores damaged blocks from usable copies and applies redo. The DBMS_REPAIR package supports a different operation: identifying damage and, when necessary, marking blocks so supported scans can skip them. Skipping a block does not recover its rows.
This lesson follows an incident from its first error through diagnosis, recovery selection, and verification. File 5, block 30123, and HR.EMPLOYEES are illustrative identifiers. Substitute values confirmed in your database. The examples have not been executed against a database, and their output depends on the actual damage, privileges, configuration, and available recovery material.
Capture the complete error stack, time, affected application operation, database identity, and container before changing anything. An ORA-01578 message commonly identifies a file and block; associated messages and trace records help identify the data file. Preserve the alert log, relevant trace files, and RMAN output together. A screenshot of the application error alone rarely provides enough information to choose a recovery method.
Physical corruption means that a block fails checks of its physical representation. Logical block corruption involves inconsistent internal contents even when physical checks succeed. A business mistake, such as a valid transaction updating the wrong salary, is a separate problem: block validation can pass while the application data is wrong. Oracle discusses these distinctions in its block media recovery guide.
Keep the response proportional to the evidence. One failing query does not prove that only one block is affected, and a long list of errors does not necessarily mean every object is lost. Identify the scope before deciding between a small block recovery and a broader restore. Preserve existing backups and archived logs; do not discard recovery material while investigating an incident.
RMAN provides a consistent starting point for checking database files. Begin with the affected file when incident urgency or database size makes a full scan inappropriate. Schedule broader validation when the initial evidence suggests damage beyond that file. These are separate choices at the RMAN prompt:
-- Check the affected file, including logical block checks.
VALIDATE CHECK LOGICAL DATAFILE 5;
-- Alternative scope: check the database.
VALIDATE CHECK LOGICAL DATABASE;
The CHECK LOGICAL option adds logical checks for blocks that pass physical checking. Review the file-level results and diagnostic references, including blocks that failed checking or were already marked corrupt. A command completing is not equivalent to every block being healthy. Validation performs substantial reads, so consider its impact alongside the incident's urgency.
BACKUP VALIDATE CHECK LOGICAL DATABASE; is another way to validate without producing backup pieces. It does not replace a real backup. Similarly, validating current files does not establish that all required backup pieces and archived logs can be read. Recovery readiness requires checking those sources too. See the RMAN VALIDATE reference for command scope and result interpretation.
Use SQL to inspect the corruption inventory. Keep the container identifier in the report, especially when investigating from a multitenant container database root:
SELECT con_id, file#, block#, blocks, corruption_type
FROM v$database_block_corruption
ORDER BY con_id, file#, block#;
A row can describe several consecutive blocks: BLOCK# is the starting block and BLOCKS is the range length. Record the entire range rather than silently treating each row as one block. The view reference defines the corruption categories and container column. An empty result is useful evidence about recorded corruption, not proof that every application relationship is correct.
Next, connect to the affected PDB using an appropriately privileged SQL session. Confirm its identity before mapping the file and block into an extent. This example assumes file 5 belongs to that PDB:
SHOW CON_NAME
SELECT owner, segment_name, partition_name, segment_type,
file_id, block_id, blocks
FROM dba_extents
WHERE file_id = 5
AND 30123 BETWEEN block_id AND block_id + blocks - 1;
The result identifies an allocated segment extent, potentially a table partition, index, or other segment. A missing result requires investigation: the session may be in the wrong container, the block may not belong to an allocated user segment, or view visibility may be limited. Do not interpret no match as permission to ignore the corruption. Root-level investigations can use container-qualified views with explicit CON_ID matching. Consult DBA_EXTENTS before interpreting file and extent numbers.
| Finding | Candidate response | Evidence needed |
|---|---|---|
| Small, known set of physically corrupt blocks | RMAN block media recovery | Usable block source and required archived redo |
| Widespread or uncertain file damage | Plan data file or broader recovery | Extent of damage, recovery point, and dependencies |
| Damage isolated to an index | Assess index recreation | Healthy base data and a plan for constraints and availability |
| Logical inconsistency or unwanted valid changes | Assess object reconstruction or point-in-time recovery | Known good state and impact on related data |
| No usable recovery source for affected rows | Controlled salvage of accessible data | Explicit acceptance and accounting of data loss |
A table containing customer orders should not be dropped simply because an error names one of its blocks. First determine whether a good copy can restore those rows. Likewise, rebuilding an index cannot supply missing base-table records. Document the selected method, expected downtime, recovery point, and verification criteria so the application owner understands what success will mean.
Consider two incidents with the same initial symptom: a report cannot read an order. In the first, the affected block is known, a usable backup exists, and the required redo is accessible. The plan can focus on recovering that block and retesting the report. In the second, several files have unexplained read failures and the storage team is still investigating. Starting a sequence of isolated repairs may obscure the larger problem. The next useful action is to establish a reliable inventory and recovery source.
Keep availability and completeness as separate acceptance criteria. A service might become available quickly while a subset of historical records remains unresolved. That may be acceptable for one application and unacceptable for another. Record who can make that decision, which operations can resume, and how users will recognize incomplete results. A DBA should not silently convert a recovery incident into a permanent data-retention decision.
For block recovery, connect RMAN to the CDB root as a common user with SYSBACKUP or SYSDBA privileges. Confirm the correct target before submitting a repair. The database must use ARCHIVELOG mode and be mounted or open with a current control file. Review available full or level 0 backups, or other supported good-block sources, plus the archived redo required to bring the block forward.
Check access to backup storage, media-management channels, and any required encryption keystore. A catalog entry is not proof that the underlying backup is readable. Block recovery uses archived redo, and a needed inaccessible log can prevent completion. These requirements are described in the RECOVER command reference.
-- Recover the specific block identified in this example.
RECOVER DATAFILE 5 BLOCK 30123;
For a reviewed inventory of physically corrupt blocks, the following broader command is an alternative. It should not be appended automatically to every individual-block repair:
RECOVER CORRUPTION LIST;
Block recovery can leave the data file online while the affected blocks are unavailable. It is intended for a bounded set of damaged blocks, not an unknown extent of file destruction. Retain the complete RMAN transcript and investigate failures instead of repeatedly changing recovery options until an error disappears. Do not add OPEN RESETLOGS to an ordinary block-recovery procedure.
A suitably configured physical standby in real-time query mode can provide good blocks for recovery. Automatic block repair has Active Data Guard licensing and configuration requirements; merely having a standby, ASM, or cloud storage does not guarantee it. Corruption found by an RMAN validation does not itself trigger that automatic repair path. Verify the supported configuration before relying on standby assistance.
Older runbooks may also recommend Data Recovery Advisor. In Oracle AI Database 26ai, DRA and its LIST FAILURE, ADVISE FAILURE, REPAIR FAILURE, and CHANGE FAILURE commands are desupported. This lesson therefore uses current validation, diagnosis, and recovery commands. Oracle records the change in About RMAN Commands.
When recovery cannot restore the required data, an administrator may consider salvaging accessible rows. Before doing so, preserve the damaged state and available diagnostics, assess supported object types, and obtain the data owner's acceptance of missing records. The following examples describe a nonpartitioned demonstration table. They are separate stages with a decision point between diagnosis and mutation.
Run package administration with the required administrative privileges in the affected container. Create a uniquely named repair table using ADMIN_TABLES; the package creates it in SYS. Here, REPAIR_LESSON4 must not already exist and USERS must be a suitable available tablespace. Do not drop an existing diagnostic table just to reuse an example name.
BEGIN
DBMS_REPAIR.ADMIN_TABLES(
table_name => 'REPAIR_LESSON4',
table_type => DBMS_REPAIR.REPAIR_TABLE,
action => DBMS_REPAIR.CREATE_ACTION,
tablespace => 'USERS');
END;
/
SET SERVEROUTPUT ON
DECLARE
l_corrupt_count BINARY_INTEGER;
BEGIN
DBMS_REPAIR.CHECK_OBJECT(
schema_name => 'HR',
object_name => 'EMPLOYEES',
object_type => DBMS_REPAIR.TABLE_OBJECT,
repair_table_name => 'REPAIR_LESSON4',
corrupt_count => l_corrupt_count);
DBMS_OUTPUT.PUT_LINE('Corruptions reported: ' || l_corrupt_count);
END;
/
SELECT object_name, block_id, marked_corrupt
FROM sys.repair_lesson4;
The corrupt_count argument is an output variable, not an optional comment. Review the recorded findings before proceeding. There is no guaranteed count of one: a real check may report different results or fail for reasons requiring further investigation. The DBMS_REPAIR reference documents procedure signatures, restrictions, and privileges.
The next operations do not restore the damaged rows. FIX_CORRUPT_BLOCKS uses findings from the repair table, rechecks blocks, and marks remaining corrupt blocks software corrupt. The label printed below deliberately describes marking, rather than claiming that lost employee records have returned.
SET SERVEROUTPUT ON
DECLARE
l_fix_count BINARY_INTEGER;
BEGIN
DBMS_REPAIR.FIX_CORRUPT_BLOCKS(
schema_name => 'HR',
object_name => 'EMPLOYEES',
object_type => DBMS_REPAIR.TABLE_OBJECT,
repair_table_name => 'REPAIR_LESSON4',
fix_count => l_fix_count);
DBMS_OUTPUT.PUT_LINE('Blocks marked software corrupt: ' || l_fix_count);
END;
/
-- Separate decision: allow supported scans to skip marked blocks.
BEGIN
DBMS_REPAIR.SKIP_CORRUPT_BLOCKS(
schema_name => 'HR',
object_name => 'EMPLOYEES',
object_type => DBMS_REPAIR.TABLE_OBJECT,
flags => DBMS_REPAIR.SKIP_FLAG);
END;
/
Skipping changes what a successful query means. A result can now omit data from marked blocks. It does not promise that every access path will work: corrupt index root and branch blocks are not skipped like eligible leaf blocks. Treat the salvaged result as incomplete until reconciled. Oracle's corrupted-data administration guide explains the operational tradeoffs.
Copying accessible rows to another table or exporting them with Data Pump does not recreate unreadable rows. Reconstruct missing information from a separately verified source where possible. Review indexes, foreign keys, constraints, triggers, grants, and application relationships when rebuilding objects. A table populated with the remaining rows can still be an incorrect replacement for the original business dataset.
Keep the original diagnostic record alongside the reconstruction record. For each missing group of records, note the source used to replace it, the checks performed, and any uncertainty that remains. If only a historical export is available, distinguish records restored from that export from later changes that still need reconstruction. Do not assume an older export represents the same recovery point as related tables.
Rehearse reconstruction in an isolated environment before switching the application to a replacement object. Use the rehearsal to identify dependencies and establish measurable acceptance checks. Preserve evidence even when the rehearsal succeeds: it explains why a reconstructed dataset is trustworthy and gives the next administrator a way to investigate discrepancies. Removing the skip setting later is also a planned decision; doing so does not reverse lost data or repair the original damaged blocks.
After RMAN recovery, validate the affected file again and review the corruption inventory. Compare the actual results with the original incident record rather than assuming that a successful return code closes the case:
-- RMAN session
VALIDATE CHECK LOGICAL DATAFILE 5;
-- SQL session with appropriate visibility
SELECT con_id, file#, block#, blocks, corruption_type
FROM v$database_block_corruption
ORDER BY con_id, file#, block#;
Then repeat the application operation that exposed the damage and check representative records and relationships. After salvage, a lower row count is an impact to explain, not a cosmetic difference to hide. Compare totals, key coverage, and related records against trusted evidence from before the incident. Record which data was recovered, reconstructed, omitted, or still uncertain.
For example, suppose an employee table becomes queryable after skipping one damaged block. A payroll report returning without error is insufficient acceptance evidence. Compare employee identifiers with an independently trusted roster, investigate missing departments or manager relationships, and reconcile the payroll period's totals. The application owner should approve the resulting dataset based on those checks, rather than on the fact that SQL now completes.
Finally, investigate the cause and protect the next recovery. Correlate database errors with storage, operating-system, and memory diagnostics. Review checksum and block-checking settings against the platform's support guidance and workload cost. Schedule validation and recovery rehearsals, retain sufficient archived redo, and confirm that backups can actually be restored. Multiple archive destinations from the previous lesson help preserve redo availability, but their existence alone does not establish that every required log is usable.
The incident record should include the affected container, files and blocks, original errors, selected recovery method, commands actually executed, verification results, and any accepted data loss. This turns a one-time repair into a repeatable operational procedure. The next lesson introduces Oracle LogMiner and the information available when examining redo activity.
Oracle Database 23c Administration