Дублирование базы данных – это процесс создания рабочей копии (дубликата) целевой (основной) базы данных (target database). Полученная при этом новая база данных называется дублированной и может располагаться с основной базой данных на одном или разных хостах. В Oracle дублированная база данных создаётся с помощью утилиты RMAN.

Дублирование обычно осуществляется для того, что бы получить свежую копию базы данных для целей разработки и тестирования. Реже дублирование используется для восстановления объектов и данных основной базы данных и проверки сделанных ранее на ней же резервных копий. Целевая и дублированная базы данных могут иметь различное расположение файлов данных, содержать разные значения инициализационных параметров, обладать различными именами. Некоторые табличные пространства вообще могут отсутствовать в дублированной базе данных.

В RMAN дублированная база данных всегда создаётся из резервной копии, ранее сделанной на целевой базе данных (базовое дублирование). Начиная с одиннадцатой версии Oracle без такой копии можно обойтись. Связано это с появлением альтернативного метода дублирования – активного. При таком способе дублирования файлы данных передаются в онлайн режиме из основной базы данных по сети. Это позволяет не тратить время на создание и копирование резервных копий, но создаёт  большую нагрузку на сеть, и увеличивает время выполнения процесса дублирования по сравнению с базовым методом.

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

В качестве тестовых мы возьмём две виртуальные машины alfa.alldba.ru и alfa2.alldba.ru с операционными системами Linux CentOS 5.4 и экземплярами базы данных Oracle 10.2. Структура каталогов файловых систем хостов одинакова. Перед нами стоит задача получения рабочего дубликата  целевой базы данных хоста alfa.alldba.ru, и размещение его в виртуальной машине alfa2.alldba.ru. Экземпляр Oracle расположенный на хосте alfa2.alldba.ru в дальнейшем будет называться вспомогательным (Auxiliary), и будет иметь только одно предназначение – это помощь в создании дублированной базы данных.

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

Базовое дублирование

Создание резервной копии

Так как дублированная база создаётся из резервной копии основной базы данных, первым делом с помощью RMAN проводим полное резервное копирование целевой базы данных хоста alfa.alldba.ru:

RMAN> backup database;
Starting backup at 02-MAR-12 using channel ORA_DISK_1 channel ORA_DISK_1: starting full datafile backupset channel ORA_DISK_1: specifying datafile(s) in backupset input datafile fno=00001 name=/u02/oradata/orcl/system01.dbf input datafile fno=00003 name=/u02/oradata/orcl/sysaux01.dbf input datafile fno=00002 name=/u02/oradata/orcl/undotbs01.dbf input datafile fno=00005 name=/u02/oradata/orcl/example01.dbf input datafile fno=00004 name=/u02/oradata/orcl/users01.dbf channel ORA_DISK_1: starting piece 1 at 02-MAR-12 channel ORA_DISK_1: finished piece 1 at 02-MAR-12 piece handle=/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_nnndf_TAG20120 302T092347_7o0svmmk_.bkp tag=TAG20120302T092347 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:06:57 channel ORA_DISK_1: starting full datafile backupset channel ORA_DISK_1: specifying datafile(s) in backupset including current control file in backupset including current SPFILE in backupset channel ORA_DISK_1: starting piece 1 at 02-MAR-12 channel ORA_DISK_1: finished piece 1 at 02-MAR-12 piece handle=/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_ncsnf_TAG20120 302T092347_7o0t8plr_.bkp tag=TAG20120302T092347 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03 Finished backup at 02-MAR-12

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

RMAN> list backup;

