Поиск по этому блогу

четверг, марта 19, 2009

Как организовать горячий резерв БД

Как организовать горячий резерв БД

Владимир Пржиялковский,
координатор Евро-Азиатской Группы Пользователей Oracle,
преподаватель УКЦ Interface Ltd.
В некоторых информационных системах требуется обеспечить бесперебойный доступ к БД невзирая на всевозможные сбои и отказы оборудования и программ. Задача придать системе "высокую степень доступности" не имеет единственного решения в ИТ, а вместо этого имеет гамму разных решений, каждое со своими выгодами и ограничениями. Многие из таких решений реализованы и в Oracle рядом специальных конфигураций системы СУБД-БД. Одно из самых доступных - организация "горячего резерва". В Oracle для обозначения горячего резерва используется термин "standby".
Основные принципы горячего резервирования
В общем, принципы организации горячего резерва в Oracle довольно просты:
(1) Организуются две активные БД: одна основная, и другая резервная.
(2) Основная БД работает в режиме архивирования журналов. На возможность подсоединения к ней и на работу с данными никаких ограничений не накладывается.
(3) Резервная БД работает в специальном режиме постоянного восстановления с архивированных журналов, получаемых от основной БД; она все время "догоняет" основную.
(4) Из этого специального режима резервную БД можно перевести в другой, когда она приостановит процедуру восстановления и сможет предоставить свои данные, однако только для чтения. Из этого второго режима мы может вернуться в первый, для нее основной.
(5) Кроме этого, из режима восстановления резервную БД можно перевести в режим обычной полнофункциональной БД, но теперь уже безвозвратно.
Техника "standby" существует в Oracle давно, и в деталях реализации претерпела за прошедшее время несколько изменений. Ниже она будет описана по состоянию для версии 9.0.
Что дает пример ниже
Техника горячего резервирования описана в документации по Oracle. Однако давно замечено (интересно, что и в фирме об этом знают!), что эта документация, за исключением избранных мест, не может служить толковым учебником. К горячему резервированию это относится в полной мере.
С другой стороны есть целый ряд статей, где методично рассказано, как организовать standby database. Однако они все или относятся к Unix, и/или содержат ошибки - по крайней мере те, что попадались мне на глаза.
Пример организации резервного копирования ниже
а) относится к платформе Windows, то есть наиболее демократичен в смысле аудитории
б) не требует наличия второй машины (что, в общем, бестолково для реальной практики, но вполне нормально, и даже удобно, для знакомства)
в) не содержит ошибок.
Пользователи на платформе Unix, как правило, более продвинутые, без особого труда внесут в приводимый пример необходимые правки.
Постановка задачи и план решения
Пусть имеется БД teacher.class (использовано глобальное именование БД). Создадим для нее резервную БД с именем sb.class (имя sb часто используется в таких примерах, но это - чистая условность). Она будет работать на той же машине, что и teacher.class. Расположения каталогов будем считать OFA-удовлетворительным.
Для teacher.class должна иметься копия БД (проще, если холодная) и должен быть включен режим архивации. Если этого нет, перед выполнением примера нужно об этом позаботиться.
Вот, для определенности, выдержка из файла INIT.ORA для teacher.class в исходном состоянии:

background_dump_dest=d:\oracle\admin\teacher\bdump
core_dump_dest=d:\oracle\admin\teacher\cdump
user_dump_dest=d:\oracle\admin\teacher\udump

db_domain="class"
global_names = true
remote_login_passwordfile=EXCLUSIVE

compatible=9.0.0
db_name=teacher

