Как извлечь данные таблицы из поврежденного блока? ORA-01578: Oracle data block corrupted (file ..., block ...)

dbstalker, 26 июля

В этом посте поднимался вопрос возможности получения данных и поврежденной таблицы минуя испорченный блок. Здесь рассмотрим возможность получения данных таблицы непосредственно из испорченного блока.

Эта возможность становится реальной, если на все колонки таблицы существует индекс. Точнее – можно получить из индексных сегментов информацию, хранящуюся в них, не смотря на то, что соответствующие блоки таблицы повреждены.

В посте был показан способ как найти ROWID первой записи таблицы в поврежденном блоке и ROWID первой записи в блоке, следующем за поврежденным блоком:

select dbms_rowid.rowid_create(1,&&DATA_OBJECT_ID,номер_файла,номер_блока,0) first_rowid from dual -- находим ROWID первой записи в поврежденном блоке

select dbms_rowid.rowid_create(1,&&DATA_OBJECT_ID,номер_файла,номер_блока+1,0) last_rowid from dual -- находим ROWID первой записи в блоке, следующем за поврежденным

Таким образом, мы получили диапазон ROWID утраченных записей таблицы. А теперь, если у нас есть индексы, выполним такие запросы на выборку, чтобы их выполнение не нуждалось в чтении таблицы. То есть, чтобы для их выполнения было достаточно чтения индексов. Предложенные ниже запросы нужно использовать для каждого существующего индекса таблицы (было бы отлично, если бы существовали индексы для каждой колонки таблицы). Таким образом, вы сможете сохранить максимально возможную информацию.

Если хотя бы один ключ имел ограничение NOT NULL тогда можно использовать метод fast full scan для доступа к индексным значениям:

SELECT /*+ INDEX_FFS(a ) */ , … FROM my_table a WHERE rowid >= ‘first_rowid’ AND rowid< ‘last_rowid’ ;

В противном случае вы не сможете использовать fast full scan, а должны взять на вооружение range scan. Для этого нужно, чтобы вы знали минимальное утраченное значение лидирующего ключа индекса (первой колонки индекса), что обеспечит вам индексное сканирование

SELECT /*+ INDEX(а ) */ , … FROM my_table a  WHERE rowid >= ‘first_rowid’’ AND rowid < ‘last_rowid’ AND >= ;

 

Новый комментарий

Я не спамер: введите суму 8+0



 

От авторов блога

О Блоге - прочитай перед началом.

Задать вопрос и получить ответ - уже решено 94 вопросов

Глоссарий - список терминов и сокращений


 
 

Бизнес форум

Последние темы:

Печь булерьян в дом
21 сентября, 1 ответа
Как Открыть Футбольную Школу
20 сентября, 1 ответа
IP телефония
20 сентября, 1 ответа