List of Backup Sets =================== BS Key Type LV Size Device Type Elapsed Time Completion Time ------- ---- -- ---------- ----------- ------------ --------------- 108 Full 610.20M DISK 00:06:55 02-MAR-12 BP Key: 119 Status: AVAILABLE Compressed: NO Tag: TAG20120302T092347 Piece Name: /u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_nnndf_TAG20120302T092 347_7o0svmmk_.bkp List of Datafiles in backup set 108 File LV Type Ckp SCN Ckp Time Name ---- -- ---- ---------- --------- ---- 1 Full 658208 02-MAR-12 /u02/oradata/orcl/system01.dbf 2 Full 658208 02-MAR-12 /u02/oradata/orcl/undotbs01.dbf 3 Full 658208 02-MAR-12 /u02/oradata/orcl/sysaux01.dbf 4 Full 658208 02-MAR-12 /u02/oradata/orcl/users01.dbf 5 Full 657258 02-MAR-12 /u02/oradata/orcl/example01.dbf BS Key Type LV Size Device Type Elapsed Time Completion Time ------- ---- -- ---------- ----------- ------------ --------------- 109 Full 6.83M DISK 00:00:02 02-MAR-12 BP Key: 120 Status: AVAILABLE Compressed: NO Tag: TAG20120302T092347 Piece Name: /u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_ncsnf_TAG20120302T092 347_7o0t8plr_.bkp Control File Included: Ckp SCN: 658245 Ckp time: 02-MAR-12 SPFILE Included: Modification time: 02-MAR-12

Перенос резервной копии

Так как одним из основных требований дублирования является наличие резервных копий и архивных файлов  на хосте, где будет создаваться дублированная база данных, нам необходимо перенести полученную копию и архивы на машину alfa2.alldba.ru, соблюдая при этом те же пути расположения файлов в файловой системе, что и на основном хосте. Для переноса будем использовать sft клиент.

Переходим на машину alfa2.alldba.ru и запускаем клиент, в котором подключаемся к хосту alfa.alldba.ru:

alfa.alldba.ru:
[oracle@alfa2 ~]$ sftp alfa.alldba.ru
Connecting to alfa.alldba.ru...
The authenticity of host 'alfa.alldba.ru (190.125.250.200)' can't be 
established.
RSA key fingerprint is 81:ab:40:5d:a3:e0:6f:7f:d8:b0:50:40:b9:fb:0e:34.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'alfa.alldba.ru,190.125.250.200' (RSA) to the list 
of known hosts.
Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.'s password:

Переходим на удалённой машине (alfa.alldba.ru) в каталог с файлом резервной копии:

sftp> cd /u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/

На локальной машине(alfa2.alldba.ru) создаём в флэш-области восстановления для резервной копии необходимые каталоги:

sftp> lmkdir /u01/app/oracle/flash_recovery_area/ORCL/backupset
sftp> lmkdir /u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/

Переходим  в созданный  каталог,проверяем одинаковость путей для резервной копии на обеих машинах и копируем файл резервной копии с alfa.alldba.ru:

sftp> lcd /u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/
sftp> pwd
Remote working directory: 
/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02
sftp> lpwd
Local working directory: 
/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02
sftp> mget *
Fetching 
/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_ncsnf_TAG2
0120302T092347_7o0t8plr_.bkp to o1_mf_ncsnf_TAG20120302T092347_7o0t8plr_.bkp
/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_ncsnf_TAG2
0120302 100% 7008KB   6.8MB/s   00:01    
Fetching 
/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_nnndf_TAG2
0120302T092347_7o0svmmk_.bkp to o1_mf_nnndf_TAG20120302T092347_7o0svmmk_.bkp
/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_nnndf_TAG2
0120302T092 100%  610MB   2.9MB/s   03:31    3

Копирование архивных журналов

Для дублирования базы данных, кроме резервной копии нам понадобятся и архивные журналы c целевой базы данных. В соответствии с настройками экземпляра они образуются в следующем каталоге:

sftp> pwd
Remote working directory: /u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02
sftp> ls -l
-rw-r-----    1 oracle   oinstall  3846144 Mar  2 09:42 o1_mf_1_16_7o0ty7cb_.arc
-rw-r-----    1 oracle   oinstall   532992 Mar  2 09:42 o1_mf_1_17_7o0tyhox_.arc
-rw-r-----    1 oracle   oinstall  5256704 Mar  2 09:42 o1_mf_1_18_7o0tz0tp_.arc