instance_name=teacher
##################################
log_archive_start = true
log_archive_dest = "e:\oracle\oradata\teacher\archive"
log_archive_format = teachers%s.arc
План нижеприводимого решения включает следующие действия:
1. Подготовка основной БД к работе в спарке с резервной
2. Клонирование основной БД и формирование из полученного клона резервной БД
3. Конфигурирование сетевых компонент Oracle Net для возможности общения двух БД друг с другом
4. Запуск резервной БД в рабочем режиме
Подготовка места для резервной БД
Сначала резервная БД создается клонированием основной, затем мы "вдохнем в нее жизнь" и запустим в режиме восстановления. Поэтому прежде всего для sb.class нужно подготовить место на диске.
В нашем примере это каталог d:\oracle\admin\sb с подкаталогами udump, bdump, cdump и pfile, а также c:\oracle\oradata\sb - их нужно завести.
Еще не забудем завести каталог e:\oracle\oradata\sb\archive для хранения собственных архивов sb.class (на будущее, когда эту базу переведут в основной режим) и каталог e:\oracle\oradata\sb\teacher_archive для приема архивов от teacher.class.
Готовим основную БД
Подправим INIT.ORA для teacher.class:

background_dump_dest=d:\oracle\admin\teacher\bdump
core_dump_dest=d:\oracle\admin\teacher\cdump
user_dump_dest=d:\oracle\admin\teacher\udump

db_domain="class"
global_names = true
remote_login_passwordfile=EXCLUSIVE

control_files=("c:\oracle\oradata\teacher\control01.ctl")
compatible=9.0.0
db_name=teacher

instance_name=teacher
##################################
log_archive_start = true
#####log_archive_dest = "e:\oracle\oradata\teacher\archive"
log_archive_dest_1 = "location=e:\oracle\oradata\teacher\archive"
log_archive_format = teachers%s.arc
log_archive_dest_state_1 = enable
log_archive_dest_2 = "service=sb.class"
log_archive_dest_state_2 = enable
log_archive_min_succeed_dest = 1
fal_client = "sb.class"
Правкой затронута только нижняя часть, отделенная строкой из #.
Во-первых, от параметра LOG_ARCHIVE_DEST (сохраненному для совместимости) мы перешли к более современному LOG_ARCHIVE_DEST_1. Параметры LOG_ARCHIVE_DEST_N в последних версиях Oracle задают направления копирования освободившихся журналов в архив, а параметры LOG_ARCHIVE_DEST_STATE_N позволяют имеющиеся направления "включать" и временно "отключать".
В нашем случае к старому архиву e:\oracle\oradata\teacher\archive добавилось как раз еще одно такое направление, но уже не в виде каталога, как раньше, а в виде БД, которой teacher.class будет пересылать свои журналы.
Параметр FAL_CLIENT = "sb.class" уточняет, что это будет резервная БД sb.class и что пересылка будет автоматической.
Остановим основную БД и выдадим в SQL*Plus:
STARTUP PFILE=?/database/initteacher.ora
ALTER DATABASE CREATE STANDBY CONTROLFILE AS 'c:\oracle\oradata\sb\control01.ctl';
ALTER SYSTEM ARCHIVE LOG CURRENT;
SHUTDOWN
То есть мы приготовили контрольный файл для резервной БД и зафиксировали точку отсчета для пересылки архивируемых журналов на sb.class.
Готовим клон для резервной БД
Копируем все файлы БД teacher.class, кроме контрольного, в c:\oracle\oradata\sb. Контрольный там уже есть.
Копируем INIT.ORA БД teacher.class в d:\oracle\admin\teacher\pfile. Правим его:

background_dump_dest=d:\oracle\admin\sb\bdump
core_dump_dest=d:\oracle\admin\sb\cdump
user_dump_dest=d:\oracle\admin\sb\udump

db_domain="class"
global_names = true
remote_login_passwordfile=EXCLUSIVE

control_files=("c:\oracle\oradata\sb\control01.ctl")
compatible=9.0.0
db_name=teacher

