Вы находитесь на страницах старой версии сайта.
Переходите на новую версию Interface.Ru

Так как же восстановить данные таблицы?

© Владимир Пржиялковский,
координатор Евро-Азиатской Группы Пользователей Oracle,
преподаватель УКЦ Interface Ltd.

Сокрушилося сердечко,
Взволновалась в сердце кровь,
Потеряла я колечко,
Потеряла я любовь.

Музыка народная, слова М. Н. Ожегова.

Аннотация

Проблема восстановления потерянных данных в таблице уже рассматривалась в статье «Как восстановить таблицу». Здесь она рассмотрена снова, но более систематично и с учетом новшеств в Oracle последних лет. Кроме того, хотя решение, предлагавшееся в прежней статье не потеряло своей силы, здесь предлагаются ему альтернативы, как представляется более понятные и более естественные с точки зрения именно процесса восстановления данных.

Введение

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

Одни способы позволяют (в некоторых случаях) восстановить образ требуемой таблицы на известный момент в прошлом. Другие позволяют (в некоторых случаях) отследить историю изменений таблицы и отменить выявленные удаления, впоследствии нежелательные. Конкретные решения могут диктоваться следующими техническими факторами:

а) версией СУБД
б) наличием или отсутствием физической копии
в) наличием или отсутствием у используемой БД режима архивирования освободившихся журналов.

Заметим также, что в нашем случае речь идет о восстановлении данных от логических потерь, а не физических (разрушений файлов), что может потребовать давней, а не самой последней по времени физической резервной копии. Кроме того, восстанавливать (вообще-то) можно как непосредственно образ таблицы, то есть сразу ее состояние на положенный момент времени, так и историю изменений, по которой затем реконструировать потерянные данные самостоятельно. Вот некоторые варианты восстановления:

Как видно, способы, предлагаемые Oracle, действительно многообразны, возможно даже избыточно. Из них наиболее универсальными остаются классические для баз данных - восстановление по логической копии таблицы, полученной с помощью exp, и восстановление по физической копии. На второе место по универсальности можно поставить восстановление по истории изменений, почерпнутой из журналов (как активных, так и архивных копий), а на третье – ряд интересных возможностей версий 9 и 10, хотя и специфичных, но также обладающих своими достоинствами.

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

Восстановление по физической холодной копии

Если в распоряжении администратора имеется физическая холодная копия БД (полный комплект файлов, образующих в Oracle БД, и скопированных при остановленной БД), можно извлечь образ нужной таблицы по состоянию на момент закрытия БД перед снятием холодной копии. Идея такого восстановления очень проста: запустить БД по холодной копии, извлечь из нее таблицу программой exp и перенести в текущую БД. Тем не менее, здесь тоже могут быть свои небольшие хитрости:

хотя запускать БД по холодной копии проще на другой, идентичной машине, сделать это можно и на одной машине с основной БД, не прерывая работы последней

Итак, пусть сейчас в активном состоянии находится БД MYDB и в каталоге c:\oracle\oradata\mydb\backup\1-cold (операционной системы Windows) находится полный комплект файлов ее холодной копии.

Подготовка файлов холодной копии для запуска

Заведем каталог и скопируем туда все файлы холодной копии, где бы они не находились изначально. Все равно мы их потом удалим, так что иметь их в одном каталоге просто удобнее. Например:

>mkdir c:\oracle\temp
>copy c:\oracle\oradata\mydb\backup\1-cold\* c:\oracle\temp

Откорректируем файл c:\oracle\temp\init.ora. Заменим все имена каталогов, имя СУБД и добавим один новый параметр:

...

background_dump_dest=c:\oracle\temp
core_dump_dest=c:\oracle\temp
user_dump_dest=c:\oracle\temp
control_files=("c:\oracle\temp\control01.ctl")

instance_name=temp

lock_name_space=temp # нужно, если восстанавливаем таблицу без
# останова основной БД и на той же машине

...

