ORA-01578 ORACLE data block corrupted
By: Date: 03.04.2012 Categories: !RUS,Data block corrupted,ORACLE
ENG: ORA-01578 ORACLE data block corrupted

Что делать (как лечить) ORA-01578 ORACLE data block corrupted?

ВНИМАНИЕ: Статья может меняться.

Последовательность действий из трёх шагов.

1) Определить какие конкретно блоки испорчены

Чтобы определить тип объекта, нужно сначала определить какие-конкретной блоки испорчены. Нужны — номер блока и номер файла.
©Bobrovsky Dmitry
Обычно сообщение о испорченном блоке, когда он выявляется, пишется в alert.log в виде сообщения об ошибке ORA-01578 и имеет примерно такой вид:
©Bobrovsky Dmitry
Sat Mar 03 10:49:26 2012
Errors in file c:\admin\r14\bdump\r14_j001_540.trc:
ORA-01578: разрушен блок данных ORACLE (файл # 4, блок # 165455)
ORA-01110: файл данных 4: 'D:\ORADATA\R14\INDX01.DBF'

Здесь номер блока и номер файла указаны явно.
Dmitry Bobrovsky
В любом случае (есть сообщение ORA-01578 в alert.log или нет, может есть косвенное подозрение) настоятельно рекомендую проверить ВСЕ файлы БД. Т.к. в alert.log указаны только те испорченные блоки к которым было обращение, но так же может быть множество испорченных блоков к которым обращения не было и вы нигде не увидите информацию о них.
Dmitry Bobrovsky
Для проверки всех файлов БД используйте утилиту DBVERIFY (dbv.exe).

Для удобства, можно выполнить запрос, чтобы получить готовы строки запуска утилиты для всех файлов БД

SELECT    'dbv file='
       || name
       || ' logfile='
       || SUBSTR (name,
                  1,
                    INSTR (name,
                           '.',
                           -1,
                           1)
                  - 1)
       || '.txt blocksize='
       || (SELECT VALUE
             FROM v$parameter
            WHERE name = 'db_block_size')
  FROM V$DATAFILE;

После этого нужно запустить полученные команды в командной оболочке (cmd.exe).

В полученных текстовых файлах вы можете увидеть результаты диагностики. Информация об испорченных блоках может быть представлена в виде Data Block Address (DBA).

DBVERIFY - Verification starting : FILE = C:\ORACLE\PRODUCT\10.2.0\ORADATA\EAO\INDX05.DBF
Block Checking: DBA = 58789211, Block Type = KTB-managed data block
**** row 105: key out of order
---- end index block validation
Page 68955 failed with check code 6401

В этом случае нужно перевести DBA в номер блока и номер файла с помощью запроса

SELECT DBMS_UTILITY.data_block_address_block (58789211) "BLOCK",
 DBMS_UTILITY.data_block_address_file (58789211) "FILE"
FROM DUAL;

2) Определить объект в котором содержаться испорченные блоки и его тип

Для определения объекта и его типа, нужно выполнить запрос (здесь понадобятся номер файла и номер блока):

SELECT segment_name , segment_type , owner , tablespace_name
 FROM sys.dba_extents
 WHERE file_id = <FILE_NUMBER>
 AND <BLOCK_NUMBER> BETWEEN block_id and block_id + blocks-1;

3) В зависимости от типа объекта — провести мероприятия по восстановлению

После того как объект выявлен, можно попробовать восстановить его. Методы восстановления различных типов объектов можно посмотреть в статье Handling Oracle Block Corruptions in Oracle7/8/8i/9i/10g/11g [ID 28814.1]. Обычно, проще всего с индексами, если сама таблица не испорчена то их можно просто удалить и создать заново.

Если БД работает с noarchivelog и нет нормального резервирования — не исключена потеря некоторых данных безвозвратно.

Если для резервирования БД используется RMAN — можно воспользоваться им для восстановления испорченных блоков (см.ПРИМЕЧАНИЕ 3).

================================================================

ПРИМЕЧАНИЕ 1: Даже если обнаружился всего один испорченный блок, лучше проверить все файлы БД на предмет наличия испорченных блоков, т.к. такие блоки обнаруживаются только в момент обращения к ним.