instance_name=sb
##################################
log_archive_format = teachers%s.arc
db_file_name_convert = "\ORADATA\TEACHER", "\ORADATA\SB"
log_file_name_convert = "\ORADATA\TEACHER", "\ORADATA\SB"
standby_archive_dest = "e:\oracle\oradata\sb\teacher_archive"
log_archive_dest = "e:\oracle\oradata\sb\archive"
lock_name_space = sb
fal_server = "teacher.class"
Обратите внимание на изменение имен каталогов и названий в верхней части текста, однако главные изменения расположены ниже строки-комментария.
Параметры DB_FILE_NAME_CONVERT и LOG_FILE_NAME_CONVERT нужны только если структуры каталогов основной и резервной БД не совпадают. В нашем случае, когда обе БД работают на одной машине, это неизбежно. Когда обе БД работают на разных машинах, проще использовать одинаковую структуру каталогов и об этих параметрах забыть.
Параметр STANDBY_ARCHIVE_DEST указывает на каталог, куда "принимающая сторона" sb.class будет складывать поступающие от teacher.class архивные копии журнала.
Параметр LOG_ARCHIVE_DEST задает каталог-архив уже для своих изменений sb.class (на будущее).
Параметр LOCK_NAME_SPACE нужен только в нашей не типичной для практики ситуации, когда обе БД будут работать на одной машине; без него две СУБД не смогут одновременно общаться с разными БД, имеющими одинаковые имена.
Наконец, параметр FAL_SERVER симметричен FAL_CLIENT в INIT-файле для teacher.class.
Копируем из e:\oracle\oradata\teacher\archive в e:\oracle\oradata\sb\teacher_archive последний по времени архивированный файл.
Обеспечиваем взаимодействие по Oracle Net
Нужно ненадолго отвлечься от резервной БД и подправить файлы listener.ora и tnsnames.ora, чтобы обе СУБД могли общаться. У нас будет автоматическая пересылка файлов на резервную БД (а могли бы этого не делать и переносить архивные файлы вручную, но это не очень интересно), и для этого основная база должна уметь соединяться с резервной. Нужные конфигурационные файлы у нас находятся в одном месте: в %oracle_home%\network\admin, а в "боевых условиях" они будут разнесены по разным машинам. Добавляем в listener.ora фрагмент:

(SID_LIST =
(оставить, как было)
(SID_DESC =
(GLOBAL_DBNAME = teacher.class)
(ORACLE_HOME = c:\oracle\ora90)
(SID_NAME = sb)
)
)
После этого listener надо перезапустить, проще всего - через окошко Services в ОС Windows, но можно и из командной строки.
В файл tnsnames.ora добавляем

