Showing posts with label Block Corruption. Show all posts
Showing posts with label Block Corruption. Show all posts

Apr 2, 2016

To find segment name from Corrupt Block

Find segment name from Corrupt Block:

Message from Alert Log :


Fri Apr 01 13:56:27 2016
Errors in file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_pr04_4915260.trc:
ORA-00339: archived log does not contain any redo
ORA-00334: archived log: '/u02/flash_recovery_area/PROD/PROD/onlinelog/o1_mf_1_chsdf09j_.log'
Errors in file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_pr04_4915260.trc (incident=4243):
ORA-00600: internal error code, arguments: [kdBlkCheckError], [80], [1288987], [6264], [], [], [], [], [], [], [], []
Incident details in: /u01/app/oracle/diag/rdbms/PROD/PROD/incident/incdir_4243/PROD_pr04_4915260_i4243.trc
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
Slave exiting with ORA-10562 exception
Errors in file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_pr04_4915260.trc:
ORA-10562: Error occurred while applying redo to data block (file# 80, block# 1288987)
ORA-10564: tablespace REGISTRATION
ORA-01110: data file 80: '/u02/flash_recovery_area/PROD/ORADATA/hr01.dbf'
ORA-10561: block type 'TRANSACTION MANAGED DATA BLOCK', data object# 89532
ORA-00600: internal error code, arguments: [kdBlkCheckError], [80], [1288987], [6264], [], [], [], [], [], [], [], []
............................


In the alert log we found that datafile 80 has corrupt block and the dartafile is hr01.dbf. The corrupted block is "1288987".

Then run below query to find segment name :

1) Query-1: Find segment name with owner

SQL> select * from dba_extents where file_id = 80 and 1288987 between block_id and block_id + blocks -1 ; 


2) Query-2: Find object details

SQL> select * from dba_objects where object_name='MLOG$_PATIENT' and object_type='TABLE'; 


It will help you.


Apr 1, 2016

Fix : ORA-10562: Error occurred while applying redo to data block

During recovering in standby using manual process ( no DG configured), I found below error in laert log.

Error in Alert Log:

Thu Mar 31 10:42:10 2016
Dumping diagnostic data in directory=[cdmp_20160331104210], requested by (instance=1, osid=23658610 (PR01)), summary=[incident=4
226].
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
Slave exiting with ORA-10562 exception
Errors in file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_pr01_23658610.trc:
ORA-10562: Error occurred while applying redo to data block (file# 80, block# 1288553)
ORA-10564: tablespace sample
ORA-01110: data file 80: '/u02/flash_recovery_area/PROD/ORADATA/sample01.dbf'
ORA-10561: block type 'TRANSACTION MANAGED DATA BLOCK', data object# 89532
ORA-00600: internal error code, arguments: [kdBlkCheckError], [80], [1288553], [6264], [], [], [], [], [], [], [], []
Recovery Slave PR01 previously exited with exception 10562
Thu Mar 31 10:42:10 2016
Errors with log /u03/restore_archive/2016_03_30/thread_2_seq_625.1575.907832317
MRP0: Background Media Recovery terminated with error 448
Errors in file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_pr00_9109508.trc:
ORA-00448: normal completion of background process
Recovery interrupted!

Solution:

(1) Take backup of related datafiles.(in primary)

e.g.,
RMAN> backup datafile 80 format '/u02/df_80_pr.bk' ;

Now transfer this backup piece to standby server.

(2) In standby : catalog the backup piece location 

RMAN > catalog backuppiece '/u03/backup_files/df_80_pr.bk';

Then list it for confirmation.

RMAN> list backuppiece'/u03/backup_files/df_80_pr.bk';
RMAN> list backup of datafile 80; # Check the backup piece

(3) Cancel MRP if started.

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

(4) Restore from backup piece:

e.g., restore datafile 80; # restore datafile 80 ;

RMAN> restore datafile 80;

Starting restore at 31-MAR-16
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=199 device type=DISK

channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00080 to /u02/flash_recovery_area/PROD/ORADATA/sample01.dbf
channel ORA_DISK_1: reading from backup piece /u03/backup_files/df_80_pr.bk
channel ORA_DISK_1: piece handle=/u03/backup_files/df_80_pr.bk tag=TAG20160331T121840
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:00:45
Finished restore at 31-MAR-16

RMAN>

(5) Start the MRP in standby:

SQL> alter database recover managed standby database disconnect ;

Sure, It will apply archivelogs again.

Thanks .


Fix : DBV-00008: USERID must be specified for OSM files

One of my friend get below error while running dbv command for a datafile which was available in ASM disk group.

Err:   DBV-00008: USERID must be specified for OSM files

Here is sample error:

$ dbv file='+DATA/PROD/datafile/sample01.dbf'

DBVERIFY: Release 11.2.0.4.0 - Production on Fri Apr 1 14:02:30 2016

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.


DBV-00008: USERID must be specified for OSM files


So, you give the username and password via userid, then it will work fine.

Sample Example :

$ dbv userid=registration/reg40 file=+DATA/PROD/datafile/sample01.dbf 

DBVERIFY: Release 11.2.0.4.0 - Production on Fri Apr 1 14:05:27 2016

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

DBVERIFY - Verification starting : FILE = +DATA/PROD/datafile/sample01.dbf


DBVERIFY - Verification complete

Total Pages Examined         : 1365512
Total Pages Processed (Data) : 836672
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 84780
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 360647
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 83413
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Total Pages Encrypted        : 0
Highest block SCN            : 0 (0.0)



Thanks .

Aug 25, 2015

Fix block corruption via RMAN - Pains & Gains of NOLOGGING mode in Oracle database

Fix block corruptions via RMAN using Oracle 11gR2
Pains & Gains of NOLOGGING mode in Oracle database

a) About NOLOGGING
b) FORCE LOGGING Options
c) Gains of NO LOGGING
d) Detection of Nologging Operations On the Primary and Standby Databases
e) An workaround to fix block corruption via RMAN