Менять имя БД в реанимированной холодной копии не будем (хотя это и возможно), а СУБД для ее активизации назовем иначе (TEMP), так как две СУБД с одинаковым именем на одной машине одновременно работать не смогут. Но одной только смены имени СУБД недостаточно; чтобы не было конфликта имен из-за сохранения имени БД, мы вынуждены добавить в INIT-файл новой СУБД специальный параметр LOCK_NAME_SPACE с указанием ее (нового) имени.

Активация новой БД

В Windows мы обязаны завести службу ОС:

>oradim -new -sid temp –pfile c:\oracle\temp\init.ora

Запускаем СУБД, открываем контрольный файл и запрашиваем исходные расположения файлов БД холодной копии:

>set ORACLE_SID=temp
> sqlplus "/ AS SYSDBA"
SQL> STARTUP MOUNT PFILE='C:\oracle\temp\init.ora'
SQL> SELECT name FROM v$datafile;
SQL> SELECT name FROM v$tempfile;
SQL> SELECT member FROM v$logfile;

Теперь следует пройтись по полученному списку файлов и поменять им в контрольном файле имена, например:

SQL> ALTER DATABASE RENAME FILE
2 'c:\oracle\oradata\mydb\system01.dbf' TO
3 'c:\oracle \temp\system01.dbf';
SQL> ALTER DATABASE RENAME FILE
2 'c:\oracle\oradata\mydb\redo02.log' TO
3 'c:\oracle\temp\redo02.log';
...

Теперь базу можно открыть:

SQL> ALTER DATABASE OPEN;

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

Вот как может выглядеть извлечение данных:

SQL> HOST exp scott/tiger TABLES=(emp)

Вот как может выглядеть восстановление:

SQL> CONNECT scott/tiger@mydb
SQL> TRUNCATE TABLE emp;
SQL> HOST imp scott/tiger@mydb TABLES=(emp)

Убираем за собой

Данные извлечены, реанимированная БД стала не нужна, и компьютер от нее нужно освободить. Для этого ее можно закрыть, удалить все связанные с ней файлы, а в Windows еще почистить реестр ОС. Например, в Windows это обеспечат следующие действия:

>oradim -shutdown -sid temp
>oradim -delete -sid temp
>rmdir /s /q c:\oracle\temp
>del /q expdat.dmp

Восстановление по физической горячей копии

Если БД находится в состоянии архивирования, имеются горячие копии ее файлов и архивированные копии журнальных файлов, то восстановление таблицы грубо выглядит так же, как при восстановлении по холодной копии (на той же или идентичной машине восстанавливаем БД, извлекаем нужные данные и удаляем реанимированную БД), но дополнительные технические возможности горячего резервирования позволяют организовать восстановление более экономно и точно.

Отличия в копировании

При копировании файлов горячей копии можно сэкономить на копировании файлов табличных пространств, где нет данных интересующих нас таблиц. Например, в нашем случае достаточно скопировать в каталог c:\oracle\temp только файлы табличных пространств SYSTEM и USERS. Правда, смонтировав новую СУБД, мы должны будем, как и прежде, переименовать файлы – но только те, что скопировали, а вот оставшиеся нужно будет попросту отключить, например:

SQL> ALTER DATABASE RENAME FILE
2 'c:\oracle\oradata\mydb\system01.dbf' TO
3 'c:\oracle \temp\system01.dbf';
...
SQL> ALTER DATABASE DATAFILE 'c:\oracle\temp\undotbs01.dbf' OFFLINE;
SQL> ALTER DATABASE DATAFILE 'c:\oracle\temp\tools01.dbf' OFFLINE;
SQL> ALTER DATABASE TEMPFILE 'c:\oracle\temp\temp01.dbf' OFFLINE;

Отличия в восстановлении

При восстановлении по горячей резервной копии данные можно восстановить на любой момент времени в промежутке между временем снятия горячей копии файлов табличного с нужными нам данными (USERS) и временем версии контрольного файла, по которому восстанавливаемся. Например:

SQL> RECOVER DATABASE UNTIL TIME '2004-09-10:12:00:00'
SQL> ALTER DATABASE OPEN RESETLOGS;
SQL> HOST exp scott/tiger TABLES=(emp)

