В один прекрасный момент в алерт-логе очень большой БД, начали появляться сообщения следующего содержания:
Ситуация осложнялось тем, что бэкапов под рукой не было.
Далее последуют инструкции по выходу из данной ситуации.
RMAN упирался в данный блок и ни в какую не хотел бэкапить базу.
Начался детальный разбор полетов, и выяснение к чему относится данный блок:
Далее было выяснено к какой таблице относился данный LOB сегмент:
DBMS_REPAIR — не смог прояснить ситуации, ввиду ограничений на работу с LOB полями.
На просторах сети было найдено решение — суть его заключалась в следующем:
Скрипт успешно вернул две записи:
При помощи нехитрого запроса были получены PRIMARY KEY данных записей и записи были успешно потерты.
Казалось бы, вот оно решение проблемы — но RMAN упорно не хотел резервировать базу упираясь в данные блоки.
Запрос в V$DATABASE_BLOCK_CORRUPTION и RMAN VALIDATE DATAFILE подтвердили о том, что блоки остались в прежнем состоянии.
Не очень хотелось создавать таблицу и забивать ее под завязку всего табличного пространства, поэтому было принято решение использовать ALTER TABLE XXX SHRINK SPACE.
Затем запускаем проверку проблемного файла RMAN'ом:
После данной операции представление V$DATABASE_BLOCK_CORRUPTION оказалось кристально чистым.
Далее база была успешно зарезервирована RMAN'ом а недостающие записи были выдернуты из реплики.
Данная проблема возникла после того как начали рассыпаться диски на сервере.
Копию раздела сняли сторонней утилитой и развернули на новый свежесобранный массив.
Все операции проводились на базе весом 1,5 Тб.
Вес таблицы 70 Гб.
Версия Oracle 11g R2 — думаю данный способ применим и для 10g.
ALTER TABLE… SHRINK SPACE CASCADE имеет ряд ограничений предварительно рекомендую ознакомится с документацией перед его использованием.
Corrupt block relative dba: 0x0724c078 (file 28, block 2408568)
Fractured block found during backing up datafile
Reread of blocknum=2408568, file=E:\ORACLE\ORADATA\XXX\XXX_BLOB16.DBF. found same corrupt data
Ситуация осложнялось тем, что бэкапов под рукой не было.
Далее последуют инструкции по выходу из данной ситуации.
RMAN упирался в данный блок и ни в какую не хотел бэкапить базу.
Начался детальный разбор полетов, и выяснение к чему относится данный блок:
SELECT owner, segment_name, segment_type FROM dba_extents WHERE file_id = 28 AND 2408568 BETWEEN block_id AND block_id + blocks - 1; OWNER ---------------------------- SEGMENT_NAME ---------------------------- SEGMENT_TYPE ------------------ DOC_USER SYS_LOB0000075021C00003$$ LOBSEGMENT
Далее было выяснено к какой таблице относился данный LOB сегмент:
SELECT table_name, column_name FROM dba_lobs WHERE owner='DOC_USER' AND segment_name='SYS_LOB0000075021C00003$$'; TABLE_NAME ------------------- COLUMN_NAME ------------------- DOC_LARGE_PIC BINARY_DATA
DBMS_REPAIR — не смог прояснить ситуации, ввиду ограничений на работу с LOB полями.
На просторах сети было найдено решение — суть его заключалась в следующем:
- 1. Поочередно перебрать записи из таблицы.
- 2. При попадании в запись, относящейся к битому блоку выдернуть ее ROWID.
set serverout on exec dbms_output.enable(100000); declare error_1578 exception; pragma exception_init(error_1578,-1578); n number; cnt number:=0; badcnt number:=0; begin for cursor_lob in (select rowid r, BINARY_DATA L from DOC_USER.DOC_LARGE_PIC) loop begin n:=dbms_lob.instr(cursor_lob.L,hextoraw('AA25889911'),1,999999) ; exception when error_1578 then dbms_output.put_line('Got ORA-1578 reading LOB at '||cursor_lob.R); badcnt:=badcnt+1; end; cnt:=cnt+1; end loop; dbms_output.put_line('Scanned '||cnt||' rows - saw '||badcnt||' errors'); end; /
Скрипт успешно вернул две записи:
Got ORA-1578 reading LOB at AAASUNAAQAAPf7hAAY Got ORA-1578 reading LOB at AAASUNAAQAAPf7hAAp
При помощи нехитрого запроса были получены PRIMARY KEY данных записей и записи были успешно потерты.
Казалось бы, вот оно решение проблемы — но RMAN упорно не хотел резервировать базу упираясь в данные блоки.
Запрос в V$DATABASE_BLOCK_CORRUPTION и RMAN VALIDATE DATAFILE подтвердили о том, что блоки остались в прежнем состоянии.
Не очень хотелось создавать таблицу и забивать ее под завязку всего табличного пространства, поэтому было принято решение использовать ALTER TABLE XXX SHRINK SPACE.
ALTER TABLE DOC_USER.DOC_LARGE_PIC ENABLE ROW MOVEMENT; ALTER TABLE DOC_USER.DOC_LARGE_PIC SHRINK SPACE CASCADE;
Затем запускаем проверку проблемного файла RMAN'ом:
RMAN VALIDATE DATAFILE 28;
После данной операции представление V$DATABASE_BLOCK_CORRUPTION оказалось кристально чистым.
Далее база была успешно зарезервирована RMAN'ом а недостающие записи были выдернуты из реплики.
UPDATE
Данная проблема возникла после того как начали рассыпаться диски на сервере.
Копию раздела сняли сторонней утилитой и развернули на новый свежесобранный массив.
Все операции проводились на базе весом 1,5 Тб.
Вес таблицы 70 Гб.
Версия Oracle 11g R2 — думаю данный способ применим и для 10g.
ALTER TABLE… SHRINK SPACE CASCADE имеет ряд ограничений предварительно рекомендую ознакомится с документацией перед его использованием.