f) Best practice to avoid block corruptions
------------------------------------------------------------------------


a) About NoLOGGING Operation:


The FORCE LOGGING option is the safest method to ensure that all the changes made in the database will be captured and available for recovery in the redo logs. Force logging is the new feature added to the family of logging attributes.

Before the existence of FORCE LOGGING, Oracle provided logging and nologging options. These two options have higher precedence at the schema object level than the tablespace level; therefore, it was possible to override the logging settings at the tablespace level with nologging setting at schema object level.

The FORCE LOGGING option can be set at the database level or the tablespace level. The precedence is from database to tablespace. If a tablespace is created or altered to have FORCE LOGGING enabled, any change in that tablespace will go into the redo log and be usable for recovery.

Similarly, if a database is created or altered to have the FORCE LOGGING enabled, any change across the database, with exception of temporary segments and temporary tablespace, will be available in redo logs for recovery. The FORCE LOGGING option can be set at database creation time or later using the alter database command.

To enable FORCE LOGGING after the database is created, use the following command:

ALTER DATABASE FORCE LOGGING;

b) FORCE LOGGING Options:

1) Database level:
  -- Enable
SQL> ALTER DATABASE FORCE LOGGING;
  -- Disable
SQL> ALTER DATABASE NO FORCE LOGGING;


b) Tablespace Level:
-- Disable
SQL> ALTER TABLESPACE <tablespace_name> NO FORCE LOGGING;
-- Enable
SQL> ALTER TABLESPACE <tablespace name> FORCE LOGGING;

c) Table level:
-- Disable
SQL> ALTER TABLE <table_name> NOLOGGING;
-- Enable
SQL> ALTER TABLE <table_name> NOLOGGING;
Note:

Temporary tablespaces and temporary segments have no effect during FORCE LOGGING mode because these objects do not generate any redo. Undo tablespaces are in FORCE LOGGING mode by default, so they cannot be put into FORCE LOGGING mode. Oracle will generate an error if an attempt is made to put a temporary tablespace or undo tablespace into FORCE LOGGING mode.

The FORCE_LOGGING column of v$database view can be queried to verify that the database is in FORCE LOGGING mode. Similarly, the FORCE_LOGGING column of dba_tablespaces view provides the same logging information for each tablespace.

select force_logging from v$database;
select force_logging from dba_tablespaces;



Warning !!!

Putting a database in FORCE LOGGING mode will have some performance impact.


c) Gains of NO LOGGING:

Nologging operations indicate that the database operation is not logged in the online redo log file. Even though a small invalidation redo record is still written to the online redo log file, nologging operations skip the redo generation of the corresponding DML data.  Nologging can be extremely beneficial for the following reasons:
  • data written to the redo is minimized dramatically
  • time to insert into a large table or index or LOB can be reduced dramatically
  • performance improves for parallel creation of large tables or indices
However, NOLOGGING is intended for configurations in which media recovery or the recovery of the corresponding object is not important. Thus, if the disk or tape or storage media fails, you will not be able to recover your changes from the redo because the changes were never logged. 

d) Detection of Nologging Operations On the Primary and Standby Databases

On the primary database, you can monitor for the most recent nologging operation that occurred in the database by issuing the following query:

         SELECT NAME, UNRECOVERABLE_CHANGE#,               
         TO_CHAR (UNRECOVERABLE_TIME,'DD-MON-YYYY HH:MI:SS')
         FROM V$DATAFILE;