sb.class =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = wsa46)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = sb)
)
)
"Оживляем" резервную БД и запускаем ее
Теперь резервную БД нужно "оживить". Войдем в консольном окошке ОС в каталог %oracle_home%\database. Скопируем initteacher.ora в initsb.ora и подправим в initsb.ora ссылку на файл: IFILE='c:\oracle\admin\teacher\pfile\init.ora' заменим на IFILE='c:\oracle\admin\sb\pfile\init.ora'.
Создадим файл пароля для sb.class:
orapwd file=PWDsb.ora password=change_on_install
Заведем службу ОС для sb.class:
oradim -new -sid sb -startmode m -pfile c:\oracle\ora90\database\initsb.ora
"Приводим" резервную БД "в чувство" и переводим в режим автоматического подката по получаемым файлам журналов. Выдаем в SQL*Plus:
CONNECT sys/change_on_install AS SYSDBA
STARTUP MOUNT PFILE=?/database/initsb.ora
RECOVER MANAGED STANDBY DATABASE
В этом месте SQL*Plus "зависает", но так и должно быть. Уходим из этого окошка, но не закрываем его.
Проверка
Теперь можно для наглядности вывести на экран два окошка с содержимым каталогов e:\oracle\oradata\teacher\archive и e:\oracle\oradata\sb\teacher_archive соответственно.
Запускаем снова основную БД в окошке с SQL*Plus, где мы эту базу останавливали:
STARTUP PFILE=?/database/initteacher.ora
Выдадим несколько раз
ALTER SYSTEM SWITCH LOGFILE;
Если все было проделано без ошибок, в обоих окошках с каталогами можно наблюдать появление одних и тех же архивных копий журнала, причем с запаздыванием: сначала в одном, потом в другом. Это свидетельствует о том, что архивные копии реально пересылаются на резервную БД.
Еще для проверки можно запустить и процесс внесения в основную БД фактических изменений, в результате чего журнальные файлы начнут переключаться самостоятельно. Для нас результат должен быть тем же самым.
Перевод резервной БД в состояние, допускающее выборку
Откроем новое консольное окошко, где выдадим в SQL*Plus:
CONNECT sys/change_on_install@sb.class AS SYSDBA
RECOVER MANAGED STANDBY CANCEL
EXIT
Вернемся в прежнее окошко с резервной БД и увидим, что сеанс SQL*Plus в нем "отвис". Сейчас архивные копии продолжают поступать в резервную БД, однако сама база уже не подкатывается. Наберем
ALTER DATABASE OPEN READONLY;
Теперь из резервной базы можно делать выборки данных.
Возврат резервной БД в режим подката
В этом же последнем окошке набираем:
CONNECT sys/change_on_install AS SYSDBA
SHUTDOWN
STARTUP MOUNT PFILE=?/database/initsb.ora
RECOVER AUTOMATIC STANDBY DATABASE
CANCEL
RECOVER MANAGED STANDBY DATABASE
Как и прежде, тут мы "зависаем".
Перевод резервной БД в рабочее состояние
Вначале поступаем, как и прежде, а потом - иначе. В новом окошке выдадим в SQL*Plus:
CONNECT sys/change_on_install@sb.class AS SYSDBA
RECOVER MANAGED STANDBY CANCEL
ALTER DATABASE RECOVER STANDBY DATABASE;
ALTER DATABASE RECOVER CANCEL;
ALTER DATABASE ACTIVATE STANDBY DATABASE;
Теперь правильнее всего будет остановить бывшую резервную, а отныне - рабочую БД, снять с нее холодную копию, проделать необходимые правки в файлах Oracle Net и запустить базу снова и подготовить для нее новый резерв. После этого можно будет использовать ее в рабочем режиме.





Standby Database
" Primary Database Setup
" Standby Database Setup
" Standby Recovery
" Managed Standby Recovery
" Read Only Database
" Standby Database Backup
Primary Database Setup
" Shutdown the database using: SHUTDOWN IMMEDIATE
" Backup all database files.
" Add an entry for the standby server into the tnsnames.ora file:
STBY=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = myServerName)(PORT = 1512))
)
(CONNECT_DATA =
(SERVICE_NAME = STBY.world)
)
)
" Assuming your database in already in ARCHIVELOG mode the first four of the following init.ora paramters will already be set. Add the last two entires:
log_archive_start = true
log_archive_dest_1 = "location=c:\Oracle\oradata\SID\archive\ mandatory reopen=5"
log_archive_dest_state_1 = enable
log_archive_format = %%ORACLE_SID%%T%TS%S.ARC

log_archive_dest_2 = "service=STBY optional reopen=5"
log_archive_dest_state_2 = enable
" Startup the database using: STARTUP PFILE=C:\Oracle\Admin\SID\PFile\init.ora
" Create standby database controlfile using: ALTER DATABASE CREATE STANDBY CONTROLFILE AS 'c:\stbycf.f';
Standby Database Setup
" Copy the production backup files to the standby server.
" Copy the standby controlfile to the standby server.
" Alter the control_files and archive parameters of the init.ora as follows:
#use the standby service name
service_names = STBY.world

#reference the standby controlfile
control_files = ("c:\Oracle\oradata\SID\stbycf.f")