Фраза RESETLOGS при открытии после незавершенного восстановления данных технически обязательна.

В результате мы извлечем из резервной копии таблицу SCOTT.EMP такой, какой она была 10 сентября 2004 года в 12 часов дня.

Технологические упрощения благодаря использованию RMAN

Программа RMAN из штатной поставки Oracle часто позволяет организовать процедуры резервирования и восстановления более удобно, нежели чем при ручном выполнении операций. Ниже приводится особо отчетливый тому пример. Правда, он исходит из определенных допущений, однако ни в коей мере не отражающих функциональные «ограничения» RMAN, а сделанных лишь для простоты. Конкретно будем считать, что:

Последние три пункта взяты для упрощения примера. Упомянутая избыточность копирования файлов скрытая, так как явно мы будем копировать наоборот, существенно меньше прежнего.

Вот как теперь можно восстановить таблицу, используя синтаксис RMAN версии 9:

>RMAN NOCATALOG TARGET /
RMAN> SQL 'TRUNCATE TABLE emp';
RMAN> SHUTDOWN IMMEDIATE
RMAN> HOST 'mkdir c:\oracle\temp';
RMAN> HOST 'copy c:\oracle\oradata\mydb\control01.ctl c:\oracle\temp';
RMAN> HOST 'copy c:\oracle\oradata\mydb\redo01.log c:\oracle\temp';
RMAN> HOST 'copy c:\oracle\oradata\mydb\redo02.log c:\oracle\temp';
RMAN> STARTUP MOUNT
RMAN> RESTORE DATABASE UNTIL TIME 'SYSDATE - 10';
RMAN> RECOVER DATABASE UNTIL TIME 'SYSDATE - 10';
RMAN> ALTER DATABASE OPEN RESETLOGS;
RMAN> HOST 'exp scott/tiger TABLES=(emp)';
RMAN> SHUTDOWN IMMEDIATE
RMAN> HOST 'copy c:\oracle\temp\control01.ctl c:\oracle\oradata\mydb';
RMAN> HOST 'copy c:\oracle\temp\redo01.log c:\oracle\oradata\mydb';
RMAN> HOST 'copy c:\oracle\temp\redo02.log c:\oracle\oradata\mydb';
RMAN> HOST 'rmdir /s /q c:\oracle\temp';
RMAN> STARTUP MOUNT
RMAN> RESTORE DATABASE;
RMAN> RECOVER DATABASE;
RMAN> ALTER DATABASE OPEN;
RMAN> HOST 'imp scott/tiger TABLES=(emp)';
RMAN> HOST 'del /q expdat.dmp';
RMAN> EXIT

То есть мы сохранили текущие контрольный и журнальные файлы, восстановили базу на 10 суток назад, извлекли нужные данные, вернули текущие контрольный и журнальные файлы на старое место, восстановили базу «как и было» и занесли в нее старые данные таблицы.

Что последнем сценарии избыточно, а что необходимо, читатель разберется сам в порядке упражнения. Замечательно однако, что приведенный перечень действий легко оформляется файлом, то есть легко автоматизируется. Например, если приведенные команды разместить в файле restore_emp.rcm, то восстановить образ таблицы по состоянию на 10 суток назад можно, набрав в ОС:

>RMAN CMDFILE=restore_emp.rcm NOCATALOG TARGET /

Внимательный читатель заметит, что подобную автоматизацию можно организовать и без использования RMAN, работая через SQL*Plus. Верно, но RMAN все же открывает больше возможностей. Например, горячие копии, по которым мы восстанавливаемся, могут быть инкрементальными, а потому гораздо более компактными, что существенно для чисто физической возможности их более долговременного хранения.

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

Дополнительная информация

За дополнительной информацией обращайтесь в компанию Interface Ltd.

Обсудить на форуме

Рекомендовать страницу

INTERFACE Ltd.
Телефон/Факс: +7 (495) 925-0049
Отправить E-Mail
http://www.interface.ru
Rambler's Top100
Ваши замечания и предложения отправляйте редактору
По техническим вопросам обращайтесь к вебмастеру
Дата публикации: 11.11.04