Скопируем весь каталог 2012_03_02 с машины alfa.alldba.ru на машину alfa2.alldba.ru, не забывая при этом соблюдать одинаковость путей расположения файлов:

sftp> cd /u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02
sftp> lmkdir /u01/app/oracle/flash_recovery_area/ORCL/archivelog
sftp> lmkdir /u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02
sftp> lcd /u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02
sftp> pwd
sftp> pwd
Remote working directory: 
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02
sftp> lpwd
Local working directory: 
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02
sftp> mget *
Fetching 
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_16_7o0t
y7cb_.arc to o1_mf_1_16_7o0ty7cb_.arc
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_16_7o0t
y7cb_.arc                              100% 3756KB   1.2MB/s   00:03    
Fetching 
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_17_7o0t
yhox_.arc to o1_mf_1_17_7o0tyhox_.arc
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_17_7o0t
yhox_.arc                              100%  521KB 520.5KB/s   00:01    
Fetching 
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_18_7o0t
z0tp_.arc to o1_mf_1_18_7o0tz0tp_.arc
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_18_7o0t
z0tp_.arc                              100% 5134KB   1.7MB/s   00:03
sftp> bye

Старт вспомогательного экземпляра

Непосредственно перед проведением процесса дублирования необходимо перевести экземпляры в нужные состояния. Экземпляр целевой базы данных (Target) на терминале alfa.alldba.ru должен быть обязательно открыт или смонтирован. Вспомогательный (Auxiliary) экземпляр на машине alfa2.alldba.ru должен находиться в несмонтированном режиме:

oracle@alfa2 ~]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.3.0 - Production on Fri Mar 2 05:43:26 2012 Copyright (c) 1982, 2006, Oracle. All Rights Reserved. Connected to an idle instance.
SQL> startup force nomount;
ORACLE instance started. Total System Global Area 285212672 bytes Fixed Size 1261372 bytes Variable Size 268435652 bytes Database Buffers 12582912 bytes Redo Buffers 2932736 bytes

Подключение к экземплярам

Для проведения процесса дублирования нам надо иметь два подключения, одно к экземпляру целевой базы данных, другое к вспомогательному экземпляру. Место расположения клиента RMAN, из которого будут производиться эти подключения, большого значения не имеет. Дублирование можно производить с любого клиентского хоста. Но чтобы не сильно зависеть  от состояния сетевого соединения и клиентской машины,  процесс лучше организовать  на хосте, где будет располагаться дублированная база данных. В нашем случае это будет хост alfa2.alldba.ru.

Запускаем RMAN и для начала попытаемся подключиться к целевой базе данных под пользователем system.

RMAN> connect target system/Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.;
MAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
ORA-01031: привилегий недостаточно

Возникает ошибка. Оказывается для дублирования необходимо подключение пользователя SYS или пользователя обладающего правами SYS. Последнего мы сейчас и создадим в Oracle на сервере alfa.alldba.ru:

SQL> grant connect, sysdba to duser identified by pass;
Grant succeeded.

Пробуем снова подключиться, но уже под новым  пользователем DUSER:

RMAN> connect target duser/Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.;
connected to target database: ORCL (DBID=1265664822)

Подключение успешно. Теперь мы можем соединиться с вспомогательным экземпляром (не забываем, что мы находимся на хосте вспомогательного экземпляра):

RMAN> connect auxiliary /;
connected to auxiliary database: ORCL (not mounted)

Соединение прошло успешно, и в настоящий момент времени у нас есть два подключения, резервная копия и архивные файлы журнала. Можно запускать непосредственно сам процесс дублирования.

Дублирование

Наберём в RMAN следующую команду:

RMAN> duplicate target database to orcl nofilenamecheck;