#switch archiving and reference archive directory
log_archive_start = false
log_archive_dest = c:\Oracle\oradata\SID\archive\
standby_archive_dest = c:\Oracle\oradata\SID\archive\
log_archive_format = %%ORACLE_SID%%T%TS%S.ARC
" Add the following entries into the listener.ora file:
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = ntfm451)(PORT = 1512))
)

STANDBY_LISTENER = (ADDRESS_LIST=
(ADDRESS=(PROTOCOL=tcp)(PORT=1512)(HOST=myHost))
)
The file should resemble the following:
# LISTENER.ORA Network Configuration File: C:\Oracle\Ora817\network\admin\listener.ora
# Generated by Oracle configuration tools.

LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = myHost)(PORT = 1521))
)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = myHost)(PORT = 1512))
)
)
(DESCRIPTION =
(PROTOCOL_STACK =
(PRESENTATION = GIOP)
(SESSION = RAW)
)
(ADDRESS = (PROTOCOL = TCP)(HOST = myHost)(PORT = 2481))
)
)

STANDBY_LISTENER = (ADDRESS_LIST=
(ADDRESS=(PROTOCOL=tcp)(PORT=1512)(HOST=myHost))
)



SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = C:\Oracle\Ora817)
(PROGRAM = extproc)
)
(SID_DESC =
(ORACLE_HOME = C:\Oracle\Ora817)
(SID_NAME = PGOAL1)
)
)
" Reload the listener file using lsnrctl reload from the command prompt.
" Add the following entry into the tnsnames.ora file:
STBY=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = myServerName)(PORT = 1512))
)
(CONNECT_DATA =
(SERVICE_NAME = STBY.world)
)
)
At this point the recovery process can start.

Standby Recovery
Regular recovery requires archive logs to be copied manually between the server and user initiation of the recovery process.
" Copy all archive logs from the primary to the standby server.
" From sqlplus do the following:
SQL> CONNECT sys/password AS SYSDBA
SQL> STARTUP NOMOUNT PFILE=C:\Oracle\Admin\SID\PFile\init.ora
SQL> ALTER DATABASE MOUNT STANDBY DATABASE;
SQL> RECOVER STANDBY DATABASE;
This process must be repeated every time archive logs are manually transfered.

Managed Standby Recovery
During managed recovery the transfer of archivelogs is controlled by the servers without user intervention.
" Copy all archive logs from the primary to the standby server. This is the only time you should need to do this.
" From sqlplus do the following:
SQL> CONNECT sys/password AS SYSDBA
SQL> STARTUP NOMOUNT PFILE=C:\Oracle\Admin\SID\PFile\init.ora
SQL> ALTER DATABASE MOUNT STANDBY DATABASE;
SQL> RECOVER MANAGED STANDBY DATABASE;
This window will then hang indefinitely while it continues to look for archive logs to apply. To stop the recovery open another sqlplus session and type:
SQL> RECOVER MANAGED STANDBY DATABASE CANCEL;
Read Only Database
The standby database can be opened in read only mode at any point. While open in this mode new archive logs are not applied to the database.
SQL> -- Cancel recovery if necessary
SQL> RECOVER MANAGED STANDBY DATABASE CANCEL;
SQL> ALTER DATABASE OPEN READ ONLY;
The database can subsequently be switched back to recovery mode as follows:
SQL> CONNECT sys/password AS SYSDBA
SQL> SHUTDOWN IMMEDIATE
SQL> STARTUP NOMOUNT PFILE=C:\Oracle\Admin\SID\PFile\init.ora
SQL> ALTER DATABASE MOUNT STANDBY DATABASE;
SQL> RECOVER MANAGED STANDBY DATABASE;
Backup Standby Database
Backups of the standby database can only be performed if the database is shut down or in read only mode. Read only mode is best for managed recovery systems as archive logs will still be transfered during the backup process, thus preventing gap sequences. Once the server is in the desired mode simple copy the appropriate database files.

For more information see:
" Oracle8i Standby Database Concepts and Administration
Hope this helps. Regards Tim...