Восстановление данных таблиц Oracle

Из Самары обратился заказчик, с жалобой на появившуюся при запуске БД Oracle, ошибку, которая возникла после отключения электропитания.

Для восстановления базы данных Оракл надо понимать устройство её структуры. В общем приближении БД Oracle состоит из табличных файлов, логов транзакций, которые описывают все изменения и т.н. контрол-файлов (контролей), которые хоть и не являются критически важными, но их корректное содержимое участвует при сборке базы на старте. В случае возникновения Power Loss, создаётся некий Chekpoint, отражённый в REDO.LOG, который при повторном включении БД можно закоммитить (commit).

Как обычно, оборудование было под надзором мега-сисадмина, а значит всё крайне запущено. Данные хранились на Raid массиве Raid 1 (mirror) состоящем из двух дисков, но на момент инцидента один диск уже давным давно был поломан, и в массиве не участвовал.

Перебои с электричеством были не редкостью, свет моргал часто, сервер ребутился и продолжал работу. Но серверное железо было настолько старым, что в момент очередного power loss у рэйд контроллера сдохла батарейка и в результате не закрылся лог-файл, что после запуска системы и привело к возникновению ошибки «CTRL-1 inconsistent with file CTRL-2».

Клиент своими силами что то пытался мутить с контрол-файлами, подсовывать их из древних резервных копий, но всё, конечно же, безрезультатно.

Получив диски на анализ, начали разбираться что к чему. Сразу смутили даты работы с файлами:

C:\oracle\oradata\MAGICASH>dir

19.11.2018  09:42         8 101 888 CONTROL01.CTL
07.11.2018  14:08         8 101 888 CONTROL02.CTL
19.11.2018  09:42         8 101 888 CONTROL03.CTL
07.11.2018  14:08        60 825 600 INDX01.DBF
07.11.2018  14:08    34 359 623 680 MG_INDX.DBF
22.10.2018  10:59    34 359 623 680 MG_INDX1.DBF
07.11.2018  14:08    34 359 623 680 MG_INDX2.DBF
07.11.2018  14:08    25 098 723 328 MG_INDX3.DBF
07.11.2018  14:08        60 825 600 MG_INDX_LARGE.DBF
07.11.2018  14:08       113 254 400 MG_LOB.DBF
07.11.2018  14:08    34 359 623 680 MG_TABLE.DBF
07.11.2018  14:08    18 874 253 312 MG_TABLE3.DBF
07.11.2018  14:08       805 314 560 MG_TABLE5.DBF
07.11.2018  14:08       113 254 400 MG_TABLE_LARGE.DBF
07.11.2018  14:08     8 514 445 312 RBS01.DBF
07.11.2018  14:08         1 049 088 REDO01.LOG
07.11.2018  14:08         1 049 088 REDO02.LOG
07.11.2018  14:08         1 049 088 REDO03.LOG
19.11.2018  09:42       276 832 256 SYSTEM01.DBF
07.11.2018  14:08     7 867 080 704 TEMP01.DBF
07.11.2018  14:08        12 591 104 TOOLS01.DBF
07.11.2018  14:08       113 254 400 USERS01.DBF

Обращаем внимание на CTL, DBF и LOG файлы.

Саму базу использовала оболочка Petrol (Петрол) — отечественная программа, которая ведёт учёт транзакций по топливным картам и картам лояльности на бензоколонках, что-то типа CRM для АЗС. Эта оболочка работает с Оракулом, который собственно и осуществляет взаимодействие интерфейсной части с базой данных.

Первым делом попытались официально обратиться в саппорт ПО Petrol, для получения сведений об особенностях работы базы и ПО, какие таблицы критичны для работы системы и т.п.. Но там сразу спросили, платил ли пользователь ПО за поддержку? Как казалось, жидокабры из Петрола просят роялти 3 рубля с проданного литра! Учитывая что маржинальность АЗС не намного выше, от такого щедрого предложения пользователь отказался давным-давно и в официальной поддержке было отказано.

По своим каналам вышли напрямую на программиста, из команды разработчиков. От него получили дистрибутив и ответы на вопросы об особенностях структуры базы данных, таблиц и т.п.

Далее, для проведения анализа ситуации потребовалось воспроизвести ошибку в лабораторных условиях. Поскольку в работу поступили только диски, а для оценки проблемы с БД требовалось запустить ОС и ПО на ней, то было принято решение развернуть новую систему, чтобы там раскатать оснастку Oracle, и подоткнуть нужные данные в чистую систему.

Отыскав старое железо и добившись по персональному запросу от Оракла старого дистрибутива, который уже давно не лежит на оф. сайте собрали ПК, поставили Win2003Srv, но не смотря на полученные дистрибутивы от Петрола с пол-пинка всё это добро не заработало. Ресёрч показал, что решить задачу с установкой новой версии можно, но сложность работ сильно возрастёт и, самое главное, кратно возрастут сроки выполнения, а они и так уже «горели».

Оставалось одно: добиваться запуска родной серверной операционки, что и было в итоге сделано. Далее разобрали файлы базы на отдельные таблицы. Часть таблиц оказалась повреждена, и довольно быстро выяснилось — почему. Сисадмины не смогли настроить антивирус, который не давал работать софту, поэтому не заморачиваясь, антивирь заблочили. Сервер нахватал троянов которые побили часть таблиц.

Самое весёлое, что сервак работал на статическом IP, и будучи вусмерть дырявым, давал доступ к базам, откуда любой толковый школьник мог получить данные, среди сотен существующих клиентов приклеить своего “левого”, вписать в его учётку выдуманную топливную карту, пин-код, начислить на карту цистерну солярки и заправляться в своё удовольствие.

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

>for %i in (*.CTL) do od --skip-bytes=0x2008 --read-bytes=4 --format=dL "%i"

>od --skip-bytes=0x2008 --read-bytes=4 --format=dL "CONTROL01.CTL"
0020010    25120526
0020014

>od --skip-bytes=0x2008 --read-bytes=4 --format=dL "CONTROL02.CTL"
0020010    25120522
0020014

>od --skip-bytes=0x2008 --read-bytes=4 --format=dL "CONTROL03.CTL"
0020010    25120526
0020014

с использованием опции _allow_resetlogs_corruption из повреждённых табличных пространств экспортировали нужные данные а потом так же, руками, проводилась сборка методом импорта во вновь созданные таблицы.

На достаточно мощной железке и SSD процесс сборки занял порядка 7-8 часов машинного времени. Полученные таблицы подсунули в Oracle и по итогам получили работающую на нашем железе операционку и софт. Для облегчения заказчику процесса переезда восстановленной базы Oracle на новую отказоустойчивую систему результат так и передали, вместе с собранным системником. Пример отчёта который Петрол формирует, основываясь на данных, которые содержатся в базе, для демонстрации работоспособности, перед оплатой.