Данная команда запустит процесс дублирования целевой базы данных, в результате которого на хосте alfa2.alldba.ru будет получена новая база данных с именем orcl. Указанное в команде ключевое слово nofilenamecheck выключает проверку имён восстанавливаемых файлов. То есть, если на хосте дублированной базы данных во время процесса дублирования попадётся уже существующий файл, по тому же пути и с тем же самым именем, то  ошибка сгенерирована не будет, и файл будет заменён (не забываем, что старые файлы базы данных на хосте alfa2.alldba.ru всё ещё существуют).

Рассмотрим более подробно отчет, который выдает команда DUPLICATE.

Вначале у нас автоматически создаются каналы, по которым будет осуществляться дублирование:

Starting Duplicate Db at 02-MAR-12
using target database control file instead of recovery catalog
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: sid=156 devtype=DISK

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

contents of Memory Script:
{
   set until scn  658802;
   set newname for datafile  1 to 
 "/u02/oradata/orcl/system01.dbf";
   set newname for datafile  2 to 
 "/u02/oradata/orcl/undotbs01.dbf";
   set newname for datafile  3 to 
 "/u02/oradata/orcl/sysaux01.dbf";
   set newname for datafile  4 to 
 "/u02/oradata/orcl/users01.dbf";
   set newname for datafile  5 to 
 "/u02/oradata/orcl/example01.dbf";
   restore
   check readonly
   clone database
   ;
}

Ниже, мы видим результат выполнения такого скрипта:

executing Memory Script
executing command: SET until clause
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
executing command: SET NEWNAME
Starting restore at 02-MAR-12
using channel ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: starting datafile backupset restore
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
restoring datafile 00001 to /u02/oradata/orcl/system01.dbf
restoring datafile 00002 to /u02/oradata/orcl/undotbs01.dbf
restoring datafile 00003 to /u02/oradata/orcl/sysaux01.dbf
restoring datafile 00004 to /u02/oradata/orcl/users01.dbf
restoring datafile 00005 to /u02/oradata/orcl/example01.dbf
channel ORA_AUX_DISK_1: reading from backup piece 
/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_nnndf_TAG20120302T092
347_7o0svmmk_.bkp
channel ORA_AUX_DISK_1: restored backup piece 1
piece 
handle=/u01/app/oracle/flash_recovery_area/ORCL/backupset/2012_03_02/o1_mf_nnndf_TAG20120
302T092347_7o0svmmk_.bkp tag=TAG20120302T092347
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:46
Finished restore at 02-MAR-12

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

sql statement: CREATE CONTROLFILE REUSE SET DATABASE "ORCL" RESETLOGS ARCHIVELOG 
  MAXLOGFILES     16
  MAXLOGMEMBERS      3
  MAXDATAFILES      100
  MAXINSTANCES     8
  MAXLOGHISTORY      292
 LOGFILE
  GROUP  1 ( '/u02/oradata/orcl/redo01.log' ) SIZE 50 M  REUSE,
  GROUP  2 ( '/u02/oradata/orcl/redo02.log' ) SIZE 50 M  REUSE,
  GROUP  3 ( '/u02/oradata/orcl/redo03.log' ) SIZE 50 M  REUSE
 DATAFILE
  '/u02/oradata/orcl/system01.dbf'
 CHARACTER SET CL8ISO8859P5

После создания контрольного файла, генерируется скрипт с единственной командой. Назначение этой команды, переключить все восстановленные из резервной копии файлы данных в статус текущих:

contents of Memory Script:
{
   switch clone datafile all;
}
executing Memory Script
released channel: ORA_AUX_DISK_1
released channel: ORA_AUX_SBT_TAPE_1
datafile 2 switched to datafile copy
input datafile copy recid=1 stamp=776843437 filename=/u02/oradata/orcl/undotbs01.dbf
datafile 3 switched to datafile copy
input datafile copy recid=2 stamp=776843437 filename=/u02/oradata/orcl/sysaux01.dbf
datafile 4 switched to datafile copy
input datafile copy recid=3 stamp=776843437 filename=/u02/oradata/orcl/users01.dbf
datafile 5 switched to datafile copy
input datafile copy recid=4 stamp=776843437 filename=/u02/oradata/orcl/example01.dbf

