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