Рубрика:
Администрирование /
Резервное копирование
|
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|
Сергей Косько
Резервное копирование и восстановление базы данных Oracle средствами ОС
Мы установили какое-либо приложение, хранилищем данных в котором служит СУБД Oracle. Но вводить систему в производственную эксплуатацию ещё рано. Предварительно необходимо создать надёжную методику резервного копирования и восстановления базы данных.
Одним из самых функциональных средств резервного копирования от Oracle является утилита RMAN. Однако использовать столь сложную систему для резервного копирования зачастую избыточно (если эксплуатируется одна-две базы данных). Кроме того, RMAN, как правило, использует отдельную базу в качестве хранилища своей собственной информации. Чтобы избежать ситуации, когда данные, необходимые для восстановления базы, хранятся в этой же базе, для резервного копирования собственно каталога RMAN необходимо использовать другие средства. Различные универсальные программы резервного копирования, которые могут работать с базами данных Oracle, тоже избыточны или небесплатны. Что же выбрать? Самый простой и экономный способ – решить эту задачу с помощью обычных скриптов и стандартных системных утилит.
Основным критерием качества методов восстановления данных является их адекватность, способность восстановить необходимые данные при любом возможном сбое. Предлагаю вам свой способ решения этой задачи для СУБД Oracle.
Рассмотрим несколько примеров резервного копирования-восстановления без использования RMAN или других утилит.
Возьмём в качестве исходной следующую информацию:
- В тестах будем использовать СУБД Oracle версии 10.2. для ОС Solaris.
- СУБД настроена на работу в режиме АRCHIVELOG.
- Рассмотрим 2 сценария восстановления: полного и неполного.
- Будем исходить из того предположения, что мы восстанавливаем данные на тот же самый сервер (или точную копию рабочего сервера БД, на котором уже установлена ОС, ПО СУБД Oracle, все необходимые исправления и создана необходимая структура каталогов).
- Для наглядности создадим отдельные архивы для файлов данных, управляющих файлов, файлов инициализации и паролей.
- Выполним полную копию базы данных двумя способами:
- с остановкой экземпляра (холодная копия);
- без остановки работы экземпляра (горячая копия).
- Расположение файлов базы данных имеет следующую структуру:
- /ora/oracle/oradata/ORCL – файлы данных;
- /ora/oracle/oradata/Redo-Ctrl/replica0 – первая копия управляющих и журнальных файлов;
- /ora/oracle/oradata/Redo-Ctrl/replica1 – вторая копия управляющих и журнальных файлов;
- /ora/oracle/oradata/log – файлы архивных журналов.
Сделаем полную копию БД двумя вышеуказанными способами:
- Холодная копия (cм. листинг 1). Это самый простой пример, он применяется редко. Мы рассмотрим его в целях сравнения с более сложными примерами.
$backuponl.sh ORCL /backup/hot
- Горячая копия (см. листинг 2). Создаёт практически аналогичный набор файлов данных, за исключением того, что копии активных журналов redo делать не нужно. Сохраним в архиве одну копию управляющего файла и скрипт control.sql для его пересоздания.
$backup.sh ORCL /backup/cold
Сценарии восстановления
Будем имитировать сбой носителя в некоторый момент времени после выполненного резервного копирования, выполняя несколько принудительных переключений активных журналов командой:
SQL> alter system switch logfile;
Затем будем стирать и восстанавливать из архива файлы, принадлежащие БД. Предполагаем, что архивные журналы имеются и доступны для восстановления в каталоге, указанном в параметрах db_recovery_file_dest/log_archive_dest.
Сценарий 1. Клонирование БД из холодной копии
Допустим, нам необходимо запустить базу данных на компьютере с аналогичным программным обеспечением и дисками. Сделаем это с помощью холодной копии. Удалим все файлы базы данных:
testcase$cd /ora/oracle/oradata/ORCL;find . -type f -exec rm -f {} \;
testcase$cd /ora/oracle/oradata/Redo-Ctrl;find . -type f -exec rm -f {} \;
Проведём восстановление:
testcase$cd /backup/cold
testcase$tar xvf control.tar
testcase$tar xvf data.tar
testcase$tar xvf dbs.tar
testcase$tar xvf redo.tar
testcase$dbstart
Это практически единственный случай, когда могут пригодиться копии активных (не путать с архивными) журналов базы данных. Во всех остальных случаях необходимо восстановление БД, и устаревшие копии уже не содержат актуальной информации. Гораздо важнее иметь полный (без пропусков) набор архивных журналов. На самом деле в данном случае активные журналы тоже не обязательны.
Часто при создании копии рабочей базы нет необходимости запускать базу именно с опцией NORESETLOGS. Если есть холодная копия, но без копии журналов (файл redo.tar), после восстановления файлов из архива нужно сделать следующее:
testcase$sqlplus "/ as sysdba"
SQL>startup mount
…
Database mounted.
SQL> recover database using backup controlfile until cancel;
ORA-00279: change 817959 generated at 05/04/2007 09:15:19 needed for thread 1
ORA-00289: suggestion :
…
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
cancel
Media recovery cancelled.
SQL>alter database open resetlogs;
Database altered.
|
В этом случае применения архивных журналов не происходит, мы просто обманываем базу данных, заставляя её пересоздать активные журналы.
Сценарий 2. Полное восстановление из горячей резервной копии
Смоделируем потерю файлов данных БД. Удалим файлы данных, но не управляющие и журнальные файлы:
testcase$cd /ora/oracle/oradata/ORCL;find . -type f -exec rm -f {} \;
Проведём восстановление только файлов данных из горячей резервной копии (см. листинг 3):
testcase$cd /backup/hot
testcase$tar xvf data.tar
testcase$recover.sh ORCL
В зависимости от версии базы данных и операционной системы может понадобиться пересоздать временный файл – это можно сделать, например, скриптом (см. листинг 4):
testcase$tmprecov.sh ORCL
Сценарий 3. Восстановление файлов управления
Если мы потеряли часть наших управляющих файлов, но сохранилась хотя бы одна копия из указанных в файле init.ora/spfile.ora, нужно скопировать эту копию во все указанные местоположения (например, если пропали файлы в каталоге replica0, нужно скопировать их из каталога replica1). Если пропали все копии управляющих файлов, и только они, необходимо отредактировать файл control.sql (полученный при выполнении горячей копии БД, листинг 2) и выполнить пересоздание управляющего файла. Если такого скрипта мы заранее не создали, тогда нам остаётся только воспользоваться сделанными ранее копиями управляющих файлов:
testcase$tar xvf control.tar
testcase$cp control01.ctl /ora/oracle/oradata/Redo-Ctrl/replica0/control01.ctl
…
testcase$cp control01.ctl /ora/oracle/oradata/Redo-Ctrl/replica1/control03.ctl
testcase$sqlplus "/ as sysdba"
SQL>startup mount
SQL> alter database backup controlfile to trace as 'control.sql' ;
SQL>shutdown
SQL>exit
Затем отредактировать и выполнить скрипт. Существует ещё один способ: скопировать текущий активный журнал в местоположение log_archive_dest в формате log_archive_format, выполнить неполное восстановление и открыть базу с опцией RESETLOGS (потери зафиксированных транзакций при этом не произойдёт, но нумерация архивных журналов начнётся сначала).
Сценарий 4. Восстановление БД при утере копии добавленного файла
После выполнения резервного копирования был добавлен один файл базы данных (см. листинг 5), и впоследствии произошла поломка жесткого диска. А копии управляющего файла и нового файла данных мы сделать не успели. Если попытаться провести восстановление базы из существующих резервных копий, восстановление будет идти только до момента создания нового файла, после чего возникнет ошибка:
SQL> alter database recover automatic using backup controlfile;
alter database recover automatic using backup controlfile
*
ERROR at line 1:
ORA-00283: recovery session canceled due to errors
ORA-01244: unnamed datafile(s) added to control file by media recovery
|
Я думаю, самым надёжным способом избежать подобной ситуации будет иметь достаточное количество реплик файла управления и всегда делать резервную копию добавляемых файлов. Если же такая ситуация произошла, можно воспользоваться последовательностью команд, представленной в листинге 6. Отмечу, что это не готовый скрипт, а лишь примерная последовательность команд с комментариями, поскольку невозможно заранее предугадать номера и названия файлов данных.
Сценарий 5. Восстановление при потере активных журналов БД
Если потеряны не все группы REDO, а только какая-то одна реплика REDO файлов БД, то остановки базы при этом не происходит. В этом случае журналы можно пересоздать или при перезагрузке скопировать файлы из одного каталога в другой. Если же мы потеряли все файлы REDO (или хотя бы как минимум активную группу), полное восстановление невозможно. Остаётся вариант неполного восстановления и последующий запуск БД с опцией RESETLOGS. В этом случае возможна потеря зафиксированных транзакций, и произойдёт сброс последовательности архивных журналов.
Смоделируем ситуацию:
testcase$dbshut
testcase$cd /ora/oracle/oradata/Redo-Ctrl
testcase$find . –type f -name \*.log –exec rm –f {} \;
testcase$sqlpplus "/ as sysdba"
SQL>startup mount
SQL>recover database until cancel
...
cancel
SQL> alter database open resetlogs;
SQL>exit
|
Из этого примера видно, как важно иметь хотя бы две реплики активных журналов базы данных (redo log). В случае их уничтожения – потеря информации (пусть иногда и допустимая) неизбежна. Её можно лишь минимизировать, например установив параметр archive_lag_target (его минимальное значение – 60 секунд).
Сценарий 6. Восстановление только по резервной копии и архивным журналам
Исходная БД погибла, остались резервная копия и архивные журналы. В данном случае, если нет специальных систем аппаратного зеркалирования управляющих файлов и журналов, возможно только неполное восстановление и последующий запуск с опцией RESETLOGS. Последовательность шагов во многом аналогична сценарию 2, но есть отличия: восстанавливаются не только файлы данных, но и управляющие файлы, файлы инициализации и паролей.
testcase$tar xvf data.tar
testcase$tar xvf control.tar
testcase$tar xvf dbs.tar
Потом, поскольку активные журналы потеряны, производится неполное восстановление (см. листинг 7). БД открывается с опцией RESTLOGS.
testcase$recovincomplett.sh ORCL
Итоги
Подводя итоги рассмотренных сценариев, хотелось бы отметить основные моменты:
- Резервная копия должна быть обязательно полной (все файлы данных, все архивные журналы, файлы управления, инициализации и пароли).
- При восстановлении производственной базы нужно стараться не допустить случая неполного восстановления (с опцией RESETLOGS), поскольку это изменяет последовательную нумерацию журналов и есть риск потери данных. Вариант восстановления БД с переходом через точку RESETLOGS вообще-то существует, но он довольно громоздкий. Не стоит усложнять самому себе жизнь. Описание этого метода приводится, например, в книге «Oracle Backup & Recovery Handbook» [2, глава 10].
- Чтобы избежать случая неполного восстановления, следует беречь активные журналы. В большинстве случаев их резервная копия невозможна, необходимо иметь несколько реплик, размещать их на RAID1 и т. п.
- Копировать активные журналы REDO, можно только при холодной копии, и нужны они только для создания клона БД.
- Не менее важно беречь и управляющие файлы. Их можно, как правило, пересоздать, но это требует времени, потеря хотя бы одной копии управляющего файла делает невозможным старт БД.
- Для восстановления необходимо иметь архивные журналы, их тоже желательно включать в резервную копию, или настроить файл параметров так, чтобы журналы архивировались в несколько мест сразу, например, на локальный диск и на сетевой. (Параметр LOG_ARCHIVE_DEST_N.)
- Холодная и горячая резервные копии БД для восстановления пригодны одинаково, нельзя сказать, что горячая копия не позволяет сделать то, что позволяет холодная. За исключением случая клонирования. Горячая копия всегда нуждается в применении впоследствии команды «recover». Для этого не обязательно, но полезно после завершения копии принудительно переключить активный журнал, чтобы не ждать, когда он переключится сам, а сразу приступать к клонированию базы данных.
- Ну и напоследок, моё трепетное отношение к полному восстановлению относится в основном к производственным базам. Если необходимо восстаноить БД на какой-то момент времени в прошлом, то такой сценарий предусматривает именно неполное восстановление.
Приложение
Листинг 1. Холодная копия БД (файл backup.sh)
#!/bin/sh
#
if [ $# -ne 2 ]
then echo "script needs two parameters: \${ORACLE_SID} <dest dir>"
exit;
fi
#
ORACLE_SID=${1};export ORACLE_SID
copydir=${2};export copydir
#Create lists of files.
#Regular database files
datalist=`sqlplus -s "/ as sysdba" <<EOF
set heading off
set pagesize 0
set linesize 300
set feed off
select file_name from dba_data_files ;
exit ;
EOF`
#Temporary files
templist=`sqlplus -s "/ as sysdba" <<EOF
set heading off
set pagesize 0
set linesize 300
set feed off
select file_name from dba_temp_files;
exit;
EOF`
#Control files ( copy all )
controlist=`sqlplus -s "/ as sysdba" <<EOF
set heading off
set pagesize 0
set linesize 300
set feed off
select name from v\\$controlfile ;
exit ;
EOF`
#Online Redo logs.
redolist=`sqlplus -s "/ as sysdba" <<EOF
set heading off
set pagesize 0
set linesize 300
set feed off
select member from v\\$logfile ;
exit ;
EOF`
#
sqlplus "/ as sysdba" <<EOF
shutdown immediate
exit;
EOF
cd ${copydir}
tar cvf data.tar ${datalist} ${templist}
tar cvf control.tar ${controlist}
tar cvf redo.tar ${redolist}
tar cvf dbs.tar ${ORACLE_HOME}/dbs/init${ORACLE_SID}.ora \
${ORACLE_HOME}/dbs/spfile${ORACLE_SID}.ora \
${ORACLE_HOME}/dbs/orapw${ORACLE_SID}
sqlplus "/ as sysdba" <<EOF
startup
exit;
EOF
#
Листинг 2. Горячая копия БД (файл backuponl.sh)
#!/bin/sh
#
if [ $# -ne 2 ]
then echo "script needs two parameters: \${ORACLE_SID} <dest dir>"
exit;
fi
#
ORACLE_SID=${1};export ORACLE_SID
copydir=${2};export copydir
#Make lists of files for backup.
#data files
datalist=`sqlplus -s "/ as sysdba" <<EOF
set heading off
set pagesize 0
set linesize 300
set feed off
select file_name from dba_data_files ;
exit ;
EOF`
#Controlfile make one copy and one trace
controlist=`sqlplus -s "/ as sysdba" <<EOF
set heading off
set pagesize 0
set linesize 300
set feed off
select name from v\\$controlfile
where rownum=1;
exit ;
EOF`
controldir=`dirname $controlist`
#
sqlplus "/ as sysdba" <<EOF
alter database begin backup;
exit;
EOF
cd ${copydir}
tar cvf data.tar ${datalist}
# Init & passwd files
tar cvf dbs.tar ${ORACLE_HOME}/dbs/init${ORACLE_SID}.ora \
${ORACLE_HOME}/dbs/spfile${ORACLE_SID}.ora \
${ORACLE_HOME}/dbs/orapw${ORACLE_SID}
sqlplus "/ as sysdba" <<EOF
alter database end backup;
alter database backup controlfile to '$controldir/conbackup.ctl' reuse ;
alter database backup controlfile to trace as '$controldir/control.sql';
alter system archive log current ;
exit;
EOF
#
for i in ${controlist}
do
# cp /tmp/conbackup.ctl ${copydir}/`basename ${i}`
tar cvf control.tar $controldir/conbackup.ctl $controldir/control.sql
rm -f $controldir/conbackup.ctl
rm -f $controldir/control.sql
done
#
Листинг 3. Полное восстановление БД (файл recover.sh)
#!/bin/sh
#
if [ $# -ne 1 ]
then echo "script needs one parameter: \${ORACLE_SID}"
exit;
fi
#
ORACLE_SID=${1};export ORACLE_SID
sqlplus "/ as sysdba" <<EOF
startup mount;
alter database recover automatic ;
alter database open;
exit;
EOF
Листинг 4. Добавление к БД нового временного файла (файл tmprecov.sh)
#!/bin/sh
#
if [ $# -ne 1 ]
then echo "script needs one parameter: \${ORACLE_SID}"
exit;
fi
#
ORACLE_SID=${1};export ORACLE_SID
#
#Temporary files
templist=`sqlplus -s "/ as sysdba" <<EOF
set heading off
set pagesize 0
set linesize 300
set feed off
select file_name from dba_temp_files;
exit;
EOF`
for i in ${templist}
do
sqlplus "/ as sysdba" <<EOF
alter database tempfile '$i' drop INCLUDING DATAFILES;
ALTER TABLESPACE "TEMP" ADD TEMPFILE '$i' size 25M autoextend on;
exit;
EOF
done
Листинг 5. Восстановление БД при утере копии вновь добавленного файла и файлов управления (файл addfile.sh)
#!/bin/sh
#
#Script for adding new dstsfile
sqlplus "/ as sysdba" <<EOF
alter tablespace users add datafile
'/ora/oracle/oradata/ORCL/users02.dbf' size 20M;
exit
EOF
Листинг 6. Неполное восстановление при потере активных журналов (файл nofile.sql)
connect / as sysdba
startup mount
alter database recover automatic using backup controlfile
--
--ERROR at line 1:
--ORA-00283: recovery session canceled due to errors
--ORA-01244: unnamed datafile(s) added to control file by media recovery
--ORA-01110: data file 5: '/ora/oracle/oradata/ORCL/users02.dbf'
--
alter database backup controlfile to trace as
'dmpctl.sql';
select name from v$datafile where file#=5;
--NAME
------------------------------------------------
--/ora/oracle/dbs/UNNAMED00005
--
alter database create datafile
'/ora/oracle/dbs/UNNAMED00005'
as '/ora/oracle/oradata/ORCL/users02.dbf';
-- Make changes in scripts for recreate controlfile.
host vi dmpctl.sql
--
shutdown
@dmpctl.sq
Листинг 7. Неполное восстановление при потере активных журналов (файл recovincomplett.sh)
#!/bin/sh
#
if [ $# -ne 1 ]
then echo "script needs one parameter: \${ORACLE_SID}"
exit;
fi
sqlplus "/ as sysdba" <<EOF
startup mount;
alter database recover automatic using backup controlfile;
alter database open resetlogs;
exit;
EOF
- Oracle Database Backup and Recovery Advanced User's Guide 10g Release 2 (10.2) Part Number B14191-02 – http://download-uk.oracle.com/docs/cd/B19306_01/backup.102/b14191/toc.htm.
- Oracle8i Backup & Recovery Handbook, Rama Velpuri and Anand Adkoli.McGraw-Hill/OsborneMedia; 4Rev Ed edition (November 14, 2000).
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|