После того как файлы переключены, производится неполное восстановление  с использованием необходимых архивных файлов.  Делает это действие специальный сгенерированный скрипт.  В самом начале  этого скрипта располагается команда,  устанавливающая серийный номер изменения (SCN).  Именно до этого SCN RMAN попытается восстановить дублированную базу данных с помощью команды recover скрипта:

contents of Memory Script:
{
   set until scn  658802;
   recover
   clone database
    delete archivelog
   ;
}

Ниже приведён результат выполнения этого скрипта:

executing Memory Script
executing command: SET until clause
Starting recover at 02-MAR-12
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: sid=155 devtype=DISK
starting media recovery
archive log thread 1 sequence 16 is already on disk as file 
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_16_7o0ty7cb_.arc
archive log thread 1 sequence 17 is already on disk as file 
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_17_7o0tyhox_.arc
archive log thread 1 sequence 18 is already on disk as file 
/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_18_7o0tz0tp_.arc
archive log 
filename=/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_16_7o0ty7
cb_.arc thread=1 sequence=16
archive log 
filename=/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_17_7o0tyh
ox_.arc thread=1 sequence=17
archive log 
filename=/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2012_03_02/o1_mf_1_18_7o0tz0
tp_.arc thread=1 sequence=18
media recovery complete, elapsed time: 00:00:02
Finished recover at 02-MAR-12

Дублированная база данных восстановлена до актуального состояния. Следующие две команды нового скрипта перезагружают вспомогательный экземпляр (auxiliary) в режим без монтирования:

contents of Memory Script:
{
   shutdown clone;
   startup clone nomount ;
}
executing Memory Script
database dismounted
Oracle instance shut down
connected to auxiliary database (not started)
Oracle instance started
Total System Global Area     285212672 bytes
Fixed Size                     1261372 bytes
Variable Size                268435652 bytes
Database Buffers              12582912 bytes
Redo Buffers                   2932736 bytes
sql statement: CREATE CONTROLFILE REUSE SET DATABASE "ORCL" RESETLOGS ARCHIVELOG 
  MAXLOGFILES     16
  MAXLOGMEMBERS      3
  MAXDATAFILES      100
  MAXINSTANCES     8
  MAXLOGHISTORY      292
 LOGFILE
  GROUP  1 ( '/u02/oradata/orcl/redo01.log' ) SIZE 50 M  REUSE,
  GROUP  2 ( '/u02/oradata/orcl/redo02.log' ) SIZE 50 M  REUSE,
  GROUP  3 ( '/u02/oradata/orcl/redo03.log' ) SIZE 50 M  REUSE
 DATAFILE
  '/u02/oradata/orcl/system01.dbf'
 CHARACTER SET CL8ISO8859P5

В отчёте мы видим команду CREATE CONTROLFILE, которая после загрузки экземпляра пересоздаёт контрольный файл, очищая тем самым его секции и устанавливая новый номер (DBID) дублированной базы данных.

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

contents of Memory Script:
{
   set newname for tempfile  1 to 
 "/u02/oradata/orcl/temp01.dbf";
   switch clone tempfile all;
   catalog clone datafilecopy  "/u02/oradata/orcl/undotbs01.dbf";
   catalog clone datafilecopy  "/u02/oradata/orcl/sysaux01.dbf";
   catalog clone datafilecopy  "/u02/oradata/orcl/users01.dbf";
   catalog clone datafilecopy  "/u02/oradata/orcl/example01.dbf";
   switch clone datafile all;
}
executing Memory Script
executing command: SET NEWNAME
renamed temporary file 1 to /u02/oradata/orcl/temp01.dbf in control file
cataloged datafile copy
datafile copy filename=/u02/oradata/orcl/undotbs01.dbf recid=1 stamp=776843459
cataloged datafile copy
datafile copy filename=/u02/oradata/orcl/sysaux01.dbf recid=2 stamp=776843459
cataloged datafile copy
datafile copy filename=/u02/oradata/orcl/users01.dbf recid=3 stamp=776843460
cataloged datafile copy
datafile copy filename=/u02/oradata/orcl/example01.dbf recid=4 stamp=776843460
datafile 2 switched to datafile copy
input datafile copy recid=1 stamp=776843459 filename=/u02/oradata/orcl/undotbs01.dbf
datafile 3 switched to datafile copy
input datafile copy recid=2 stamp=776843459 filename=/u02/oradata/orcl/sysaux01.dbf
datafile 4 switched to datafile copy
input datafile copy recid=3 stamp=776843460 filename=/u02/oradata/orcl/users01.dbf
datafile 5 switched to datafile copy
input datafile copy recid=4 stamp=776843460 filename=/u02/oradata/orcl/example01.dbf