Запрос (выполнять под SYS) для получения набора команд, которые необходимо выполнить в CMD. В результате выполнения в папке где лежать файлы БД получаться файлы *.txt с результатами проверки.

select 'dbv file='||name||' logfile='||substr(name,1,instr(name,'.',-1,1)-1)||'.txt blocksize='||(select value from v$parameter where name='db_block_size') from V$DATAFILE;

ПРИМЕЧАНИЕ 2: Начиная примерно с 10.2.0.5 в alert.log пишется сразу информация об объекте в котором выявлен испорченный блок, что очень удобно. Выглядит это так

Mon Apr 09 10:49:21 Ekaterinburg Daylight Time 2012
Hex dump of (file 4, block 3116391) in trace file c:oracleproduct10.2.0adminssdbdumpssd_s002_3252.trc
Corrupt block relative dba: 0x002f8d67 (file 4, block 3116391)
Fractured block found during buffer read
Data in bad block:
type: 6 format: 2 rdba: 0x002f8d67
last change scn: 0x0000.001c3a89 seq: 0x3 flg: 0x04
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0xac160601
check value in block header: 0xbda5
computed block checksum: 0x969d
Reread of rdba: 0x002f8d67 (file 4, block 3116391) found same corrupted data
Mon Apr 09 10:49:21 Ekaterinburg Daylight Time 2012
Corrupt Block Found
TSN = 4, TSNAME = INDX
RFN = 1024, BLK = 3116391, RDBA = 3116391
OBJN = 45280, OBJD = 45280, OBJECT = RT_RE_FK_I, SUBOBJECT =
SEGMENT OWNER = REG_RT, SEGMENT TYPE = Index Segment

ПРИМЕЧАНИЕ 3: Если база работает в archivelog и есть резервные копии сделанные с помощью RMAN. Можно восстановить испорченные блоки с помощью RMAN.


-- ВНИМАНИЕ: Синтаксис для разных версий Oracle может различаться - уточнить по документации
-- Соединиться с БД (без каталога)
CMD> rman target /
-- Выполнить проверку БД для выявления испорченных блоков
RMAN> run {BACKUP VALIDATE DATABASE;}

-- Посмотреть выявленные испорченные блоки можно запросом
SQL> SELECT * FROM v$backup_corruption;

-- Лечение
-- Лечить конкретный блок
RMAN> run {blockrecover DATAFILE 5 BLOCK 114;}
-- Лечить все испорченные блоки разом
RMAN> run {blockrecover CORRUPTION LIST;}

ПРИМЕЧАНИЕ 4: Начиная с 11.1.0.6 в RMAN появились новые команды для blockrecover (старые команды поддерживаются). Подробнее — New Rman Blockrecover command in 11g (Recover corruption list) [ID 1390759.1].

================================================================

ЧТО ПОЧИТАТЬ:

Master Note for Handling Oracle Database Corruption Issues [ID 1088018.1]
Статья дает глобальное представление о повреждениях БД и необходимых действиях в зависимости где это повреждение обнаружено.
Это практически карта на которой отображены все статьи по corruption.

Physical and Logical Block Corruptions. All you wanted to know about it. [ID 840978.1]
Объясняет причины логических и физических повреждений.
Интересно почитать для общего развития.

OERR: ORA-1578 «ORACLE data block corrupted (file # %s, block # %s)» Master Note [ID 1578.1]
Описывает что делать при ошибке ORA-01578.
Общее описание далее может понадобиться [ID 28814.1].

How to identify the corrupt Object reported by ORA-1578 / RMAN / DBVERIFY [ID 819533.1]
Описывает как определить испорченный объект по сообщению ORA-1578 или RMAN или DBVERIFY.
Общее описание далее может понадобиться [ID 28814.1].

Handling Oracle Block Corruptions in Oracle7/8/8i/9i/10g/11g [ID 28814.1]
Описывает как определить поврежденный объект и что делать с каждым конкретным типом объектов.
Запись ORA-01578 ORACLE data block corrupted впервые появилась Dmitry Bobrovsky Blog

— Author: Dmitry Bobrovsky Google