The above primary database's query dictates when the most recent nologging operation occurred and when the invalidation redo was written to the redo.  Once Redo Apply (or Media Recovery) processes the invalidation redo, it marks all the corresponding data blocks corrupt.  You will detect encounter corrupted blocks on the physical standby database when you query any data that references these data blocks.   You will receive the following errors: 

                ORA-01578: ORACLE data block corrupted (file # 3, block # 514)
                ORA-01110: data file 3: '/oracle/oradata/PROD/users.dbf'
                ORA-26040: Data block was loaded using the NOLOGGING option


You can proactively catch some of these corrupted blocks on Redo Apply (or media recovery) instance by running DBVERIFY on the data files.

Example :
           
$ cd /oracle/oradata/PROD
$ dbv file=users01.dbf

DBVERIFY: Release 11.2.0.4.0 - Production on Tue Aug 25 16:41:53 2015

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

DBVERIFY - Verification starting : FILE = /oracle/oradata/PROD/users01.dbf

DBV-00201: Block, DBA 17162242, marked corrupt for invalid redo application
DBV-00201: Block, DBA 17162244, marked corrupt for invalid redo application
...
...
DBV-00201: Block, DBA 17162493, marked corrupt for invalid redo application


DBVERIFY - Verification complete

Total Pages Examined         : 407680
Total Pages Processed (Data) : 221830
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 1257
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 175354
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 9239
Total Pages Marked Corrupt   : 111
Total Pages Influx           : 0
Total Pages Encrypted        : 0
Highest block SCN            : 2355429844 (29.2355429844)
 

$ SQL apply ignores the invalidation redo since it cannot convert it to any reasonable SQL; so, the logical standby will not receive any immediate errors.   If future transactions reference the missing data, then apply slave will receive an ORA-01403 in the alert.log.  

For example, the following UPDATE statement failed on the logical standby because it was referencing  'nologged' rows that do not exist on the logical standby database.

-- Repair of Nologged Changes on the Physical and Logical Standby Databases:

After a nologged operation on the primary is detected, it is recommended to create a backup immediately if you want to recover from this operation in the future.  However there are additional steps required if you have an existing physical or logical standby database.    This is crucial if you want to preserve the data integrity of your standby databases.

For a physical standby database, Redo Apply will process the invalidation redo and mark the corresponding data blocks corrupt.

For a physical standby database, follow these steps to reinstantiate the relevant data files .

    1. stop Redo Apply (recover managed standby database cancel)
    2. offline corresponding datafile(s) (alter database datafile <NAME> offline drop;)
    3. start Redo Apply (recover managed standby database disconnect)
    4. copy the appropriate backup datafiles over from the primary database (e.g. use RMAN to backup datafiles and copy them)
    5. stop Redo Apply (recover managed standby database cancel)
    6. online corresponding data files (alter database datafile <NAME> online;)
    7. start Redo Apply (recover managed standby database disconnect)

======================
Solution with an workaround:
======================

As per above section, we can use this procedure if RMAN backup has not failed while reading the corrupt block. To determine the same, run a backup on the datafile having the corrupt block:

RMAN> backup check logical datafile 7 format '/u03/backup/%U' tag 'CORRUPT_BLK_FILE_BKP';

Starting backup at 24-AUG-15
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00007 name=/oracle/oradata/PROD/demo01.dbf
channel ORA_DISK_1: starting piece 1 at 24-AUG-15
channel ORA_DISK_1: finished piece 1 at 24-AUG-15
piece handle=/u03/backup/1jnbhl5c_1_1 tag=CORRUPT_BLK_FILE_BKP comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 24-AUG-15


Ensure that the location where backup-piece will be created has sufficient space. You can change this destination using the FORMAT clause. Also, even though the backup seems successful, crosscheck using
below query that the corrupt block is not contained in the backup:

SQL> select BP.HANDLE, BP.COMPLETION_TIME, BC.FILE#, BC.BLOCK#, BC.BLOCKS, BC.MARKED_CORRUPT, BC.CORRUPTION_TYPE
    from V$BACKUP_PIECE BP, V$BACKUP_CORRUPTION BC
    where BP.SET_COUNT = BC.SET_COUNT and
          BP.SET_STAMP = BC.SET_STAMP and
          BP.TAG = 'CORRUPT_BLK_FILE_BKP';


no rows selected.

If the above query returns rows showing the corrupt block, we cannot use this procedure. In above case, since it has not returned rows, we can be sure that RMAN has skipped the corrupt block due to unused block optimization algorithm described above. Now, if the datafile is restored from this backup, RMAN will format and restore a empty copy of the corrupt block which can then be used for rman block recovery as below.

1. Restore the datafile to alternate location:

RMAN> run {
2> set newname for datafile 7 to '/oracle/oradata/PROD/demo01_RESTORED.dbf';
3> restore datafile 7 from tag 'CORRUPT_BLK_FILE_BKP';
4> }

executing command: SET NEWNAME

Starting restore at 24-AUG-15
using channel ORA_DISK_1

channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00007 to /oracle/oradata/PROD/demo01_RESTORED.dbf
channel ORA_DISK_1: reading from backup piece /u03/backup/1jnbhl5c_1_1
channel ORA_DISK_1: piece handle=/u03/backup/1jnbhl5c_1_1 tag=CORRUPT_BLK_FILE_BKP
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:00:03
Finished restore at 24-AUG-15


2. Run DBV on the restored datafile to verify it is free from corruption:

$ dbv file=/oracle/oradata/PROD/demo01_RESTORED.dbf blocksize=8192


DBVERIFY: Release 11.2.0.4.0 - Production on Tue Aug 25 17:01:13 2015

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

DBVERIFY - Verification starting : FILE = /oracle/oradata/PROD/demo01_RESTORED.dbf

DBVERIFY - Verification complete

Total Pages Examined         : 12800
Total Pages Processed (Data) : 0
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 12799
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 1
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Total Pages Encrypted        : 0
Highest block SCN            : 775154 (0.775154)


3. Run BLOCKRECOVER command as below to repair the corrupt block.

The corrupt block will be replaced by the empty, formatted block from the restored datafile:

RMAN> blockrecover datafile 7 block 150 FROM DATAFILECOPY;

Starting recover at 24-AUG-15
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=22 device type=DISK

channel ORA_DISK_1: restoring block(s) from datafile copy /oracle/oradata/PROD/demo01_RESTORED.dbf

starting media recovery
media recovery complete, elapsed time: 00:00:01


Finished recover at 24-AUG-154. 

Run DBV on the original file to confirm that it is now free from corruption:


$ dbv file=/oracle/oradata/PROD/demo01.dbf blocksize=8192

DBVERIFY: Release 11.2.0.4.0 - Production on Tue Aug 25 17:11:33 2015

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

DBVERIFY - Verification starting : FILE = /oracle/oradata/PROD/demo01.dbf

DBVERIFY - Verification complete

Total Pages Examined         : 12800
Total Pages Processed (Data) : 356
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 0
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 152
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 12292
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Total Pages Encrypted        : 0
Highest block SCN            : 775154 (0.775154)


5. Additionally, you can run VALIDATE in RMAN to verify further:

RMAN> backup validate check logical datafile 7;

Starting backup at 24-AUG-15
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=22 device type=DISK
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00007 name=/oracle/oradata/PROD/demo01.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
7    OK     0              12292        12801           775154
  File Name: /oracle/oradata/PROD/demo01.dbf
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       0              356
  Index      0              0
  Other      0              152

Finished backup at 24-AUG-15


f) Best practices to avoid block corruptions:

Regular and proactive checking of the database for corruptions:

1. Run the DBVerify utility against the datafile at a periodic intervals, to check for any physical corruption.

e.g.,
dbv file=system01.dbf blocksize=8192

2.  Run object level analyze command at a periodic intervals. This will check for logical inconsistencies and even detect physical corruptions. It is important to note that this command locks the object, which is  being  analyzed so need to be performed at off-peak hours. The online option available with analyze helps
in removing this restriction to some extent.( IN OFF PAEK HOURS only)