И наконец, последний скрипт содержит всего одну команду, которая открывает полученную новую базу данных с опцией RESETLOG. Команда сбрасывает текущий SCN в единицу, архивирует незаархивированные журнальные файлы, в том числе и текущий журнал, и отбрасывает всю REDO информацию неприменённую во время восстановления. Этой же командой пересоздаются и текущие онлайн журналы:

contents of Memory Script:
{
   Alter clone database open resetlogs;
}
executing Memory Script
database opened
Finished Duplicate Db at 02-MAR-12

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

Устранение ошибок

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

Cannot re-create tempfile /u02/oradata/orcl/temp01.dbf, the same name file 
exists

Во-вторых, файлы журналов повторного выполнения создались совсем не в том  месте, которое ожидалось. Как видно из представления v$logfile, файлы журнала были размещены в флэш-области дублированной базы данных, что само по себе является временным решением:

SYSTEM@ALFA2> SELECT member FROM v$logfile;
 
MEMBER                                                                  
------------------------------------------------------------------------
/u01/app/oracle/flash_recovery_area/ORCL/onlinelog/o1_mf_3_75do5wbp_.log
/u01/app/oracle/flash_recovery_area/ORCL/onlinelog/o1_mf_2_75do5vhv_.log
/u01/app/oracle/flash_recovery_area/ORCL/onlinelog/o1_mf_1_75do5thj_.log

В чём причины этих «ошибок» и как их исправить?

Начнём с неудачной попытки пересоздания файла временного табличного пространства. Как известно, в резервную копию, которую делает RMAN на целевой базе данных, не включаются файлы временных табличных пространств и файлы оперативного журнала. Подразумевается, что они будут пересозданы во время дублирования. Местоположение файлов временного табличного пространства заносится в новый контрольный файл во время выполнения скрипта, устанавливающего новые имена  для этих файлов (команда SET NEWNAME FOR TEMPFILE). Следующая за этим команда переключения SWITCH переводит  временные файлы в статус текущих, попутно пересоздавая их. Так как файл временного табличного пространства не заменяется,  а  пересоздаётся, возникает конфликт с файлом temp01.dbf, который уже до этого находился в каталоге /u01/opt/oracle/oradata/orcl. В процессе дублирования, во время перезагрузки экземпляра, этот старый файл пытается пройти тест на принадлежность к базе данных и не проходит его, выдавая ошибку ORA-01186. Следующая за тестом попытка пересоздания файла temp01.dbf тоже терпит неудачу. Похоже, опция NOFILENAMECHECK не действует на файлы временного табличного пространства. Впрочем, вполне возможно в будущих релизах Oracle это будет исправлено.

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

alter database tempfile '/u02/oradata/orcl/temp01.dbf' drop including 
datafiles;
alter tablespace temp add tempfile '/u02/oradata/orcl/temp01.dbf' size 82m;

Можно так же удалить файл temp01.dbf,  предшествующей базы данных хоста  alfa2.alldba.ru до начала дублирования. Тогда пересоздание файла временного табличного пространства пройдёт автоматически, без ошибок, ведь физически этого файла уже не будет.

