Контакты Поиск
17.09.2008 11:23
Имеет следующюю ситуацию
При попытке провести приходную накладную:
ORA-01578: разрушен блок данных ORACLE (файл # 3, блок # 67504)
ORA-01110: файл данных 3: '/opt/oracle/oradata/matrix36/indx01.dbf'
ORA-06512: на "SUPERMAG.DOCGOODS", line 919
ORA-06512: на "SUPERMAG.DOCGOODS", line 3019
ORA-06512: на "SUPERMAG.DOCGOODS", line 3539
ORA-06512: на "SUPERMAG.DOCUMENTS", line 6657
ORA-06512: на "SUPERMAG.DOCUMENTS", line 6812
ORA-06512: на line 1
begin SuperMag.SMDocStateAccStoreWI('МПН3600681'); end;
Поиск по sql.ru вывел на статью

Делая всё по этой статье на восстановление ушло 10 минут, а не будь RMAN`а то восстановление было бы долгим и мучительным.
содержание статьи для памяти

How to check for and repair block corruption with RMAN in Oracle 9i and Oracle 10g

Problem: the application encounters an ORA-01578 runtime error because there are one or more corrupt blocks in a table it is reading.

How can corrupt blocks be caused?
First of all we have two diffent kinds of block corruption:
- physical corruption (media corrupt)
- logical corruption (soft corrupt)
Physical corruption can be caused by defected memory boards, controllers or broken sectors on a hard disk;
Logical corrution can amoung other reasons be caused by an attempt to recover through a NOLOGGING action.
There are two initialization parameters for dealing with block corruption:
- DB_BOCK_CHECKSUM (calculates a checksum for each block before it is written to disk, every time)
causes 1-2% performance overhead
- DB_BLOCK_CHECKING (serverprocess checks block for internal consistency after every DML)
causes 1-10% performance overhead
If performance is not a big issue then you should use these!

Normally RMAN checks only for physically corrupt blocks
with every backup it takes and every image copy it makes.
This is a common misunderstanding amoung a lot of DBAs.
RMAN doesn not automatically detect logical corruption by default!
We have to tell it to do so by using
The info about corruptions can be found in the following views:

SYS @ orcl AS SYSDBA SQL > select * from v$backup_corruption;

---------- ---------- ---------- ---------- ---------- ---------- ----------
---------- ------------------ --- ---------
1 586945441 586945402 3 1 5 81
-- SYS @ orcl AS SYSDBA SQL > select * from v$copy_corruption;

Here is a case study:

HR @ orcl SQL > select last_name, salary
2 from employees;

ERROR at line 2:

ORA-01578: ORACLE data block corrupted (file # 5, block # 83)
# this could be an ORA-26040 in Oracle 8i! and before
ORA-01110: data file 5: '/u01/app/oracle/oradata/orcl/

This is what you find in the alert_.log:

Wed Apr 5 08:17:40 2006
Hex dump of (file 5, block 83) in trace file
Corrupt block relative dba: 0x01400053 (file 5, block 83)
Bad header found during buffer read
Data in bad block:
type: 67 format: 7 rdba: 0x0a545055
last change scn: 0x0000.0006d162 seq: 0x1 flg: 0x04
spare1: 0x52 spare2: 0x52 spare3: 0x0
consistency value in tail: 0xd1622301
check value in block header: 0x63be
computed block checksum: 0xe420
Reread of rdba: 0x01400053 (file 5, block 83)
found same corrupted data

Wed Apr 5 08:17:41 2006
Corrupt Block Found
RFN = 5, BLK = 83, RDBA = 20971603
OBJN = 51857, OBJD = 51255, OBJECT = , SUBOBJECT =

Starting with Oracle 9i we can use RMAN
to check a database for both physically and logically corrupt blocks.

Here is the syntax:
RMAN> backup validate check logical database;
Starting backup at 05-04-2006:08:23:20
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=136 devtype=DISK
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
input datafile fno=00001 name=/u01/app/oracle/oradata/orcl/
input datafile fno=00003 name=/u01/app/oracle/oradata/orcl/
input datafile fno=00005 name=/u01/app/oracle/oradata/orcl/
input datafile fno=00002 name=/u01/app/oracle/oradata/orcl/
input datafile fno=00004 name=/u01/app/oracle/oradata/orcl/
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:45
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
including current control file in backupset
including current SPFILE in backupset
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
including current control file in backupset
including current SPFILE in backupset
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
Finished backup at 05-04-2006:08:24:10

RMAN does not physically backup the database with this command
but it reads all blocks and checks for corruptions.

If it finds corrupted blocks it will place the information about the corruption into a view:

SYS @ orcl AS SYSDBA SQL > select * from v$database_block_corruption;
---------- ---------- ---------- ------------------ ---------
5 81 4 0 CORRUPT

this is what we find in the alert_.log:
Corrupt block relative dba: 0x014000b1 (file 5, block 177)
Bad header found during backing up datafile
Data in bad block:
type: 67 format: 7 rdba: 0x0a545055
last change scn: 0x0000.0007bc77 seq: 0x3 flg: 0x04
spare1: 0x52 spare2: 0x52 spare3: 0x0
consistency value in tail: 0xbc772003
check value in block header: 0xb32
computed block checksum: 0xe4c1
Reread of blocknum=177, file=/u01/app/oracle/oradata/orcl/
found same corrupt data

Now we can tell RMAN to recover all the blocks
which it has found as being corrupt:

RMAN> blockrecover corruption list;
# (all blocks from v$database_block_corruption)

Starting blockrecover at 05-04-2006:10:09:15
using channel ORA_DISK_1
channel ORA_DISK_1: restoring block(s) from datafile copy /u01/app/

starting media recovery
archive log thread 1 sequence 2 is already on disk as file /u01/app/oracle/

archive log thread 1 sequence 1 is already on disk as file

media recovery complete, elapsed time: 00:00:01
Finished blockrecover at 05-04-2006:10:09:24

this is in the alert_.log:
Starting block media recovery
Wed Apr 5 10:09:22 2006
Media Recovery Log /u01/app/oracle/flash_recovery_area/ORCL/

Wed Apr 5 10:09:23 2006
Media Recovery Log /u01/app/oracle/flash_recovery_area/ORCL/
archivelog/2006_04_05/o1_mf_1_2_236wxbsp_.arc ( restored)

Wed Apr 5 10:09:23 2006
Recovery of Online Redo Log: Thread 1 Group 1 Seq 1 Reading mem 0
Mem# 0 errs 0: /u01/app/oracle/oradata/orcl/redo01.log
Wed Apr 5 10:09:23 2006
Completed block media recovery

I recommend you to check your database for corrupt blocks
with RMAN on a regular basis, proactively.
If you do so you RMAN finds out about block corruptions
before your application runs into an ORA-01578 and
before you find out that you have backed up the corrupt blocks again and again.

There have been incidents when DBAs found out
that they did not have a backup with the un-corruted block any more,
because you have deleted the last one with a not corrupted version.
They could not recover the block any more!

For more detailed info about recovering corrupt blocks
(without and with RMAN, releases 7-10g)
pls see metalink also:
Subject: Handling Oracle Block Corruptions in Oracle7/8/8i/9i/10g
Doc ID: Note:28814.1 Type: BULLETIN
Last Revision Date: 26-MAR-2006 Status: PUBLISHED
17.09.2008 13:52
Я в свое время начинал с этого:
за что вспомнил... Фраза:
"As RMAN proceeds, you can perform some stationary exercise at your desk, increase your blood pressure and heart rate by running..."
Собственно, сделать превентивную меру несложно, у меня еженощно полный бекап базы, добавляю строку:
backup validate check logical database;
а себе вывод по крону
select * from v$database_block_corruption;
если ничего не выведется, то и письмо не придет...
02.03.2009 11:35
по этой же теме, но уже на русском
Сегодня получено в журнале оповещения сообщение "ORA-01578: ORACLE data block corrupted (file # 2, block # 1028472)". Что делать и куда бежать?
Так как на сервере стоит ORA10g, то оказывается можно восстановить только поломаный блок.
Используя, Enterprise manager (стартует emctl start dbconsole), создали задание для RMAN на восстановление блока:Maintenance-Perform Recovery - Object Level Recovery - Block Recovery -Data blocks may be recovered using one of the following methods -Datafiles. Затем нужно указать поврежденный файл данных и номер блока (эта информация может быть почерпнута из журнала оповещений (alert_mydb.log)
Задание было запущено на выполнение. Начался накат архивных журнальных файлов. Вот Вам кусочек из алерта:

alter database recover datafile list clear
Mon Mar 17 10:35:23 2008
Completed: alter database recover datafile list clear
Mon Mar 17 10:35:23 2008
Starting block media recovery
Mon Mar 17 10:35:25 2008
Media Recovery Log /mnt/raid5/oracle/archive/1_23865_646597233.dbf
Mon Mar 17 10:35:27 2008
Media Recovery Log /mnt/raid5/oracle/archive/1_23866_646597233.dbf
Mon Mar 17 10:35:29 2008
Media Recovery Log /mnt/raid5/oracle/archive/1_23867_646597233.dbf
Mon Mar 17 10:35:32 2008
Media Recovery Log /mnt/raid5/oracle/archive/1_23868_646597233.dbf
Mon Mar 17 10:35:34 2008
Media Recovery Log /mnt/raid5/oracle/archive/1_23869_646597233.dbf
Mon Mar 17 10:35:36 2008
Media Recovery Log /mnt/raid5/oracle/archive/1_23870_646597233.dbf
Mon Mar 17 10:35:37 2008

Mon Mar 17 11:13:31 2008
Media Recovery Log /mnt/raid5/oracle/archive/1_24944_646597233.dbf
Mon Mar 17 11:13:32 2008
Completed block media recovery
И что приятно: база открыта, народ пашет в поте лица. Вот протокол какой приготовил RMAN:

Recovery Manager: Release - Production on ???? ???°N? 17 10:35:17 2008

Copyright (c) 1982, 2005, Oracle. All rights reserved.

connected to target database: mydb (DBID=1345620281)
using target database control file instead of recovery catalog

echo set on

RMAN> run {
2> blockrecover datafile 2 block 1028472;
3> }
Starting blockrecover at 17.03.08
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=198 devtype=DISK

channel ORA_DISK_1: restoring block(s) from datafile copy /mnt/raid5/flash_recovery_area/mydb/datafile/o1_mf_undotbs1_3sndfzv4_.dbf

starting media recovery
media recovery complete, elapsed time: 00:38:16

Finished blockrecover at 17.03.08

RMAN> exit;

Recovery Manager complete.
цитата из статьи "Oracle9i. Обзор некоторых новых возможностей"
Особого внимания заслуживает новая возможность Recovery Manager – восстановление отдельного блока файла данных. Раньше одним из стандартных способов восстановления при обнаружении поврежденного (corrupted) блока было копирование файла, содержащего этот блок, из резервной копии и применение к нему архивных и оперативных журналов. Это требовало как минимум перевода поврежденного табличного пространства в автономный режим на время копирования файла, что приводило к недоступности части данных на довольно длительный срок. Теперь Recovery Manager может извлечь из резервной копии только поврежденный блок, выполнить его восстановление при помощи журналов и записать восстановленный блок в файл данных. В этом случае временно недоступными оказываются только данные в поврежденном блоке.
а вот еще хорошее предложение на странице

Убеждение № 8: разрушенный блок требует удаления объекта
Консультанты IT боятся сообщения об ошибке Oracle ORA-1578: "Oracle data block corrupted" (Блок данных Oracle разрушен). Внутренняя структура одного из блоков базы данных перестала быть правильной. Сообщение идентифицирует ошибочный блок по номеру файла и номеру блока. Для “лечения” проблемы нужно выполнить запрос типа:
SELECT owner, segment_name, segment_type
FROM dba_extents
WHERE file_id =
AND BETWEEN block_id AND block_id + blocks - 1;
где < номер_файла> и < номер_блока> являются числами из сообщения об ошибке. Этот запрос укажет, какой объект содержит разрушенный блок. После этого, в зависимости от типа объекта, восстановление является либо прямым (для индексов и временных сегментов), либо трудным (для таблиц), либо очень трудным (для активных сегментов отката и частей словаря данных).
Однако, в Oracle 9i Enterprise Edition новая команда диспетчера восстановления (RMAN) – BLOCKRECOVER – может восстановить блок на месте, не удаляя, а затем повторно создавая вовлеченный объект. После регистрации в RMAN и соединения с целевой базой данных наберите:
При выполнении резервного копирования в RMAN обновляется новое представление, V$DATABASE_BLOCK_CORRUPTION, и блок должен быть внесен в список, как испорченный, для последующего выполнения BLOCKRECOVER. Чтобы восстановить все блоки, которые были отмечены как испорченные, может быть использована следующая последовательность RMAN:
Этот подход эффективен, если в восстановлении нуждаются только несколько блоков. При крупномасштабном разрушении (повреждении) более эффективно восстановить (restore) предшествующее “изображение” файла данных, и затем восстановить (recover) весь файл данных в его первоначальном (перед разрушением) состоянии. Как и для любой новой возможности, тщательно проверьте ее перед использованием для промышленной базы данных.
Успехов Вам в труде!
оригинал тут
26.04.2009 11:11
До кучи, скрипт на просмотр поврежденных сегментов
SELECT distinct d.SEGMENT_TYPE||':'||d.OWNER||'.'||d.SEGMENT_NAME 
FROM DBA_EXTENTS d, v$database_block_corruption b 
where b.file#=d.file_id and b.block# between d.block_id and d.block_id+d.blocks-1
или если блок в свободном пространстве файлов
SELECT count(*)
FROM DBA_free_space d, v$database_block_corruption b 
where b.file#=d.file_id and b.block# between d.block_id and d.block_id+d.blocks-1
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#
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
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#;
26.04.2009 22:59
На тему восстановления блоков.. Поделюсь опытом прошедших двух суток. Итак, после восстановления базы на дату, обнаружились 3400 с гаком записи о сбойных блоках. "Ну не вопрос" сказал я, потер руки и запустил полный blockrecovery. Короче, когда я его через две недели остановил, оставалось 340 блоков. Не знаю, во что он уходит, но уходит с концами, забирая себе в партнеры несколько процов, грузя их под завязку (у меня в параллелизме 4, три проца были заняты). Причем, несколько суток количество строк в листе сбойных блоков не меняется. Уперся рогом, поперезапускал, оставлял на длительное время, не лечит и все. Стал разбираться. До сих пор грешу на commit_write=batch,nowait. После расчета ТД, количество блоков резко выросло, но полным blockrecovery уменьшилось до прежнего уровня. Пустил перестройку всех объектов - не помогло. Точнее из 340 стало блоков чуть больше 100. Вот тут и началось самое интересное. Прыгал с бубном, ставил патчи, мувил и пересобирал online индексы, в unusable их запихивал - не помогало. Блоки оставались трупами. Накидал скриптик (выше) выдернул имена объектов. Оказалось еще интереснее, практически все это были индексы PK. Дизаблил констрейнт, дропал индекс, включал констрейнт, вуаля, строк в листе сбойных блоков становилось меньше, т.е. перебилд ни к чему не приводил, только пересоздание. Еще интереснее стало, когда дело остановилось на 34 записях о блоках. Они ничему не принадлежали. Т.е. список сбойных сегментов опустел, а в списке сбойных блоков оставалось еще 34 записи. Вот тут я основательно потрепал бубен. Уже собирался даже ТП пересоздавать. Решение пришло в виде эксгумации программки dbv. Неожиданно (пишу быстрее, чем это все произошло), она терпеливо пролопатила файл, пометила блоки сбойными, после чего они пропали из списка. Замечу, что файлики у меня далеко не 2Гб.
SQL> select * from v$database_block_corruption;

no rows selected
Ура... Как меня достали глюки... Устал. Но хоть одной проблемной базой меньше...
Кстати, ноты для чтения по теме: 283053.1 (последний абзац), 463821.1, 336133.1
29.05.2009 13:29
Какая прелесть... blockrecover работает только в Enterprise... Вот я сел в лужу-то :(
27.07.2009 09:32
кто-нибудь может поделиться вот этим докумекнтом?
Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 21 сообщение(ий)):
У вас нет прав чтобы видеть скрытый текст, содержащийся здесь.
27.07.2009 09:52
Вот он.
Тип файла: rar showdoc.rar (18.7 Кб, 328 просмотров)
27.07.2009 10:00
Вот еще до кучи
Тип файла: rar 403747.1.rar (6.0 Кб, 279 просмотров)
Тип файла: rar 61685.1.rar (5.2 Кб, 267 просмотров)
19.03.2010 09:32
У меня вываливается ошибка:

ORA-01578: разрушен блок данных ORACLE (файл # 3, блок # 333443)
ORA-01110: файл данных 3: 'D:\ORACLE\ORADATA\REGIONCO\INDX01.DBF'
ORA-06512: на "SUPERMAG.INSPECT", line 3365
ORA-06512: на line 1
ORA-06512: на "SUPERMAG.INSPECT", line 315
ORA-06512: на "SUPERMAG.DOCUMENTS", line 6813
ORA-06512: на line 1
Источник: SmLibaryBase trace
HRESULT=80004005 custom=0 SQLState=<none>
begin SuperMag.SMDocStateAccStoreCO('КЗЦО000169'); end;

Как с ней бороться? С чего начать? Можно по-подробнее - я новичек в этом деле :)
Из выше изложенного только понял что вылечить можно, но как?

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.