e.g.,
SQL> Analyze table <user>.<table_name> validate structure cascade [online];
SQL> Analyze index <user>.<index_name/cluster_name> validate structure;
     
   For partition table analyze, the utlvalid.sql script must be run to create invalid_rows table If not run you need to run the below analyze command instead.

SQL> Analyze table <user>.<table_name> partition <partition_name> validate structure cascade into invalid_rows;

3. Always take full database export backup ( use EXPDP/ EXP)

e.g.,
expdp directory=dir_name dumpfile=dump_name.dmp logfile=log_name.log full=y

Note : As per requirement you can add many more parameters. Use expdp -help to see details.

Click here to read more about expdp

4. Ensuring the data free of corruptions when doing a bulk load. After the dataload, perform normal
   validations(select/analyze/export) to detect corruptions, if introduced while loading.

5. Use RMAN to check the existence of physical and logical corruption.

e.g.to validate the complete database

RMAN> BACKUP CHECK LOGICAL VALIDATE DATABASE;

Note: See the above document to know more about RMAN validation.

6. Use DBMS_REPAIR package to verify corruption in an object and can use this package to mark the block as soft corrupt.

DBMS_REPAIR.CHECK_OBJECT :CHECK_OBJECT procedure checks the specified object and populates the repair
table with information about corruption and repair directive(s). Validation consists of block checking all blocks in the object. All blocks previously marked corrupt will be skipped.

Click here to read more...

7. Run Memory/Hardware diagnostics periodically.

8. Set block checking parameters.

DB_BLOCK_CHECKING = TRUE (FULL from 10.2 onwards)
DB_BLOCK_CHECKSUM = TRUE (FULL from 10.2 onwards)
_DB_BLOCK_CHECK_FOR_DEBUG = TRUE

Note : Enable these parameter has performance impact. Don't go above parameters unless untill load test clarification. See more documents in Oracle site.

11g specific:

* DB_ULTRA_SAFE = { OFF | DATA_ONLY | DATA_AND_INDEX }

Click here to read "Best Practices for Avoiding and Detecting Corruption" (Doc ID 428570.1)

Aug 7, 2015

ORA-00399: corrupt change description in redo log : a workaround

Fix : ORA-00399: corrupt change description in redo log

In one of my test instance I found below issues and fixed with given workaround. You can try this.

SQL> startup;
ORACLE instance started.
.........
Database mounted.
ORA-00399: corrupt change description in redo log
ORA-00353: log corruption near block 113746 change 123790201307 time 08/07/2015
10:23:06
ORA-00312: online log 5 thread 1: '/u02/oracle/oradata/testdb/redo05.log'
SQL>


SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open


SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: '/u02/oracle/oradata/testdb/system01.dbf'

Reason and Prerequisites:

In general, the above errors suggest that the redo log is corrupt. A repair for these types of  inconsistencies is not supported. In almost all cases, hardware problems trigger these errors If the process of recovering a redo log terminates with one of the above errors, you can no longer import the subsequent redo logs, for the sake of transaction consistency. In the worst-case scenario, you can only perform a partial recovery before the redo log in question. All subsequent changes then disappear.

If you receive one of the above errors when archiving an online redo log, you can usually solve this problem without any data loss.  In this case, additional errors such as ORA-00255 or ORA-16038 usually occur.

Note 540463 contains information about how to proactively check the redo log consistency.
Note 1016173 describes the redo log validation using RMAN.


My workaround:

SQL> select name,open_mode from v$database;

NAME      OPEN_MODE
--------- --------------------
TESTDB    MOUNTED

SQL> col FIRST_CHANGE# format 99999999999999;
SQL>
SQL> select group#,status,archived,sequence#,first_change# from v$log;

    GROUP# STATUS           ARC  SEQUENCE#   FIRST_CHANGE#
---------- ---------------- --- ---------- ---------------
         5 CURRENT          NO       29551    123790176390
         6 ACTIVE           NO       29550    123790099280
         7 INACTIVE         YES          1    120240973534
         8 UNUSED           YES          0               0

SQL>


Do below as per the "status":

1) If 'status' = INACTIVE you are lucky, you can clear the group:

SQL> alter database clear <unarchived> logfile group n;
(use 'unarchived' when 'archived' shows 'NO') .

2) If 'status' = ACTIVE try

SQL> alter database checkpoint;,

if this command executes successfully, logfile gets status INACTIVE and again you can clear the

logfile, if not you have to handle the logfile as CURRENT.

3) If 'status' = CURRENT you must do an incomplete recovery up to the latest usable SCN:



restore database until scn <first_change#_of_current_logfile>;
recover database until scn <first_change#_of_current_logfile>;
alter database open resetlogs;

e.g.,

RMAN> restore database until scn 123790176390;

RMAN> recover database until scn 123790176390;

SQL> alter database open resetlogs;


Note : If issue is not resolved, then restore from fresh backups.

Jul 24, 2014

Block corruption & Correction: a case study

Logical Block corruption & Correction: a case study

In one of a production database, I have received following errors in UI ( front-end) and back-end as well though mail. I started investigation though logs and conclude about logical corruption with few requested logs. Please go through my analysis.

1) Error received Front End :

Timestamp: 7/22/2014 4:21:34 PM
Message: OraDataServiceProvider.AddIssueDetails Message : ORA-01476: divisor is equal to zero
ORA-06512: at "SALES.F_UPDATEINVENOTARY", line 517
ORA-00600: internal error code, arguments: [4511], [], [], [], [], [], [], [], [], [], [], []
ORA-06512: at "SALES.P_ADDISSUE", line 334
ORA-06512: at line 1
----------------------------------------
Timestamp: 7/22/2014 4:21:34 PM
Message: OraDataServiceProvider.AddIssueDetails StackTrace :    at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, 
OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck)
   at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, 
IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, Boolean bCheck)
   at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
   at eHIS.OracleDataAccessHelper.ORACLEHelper.ExecuteNonQuery(String connectionString, CommandType cmdType, String 
sqlCommandText, OracleParameter[] parameterArray)
   at eHIS.SALES.DataAccess.OraDataServiceProvider.AddIssueDetails(String Issue, String& IssueCode)

2)Error received back End : ( in alert log)

2.1) from alert Log:

Tue Jul 22 17:05:49 2014
Errors in file /u01/app/oracle/diag/rdbms/prod/PROD1/trace/PROD1_ora_11731176.trc  (incident=82147):
ORA-00600: internal error code, arguments: [4511], [], [], [], [], [], [], [], [], [], [], []
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.

2.2) from related .trc file:

DDE: Problem Key 'ORA 600 [4511]' was flood controlled (0x6) (incident: 82875)
ORA-00600: internal error code, arguments: [4511], [], [], [], [], [], [], [], [], [], [], []
DDE: Problem Key 'ORA 600 [4511]' was flood controlled (0x6) (incident: 82876)
*** 2014-07-22 16:44:40.284
*** CLIENT ID:() 2014-07-22 16:44:40.284

ORA-00600: internal error code, arguments: [4511], [], [], [], [], [], [], [], [], [], [], []

2.3) from related incident .trc file:

Dump continued from file: /u01/app/oracle/diag/rdbms/prod/PROD2/trace/PROD2_ora_13893936.trc
ORA-00600: internal error code, arguments: [4511], [], [], [], [], [], [], [], [], [], [], []

========= Dump for incident 95001 (ORA 600 [4511]) ========
*** 2014-07-22 16:22:26.385
dbkedDefDump(): Starting incident default dumps (flags=0x2, level=3, mask=0x0)
----- Current SQL Statement for this session (sql_id=8ax21gq9d3rb1) -----
UPDATE BOOKSTORE I SET I.QOHISTORY = (SELECT SUM(QTY) FROM QOHISTORY WHERE BOOKCODE = :B2 AND STORECODE = :B1 ), 

I.HOLDQOHISTORY=I.HOLDQOHISTORY+ABS(:B3 ) WHERE I.BOOKCODE = :B2 AND I.STORECODE = :B1 
----- PL/SQL Stack -----
----- PL/SQL Call Stack -----
  object      line  object
  handle    number  name
7000003c7a76dd8       241  function SALES.F_UPDATEINVENOTARY
7000004b1c7e110       334  procedure SALES.P_ADDISSUE
7000004aecaf568         1  anonymous block


3) Issue Description:

From the above errors I investigated related procedure and function. From the error, it seems there is a transaction issue with "BOOKSTORE" table. Same issue also logged by support team. But ORA-00600 is related to so many bugs. But this error which is clearly described in related incident .trc file that no update is happening in "BOOKSTORE" table. So initially it is clear. But we need to investigate more and confirm about the issue.

Note: From all all alert logs ( both node) and incident file, I came to know two table corrupted logically. BOOKSTORE and PURCHASEITEMS.

4) Confirmation investigations:

Here are some confirmation investigations:

4.1) Analyze the structure for validation:

e.g.,
While running "analyze table SALES.PURCHASEITEMS validate structure online;", we are getting below error:

SQL> analyze table SALES.PURCHASEITEMS validate structure online;
analyze table SALES.PURCHASEITEMS validate structure online
*
ERROR at line 1:
ORA-01498: block check failure - see trace file

Then I started tracing this with following way:

Analyze the table and upload tracefile generated if analyze fails, trace name should end in _ANALYZE.trc.

SQL> alter session set tracefile_identifier='ANALYZE';
SQL> analyze table SALES.PURCHASEITEMS validate structure online;

Here are some contents from generated .trc file:

*** 2014-07-17 21:33:09.884
*** SESSION ID:(408.36503) 2014-07-17 21:33:09.884
*** CLIENT ID:() 2014-07-17 21:33:09.884
*** SERVICE NAME:(SYS$USERS) 2014-07-17 21:33:09.884
*** MODULE NAME:(sqlplus@ehdb2 (TNS V1-V3)) 2014-07-17 21:33:09.884
*** ACTION NAME:() 2014-07-17 21:33:09.884

Block Checking: DBA = 185398234, Block Type = KTB-managed data block
data header at 0x70000017729c0ac
kdbchk: row locked by non-existent transaction
        table=0   slot=19
        lockid=4   ktbbhitc=5
Block header dump:  0x0b0cf3da
 Object id on Block? Y
 seg/obj: 0x122c8  csc: 0x0f.e2b866de  itc: 5  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0xb0cf300 ver: 0x01 opc: 0
     inc: 0  exflg: 0

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x001d.011.000237cd  0x01001e9e.4eb3.2a  C---    0  scn 0x000e.fa71110c
0x02   0x0177.008.000004cd  0x0100022d.0092.11  C---    0  scn 0x000e.5f6767bd
0x03   0x0092.00b.0003c7b9  0x00c0d3e4.7168.0b  C---    0  scn 0x000e.aebfb808
0x04   0x000d.01f.0006477b  0x0107008d.c219.25  C---    0  scn 0x000e.d03f9c6f
0x05   0x0017.001.00036313  0x01017ea0.67db.36  C---    0  scn 0x000e.fa70d161
bdba: 0x0b0cf3da
data_block_dump,data header at 0x70000017729c0ac
===============
tsiz: 0x1f50
hsiz: 0x8c
pbl: 0x70000017729c0ac
     76543210
flag=--------
ntab=1
nrow=61
frre=-1
fsbo=0x8c
fseo=0x952
avsp=0x909
tosp=0x924
...........
..........

But this may not understandable directly unless we do readable form. If you have Oracle support ID, then you can raise SR and upload this trace file. If without error stucture validated, probably there is other cause. Then let us proceed

some other tests.