Третий  вариант  немного экзотический. Его суть состоит в использовании параметра инициализации db_file_name_convert. Хотя этот параметр используется в основном для файлов данных, когда надо переименовать имя или расположение файла в дублированной базе данных, для файлов временного табличного пространства его можно тоже использовать.  Изменяем вышеуказанный параметр. В качестве его значения перечислим  местоположение файлов временного табличного пространства в основной и дублированной базе данных. Имена у этих файлов будут разные:

SQL> alter system set db_file_name_convert='/u02/oradata/orcl/temp01.dbf',
'/u02/oradata/orcl/temp02.dbf' SCOPE=SPFILE;
System altered.

Не забывая перезагрузить экземпляр, проведем всю процедуру дублирования заново. В результате  мы видим, что образовался ещё один файл временного табличного пространства:

[oracle@alfa2 orcl]$ ls –l
…
-rw-r----- 1 oracle oinstall  85991424 Авг 26 12:56 temp01.dbf
-rw-r----- 1 oracle oinstall  85991424 Мар  2 11:08 temp02.dbf
…

В процессе дублирования произошло изменение имени файла temp01.dbf на temp02.dbf, после чего он был благополучно создан и добавлен во временное табличное пространство:

SYSTEM@ALFA2> select status, name from v$tempfile;
 
STATUS NAME                        
------ ----------------------------
ONLINE /u02/oradata/orcl/temp02.dbf

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

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

Как было сказано ранее, файлы оперативных журналов не сохраняются в резервной копии RMAN. При дублировании, в момент открытия дублированной базы данных с опцией RESETLOGS, происходит неявное создание этих журналов. При этом местоположение файлов журналов никак не соответствует их местоположению в основной базе данных и зависит от нескольких факторов. Во-первых, если установлен хотя бы один из инсталляционных параметров DB_CREATE_ONLINE_LOG_DEST_n, журнальный файл создаётся по пути указанному в этом параметре. Если значение вышеуказанного параметра не определено, то журналы создаются в каталогах указанных в параметрах DB_CREATE_FILE_DEST и DB_RECOVERY_FILE_DEST.  В нашем случае был определён именно параметр DB_RECOVERY_FILE_DEST, поэтому в процессе дублирования там и создались журнальные файлы:

SYSTEM@ALFA2> show parameters db_recovery_file_dest

Параметр Тип Значение -------------------------- ------- ------------------------------------ db_recovery_file_dest string /u01/app/oracle/flash_recovery_area/

Как сделать так, чтобы журнальные файлы  дублированной базы данных располагались и имели имена, так же как и на основной? Можно конечно удалить журналы после окончания дублирования, а затем снова создать их уже в нужных каталогах,  но это далеко не самый простой путь, здесь есть свои сложности. Наиболее оптимальным в нашем случае будет использование параметра log_file_name_convert. Этот параметр специально предназначен для преобразования местоположения журнала при дублировании. Если мы укажем в качестве его значения каталоги, где будут находиться оперативные журналы баз, то при дублировании журналы будут созданы в дублированной базе данных по указанным путям.  Например, изменим в нашем примере значение инициализационного параметра log_file_name_convert, указав следующие каталоги:

SQL> alter system set 
log_file_name_convert='/u02/oradata/orcl/','/u02/oradata/orcl/' SCOPE=SPFILE;
System altered.

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

Подведение итогов

Настало время подвести некоторые итоги и коротко определить основные действия, которые необходимо сделать для осуществления базового дублирования:

  • Создание в RMAN резервной копии целевой базы данных.
  • Копирование резервной копии и необходимых архивных журнальных файлов с хоста целевой базы данных на хост вспомогательного экземпляра.
  • Установка значения параметра log_file_name_convert во вспомогательном экземпляре;
  • Старт вспомогательного экземпляра в несмонтированном режиме.
  • Запуск RMAN на хосте вспомогательного экземпляра.
  • Подключение из RMAN к экземпляру целевой базы данных и вспомогательному экземпляру.
  • Запуск из RMAN процесса дублирования целевой базы данных.
  • Удаление и создание файла временного табличного пространства в дублированной базе данных.

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