4.2) Using RMAN method:

check the files used by these two tables PURCHASEITEMS and BOOKSTORE with RMAN to see how many blocks are affected

$ rman target / nocatalog

b) RMAN> run {
allocate channel d1 type disk;
allocate channel d2 type disk;
allocate channel d3 type disk;
allocate channel d4 type disk;
backup check logical validate datafile x,y,z;
}

/** where x,y,z should be replaced by the file#

Output:

$ rman target / nocatalog

RMAN>

run { 
allocate channel d1 type disk; 
allocate channel d2 type disk; 
allocate channel d3 type disk; 
allocate channel d4 type disk; 
backup check logical validate datafile 44,45,46; 
} 2> 3> 4> 5> 6> 7> 

allocated channel: d1
channel d1: SID=39 instance=PROD1 device type=DISK

allocated channel: d2
channel d2: SID=424 instance=PROD1 device type=DISK

allocated channel: d3
channel d3: SID=629 instance=PROD1 device type=DISK

allocated channel: d4
channel d4: SID=1358 instance=PROD1 device type=DISK

Starting backup at 22-JUL-14
channel d1: starting full datafile backup set
channel d1: specifying datafile(s) in backup set
input datafile file number=00044 name=+DATA/prod/datafile/sales01.dbf
channel d2: starting full datafile backup set
channel d2: specifying datafile(s) in backup set
input datafile file number=00045 name=+DATA/prod/datafile/sales_index01.dbf
channel d3: starting full datafile backup set
channel d3: specifying datafile(s) in backup set
input datafile file number=00046 name=+DATA/prod/datafile/sales_indx_01.dbf
channel d3: backup set complete, elapsed time: 00:00:16
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
46   OK     0              309          18640           24375064492
  File Name: +DATA/prod/datafile/sales_indx_01.dbf
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       0              0               
  Index      0              17782           
  Other      0              549             

channel d2: backup set complete, elapsed time: 00:01:19
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
45   OK     0              37946        664640          88021468605
  File Name: +DATA/prod/datafile/sales_index01.dbf
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       0              0               
  Index      0              616016          
  Other      0              10678          

channel d1: backup set complete, elapsed time: 00:01:32
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
44   FAILED 0              48213        963536          88021469422
  File Name: +DATA/prod/datafile/sales01.dbf
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       7              907742          
  Index      0              1               
  Other      0              7580          

validate found one or more corrupt blocks
See trace file /u01/app/oracle/diag/rdbms/prod/PROD1/trace/PROD1_ora_21823514.trc for details
Finished backup at 22-JUL-14
released channel: d1
released channel: d2
released channel: d3
released channel: d4

RMAN> 

RMAN> quit


Recovery Manager complete.


Here, RMAN reported no. of blocks corrupted with this statement, "Block Type Blocks Failing Blocks Processed". i.e., here we have some confirmation about block corruption. Next we will do some acid tests for max clarity.

4.3) Using DBMS packages:

Pre-requisites:

a) create 'REPAIR_TABLE' table :
Examples: Building a Repair Table or Orphan Key Table
The ADMIN_TABLE procedure is used to create, purge, or drop a repair table or an orphan key table.
A repair table provides information about the corruptions that were found by the CHECK_OBJECT procedure and how these will be addressed if the FIX_CORRUPT_BLOCKS procedure is run. Further, it is used to drive the execution of the FIX_CORRUPT_BLOCKS procedure.

Example: Creating a Repair TableThe following example creates a repair table for the users tablespace.

SET SERVEROUTPUT ON
BEGIN
DBMS_REPAIR.ADMIN_TABLES (
     TABLE_NAME => 'REPAIR_TABLE',
     TABLE_TYPE => dbms_repair.repair_table,
     ACTION     => dbms_repair.create_action,
     TABLESPACE => 'USERS');
END;
/

b) Detecting Corruption :

The CHECK_OBJECT procedure checks the specified object, and populates the repair table with information about corruptions and repair directives. You can optionally specify a range, partition name, or subpartition name when you want to check a portion of an object.

Validation consists of checking all blocks in the object that have not previously been marked corrupt. For each block,  the transaction and data layer portions are checked for self consistency. During CHECK_OBJECT, if a block is encountered that has a corrupt buffer cache header, then that block is skipped.

The following is an example of executing the CHECK_OBJECT procedure for the SALES.PURCHASEITEMS table.

SET SERVEROUTPUT ON
DECLARE num_corrupt INT;
BEGIN
num_corrupt := 0;
DBMS_REPAIR.CHECK_OBJECT (
     SCHEMA_NAME => 'SALES',
     OBJECT_NAME => 'PURCHASEITEMS',
     REPAIR_TABLE_NAME => 'REPAIR_TABLE',
     CORRUPT_COUNT =>  num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt));
END;
/

output:

number corrupt: 2

PL/SQL procedure successfully completed

set serveroutput on
DECLARE num_corrupt INT;
BEGIN
num_corrupt := 0;
DBMS_REPAIR.CHECK_OBJECT (
SCHEMA_NAME => 'SALES',
OBJECT_NAME => 'BOOKSTORE',
REPAIR_TABLE_NAME => 'REPAIR_TABLE',
corrupt_count => num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt));
END;
/

output:
number corrupt: 5

PL/SQL procedure successfully completed

Here it is confirmed, no. of corrupted blocks.

Run the below view to find comoplete information:

SQL> SELECT OBJECT_NAME, BLOCK_ID, CORRUPT_TYPE, MARKED_CORRUPT,CORRUPT_DESCRIPTION, REPAIR_DESCRIPTION
FROM REPAIR_TABLE;
OR
select object_id,object_name,BLOCK_ID, CORRUPT_TYPE, CORRUPT_DESCRIPTION from REPAIR_TABLE;

see: corrupt_blocks_output.xls



5) Corrective actions:

5.1) I can recommend some simplest method which needs to perform in downtime: Create copy tables after disbling constraints and truncate the currupted tables and then re-insert them. Example:


Step_1: take the counts
Check counts:

select count(1) from SALES.PURCHASEITEMS -- 491609
select count(1) from SALES.copy_PURCHASEITEMS -- 491609
select count(1) from SALES.BOOKSTORE -- 168806
select count(1) from  SALES.copy_BOOKSTORE -- 168806

Step_2: Take logical backup -- when downtime starts, to avoid any other issues if entire schema size is less or take only required tables.

$ expdp directory=DATA_PUMP dumpfile=sales_22Jul14.dmp logfile=sales_22Jul14_exp.log schemas=SALES parallel=3 exclude=statistics cluster=NO

Step_3: Create copy table for two issued tables:

create table copy_PURCHASEITEMS as select * from SALES.PURCHASEITEMS;
alter table SALES.PURCHASEITEMS disable constraint FK_PURCHASEITEMS_PO;
truncate table SALES.PURCHASEITEMS;
insert into SALES.PURCHASEITEMS select * from SALES.copy_PURCHASEITEMS;
alter table SALES.PURCHASEITEMS enable constraint FK_PURCHASEITEMS_PO;

create table SALES.copy_BOOKSTORE as select * from SALES.BOOKSTORE ;
truncate table SALES.BOOKSTORE;
insert into SALES.BOOKSTORE select * from SALES.copy_BOOKSTORE;


Step_4: Analyze tables:

exec dbms_stats.gather_table_stats(ownname => 'SALES',tabname => 'PURCHASEITEMS',cascade => TRUE);
exec dbms_stats.gather_table_stats(ownname => 'SALES',tabname => 'BOOKSTORE',cascade => TRUE);


5.2) Using DBMS Packages

Fixing Corrupt Blocks

Use the FIX_CORRUPT_BLOCKS procedure to fix the corrupt blocks in specified objects based on information in the repair table that was generated by the CHECK_OBJECT procedure. Before changing a block, the block is checked to ensure that the block is still corrupt. Corrupt blocks are repaired by marking the block software corrupt. When a repair is performed, the associated row in the repair table is updated with a timestamp.

This example fixes the corrupt block in table SALES.PURCHASEITEMS that was reported by the CHECK_OBJECT procedure.

SET SERVEROUTPUT ON
DECLARE num_fix INT;
BEGIN
num_fix := 0;
DBMS_REPAIR.FIX_CORRUPT_BLOCKS (
     SCHEMA_NAME => 'SALES',
     OBJECT_NAME=> 'PURCHASEITEMS',
     OBJECT_TYPE => dbms_repair.table_object,
     REPAIR_TABLE_NAME => 'REPAIR_TABLE',
     FIX_COUNT=> num_fix);
DBMS_OUTPUT.PUT_LINE('num fix: ' || TO_CHAR(num_fix));
END;
/

Simple & strait workaround:

-- start DBMS API to skip corrupt block flag

BEGIN
DBMS_REPAIR.SKIP_CORRUPT_BLOCKS (
SCHEMA_NAME => 'SALES',
OBJECT_NAME => 'BOOKSTORE',
OBJECT_TYPE => dbms_repair.table_object,
FLAGS => dbms_repair.SKIP_FLAG);
END;
/

-- Create a repair table

> create table SALES.BOOKSTORE_REPAIR as select * from SALES.BOOKSTORE;

-- Check counts

select count(*) from SALES.BOOKSTORE;
select count(*) from SALES.BOOKSTORE_REPAIR;

-- If the count is close 

>truncate table SALES.BOOKSTORE;
>insert into SALES.BOOKSTORE select * from SALES.BOOKSTORE_REPAIR;

Note: In my experience, I found some junk data updated in table and anonyms row inserted in the table. Manually data corrected and anaonymous record deleted with a pl/sql programming. Here are few errors:
error-1:
insert into SALES.BOOKSTORE
select * from SALES.servicerequestdetails_repair ;

ORA-12899: value too large for column "SALES"."BOOKSTORE"."EXTRACHARGEFLAG" (actual: 83, maximum: 5)

error-2:
insert into SALES.BOOKSTORE
select * from SALES.BOOKSTORE_repair ;

ORA-12899: value too large for column "SALES"."BOOKSTORE"."CONSULTATIONDATE" (actual: 120, maximum: 7)

etc.

-- after correction, check the counts again.

>select count(*) from SALES.BOOKSTORE;
>select count(*) from SALES.BOOKSTORE_REPAIR;

-- Again set "no skip" flag

BEGIN
DBMS_REPAIR.SKIP_CORRUPT_BLOCKS (
SCHEMA_NAME => 'SALES',
OBJECT_NAME => 'BOOKSTORE',
OBJECT_TYPE => dbms_repair.table_object,
FLAGS => dbms_repair.NOSKIP_FLAG);
END;
/

-- Analyze the table


exec DBMS_STATS.gather_table_stats(ownname=> 'SALES',tabname=>'BOOKSTORE',estimate_percent => 100,cascade=>TRUE,degree=>1,granularity=>'AUTO',method_opt=>'FOR ALL INDEXED COLUMNS SIZE AUTO');

-- To validate database and backup sets




Start RMAN and connect to a target database.
Execute the VALIDATE command with the desired options.
For example, to validate all datafiles and control files (and the server parameter file if one is in use), execute the following command at the RMAN prompt:
RMAN> VALIDATE DATABASE;
e.g.,
RMAN> VALIDATE DATABASE;

Starting validate at 15-MAY-15
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=547 device type=DISK
channel ORA_DISK_1: starting validation of datafile
channel ORA_DISK_1: specifying datafile(s) for validation
input datafile file number=00053 name=/oradata/datafiles/PROD/PAYROLL01.dbf
......
.....

-- Validate backupset:
Alternatively, you can validate a particular backup set by using the form of the command shown in the following example (sample output included).
RMAN> VALIDATE BACKUPSET 22;

Below query can be used to find any corrupted block is avialbe in database or not:

set head on; 
set pagesize 2000 
set linesize 250 
select * from v$database_block_corruption;
SELECT e.owner, e.segment_type, e.segment_name, e.partition_name, c.file# 
, greatest(e.block_id, c.block#) corr_start_block# 
, least(e.block_id+e.blocks-1, c.block#+c.blocks-1) corr_end_block# 
, least(e.block_id+e.blocks-1, c.block#+c.blocks-1) 
- greatest(e.block_id, c.block#) + 1 blocks_corrupted 
, null description 
FROM dba_extents e, v$database_block_corruption c 
WHERE e.file_id = c.file# 
AND e.block_id <= c.block# + c.blocks - 1 
AND e.block_id + e.blocks - 1 >= c.block# 
UNION 
SELECT s.owner, s.segment_type, s.segment_name, s.partition_name, c.file# 
, header_block corr_start_block# 
, header_block corr_end_block# 
, 1 blocks_corrupted 
, 'Segment Header' description 
FROM dba_segments s, v$database_block_corruption c 
WHERE s.header_file = c.file# 
AND s.header_block between c.block# and c.block# + c.blocks - 1 
UNION 
SELECT null owner, null segment_type, null segment_name, null partition_name, c.file# 
, greatest(f.block_id, c.block#) corr_start_block# 
, least(f.block_id+f.blocks-1, c.block#+c.blocks-1) corr_end_block# 
, least(f.block_id+f.blocks-1, c.block#+c.blocks-1) 
- greatest(f.block_id, c.block#) + 1 blocks_corrupted 
, 'Free Block' description 
FROM dba_free_space f, v$database_block_corruption c 
WHERE f.file_id = c.file# 
AND f.block_id <= c.block# + c.blocks - 1 
AND f.block_id + f.blocks - 1 >= c.block# 
order by file#, corr_start_block#; 






Note: If you have "NOLOGING" block corruption, you can follow aboev method, but in alert log message will come. Below query can be used to find "NOLOGGING" block corruptions. 


select * from v$database_block_corruption 
where CORRUPTION_TYPE='NOLOGGING';




You can use below query since when this corruption occured:

select file#, block#, first_time, next_time
from   v$archived_log, v$database_block_corruption
where  CORRUPTION_CHANGE# between first_change# and next_change#
  and CORRUPTION_TYPE='NOLOGGING';


Fix: Keep your database in FORCE LOGGING mode.

sql> connect sys as sysdba
sql> alter database force logging;

If you are getting LOB segments as corrupted block, then first find which segment it refers. Use below query:
e.g., Assume, 'SYS_LOB0004142294C00005$$' came as corrupted segment.

select * from dba_lobs where segment_name='SYS_LOB0004142294C00005$$'

Thanks
Post comments, if you have some doubts...

Oct 23, 2013

Find & repair Corrupt block in Oracle database

~ Find & repair Corrupt block in Oracle
~ Applies to any Oracle version
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- Find if any block (Table) is corrupted.

SQL> select * from V$DATABASE_BLOCK_CORRUPTION -- will show if any corruped block

Below query can give you information about corrupted block:

set head on; 
set pagesize 2000 
set linesize 250 
select * from v$database_block_corruption;
SELECT e.owner, e.segment_type, e.segment_name, e.partition_name, c.file# 
, greatest(e.block_id, c.block#) corr_start_block# 
, least(e.block_id+e.blocks-1, c.block#+c.blocks-1) corr_end_block# 
, least(e.block_id+e.blocks-1, c.block#+c.blocks-1) 
- greatest(e.block_id, c.block#) + 1 blocks_corrupted 
, null description 
FROM dba_extents e, v$database_block_corruption c 
WHERE e.file_id = c.file# 
AND e.block_id <= c.block# + c.blocks - 1 
AND e.block_id + e.blocks - 1 >= c.block# 
UNION 
SELECT s.owner, s.segment_type, s.segment_name, s.partition_name, c.file# 
, header_block corr_start_block# 
, header_block corr_end_block# 
, 1 blocks_corrupted 
, 'Segment Header' description 
FROM dba_segments s, v$database_block_corruption c 
WHERE s.header_file = c.file# 
AND s.header_block between c.block# and c.block# + c.blocks - 1 
UNION 
SELECT null owner, null segment_type, null segment_name, null partition_name, c.file# 
, greatest(f.block_id, c.block#) corr_start_block# 
, least(f.block_id+f.blocks-1, c.block#+c.blocks-1) corr_end_block# 
, least(f.block_id+f.blocks-1, c.block#+c.blocks-1) 
- greatest(f.block_id, c.block#) + 1 blocks_corrupted 
, 'Free Block' description 
FROM dba_free_space f, v$database_block_corruption c 
WHERE f.file_id = c.file# 
AND f.block_id <= c.block# + c.blocks - 1 
AND f.block_id + f.blocks - 1 >= c.block# 
order by file#, corr_start_block#; 


1) Collect file ids
sql> select distinct file_id from dba_extents;
2) Collect details
sql>
SELECT file_id,segment_name,segment_type,owner,tablespace_name,block_id,blocks
FROM   sys.dba_extents
WHERE  (file_id between 1 and 23) AND 658438 BETWEEN block_id AND block_id + blocks - 1;
3) Repair - If Table

a) Collect all data to temporary table and collect all DDL script and grants.
b) drop the table and re-create it with DDL script. (Disable refence key before drop, enable after create table)
c) Insert all records to the table

Note: This entire activity should not be taken in prod databases without Oracle support's recommendation.

Click here to get my work-around which is posted to this blog.

Hope this will help to resolve block corruption issue.

Translate >>