Резервное копирование баз данных Oracle - современный подход

THE HOLY BIBLE - King James Version - БИБЛИЯ в Синодальном переводе
"Нас Атакуют!" Изобличи козни лукавого, запрети диаволу

Резервное копирование баз данных Oracle - современный подход

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

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

Прежде чем мы продолжим, я хотел бы привести строки из Евангелия:



................... == От Луки святое благовествование == ......................
=== Глава 11, Стих 4 ===
2 Он сказал им: когда молитесь, говорите: Отче наш, сущий на небесах! да
 святится имя Твое; да приидет Царствие Твое; да будет воля Твоя и на земле,
 как на небе;
3 хлеб наш насущный подавай нам на каждый день;
4 и прости нам грехи наши, ибо и мы прощаем всякому должнику нашему; и не
 введи нас в искушение, но избавь нас от лукавого.

Лично для вас благая весть - Единородный Сын Божий Иисус Христос любит вас, Он взошел на крест за ваши грехи, был распят и на третий день воскрес, сел одесную Бога и открыл нам дорогу в Царствие Небесное.

"не введи нас в искушение, но избавь нас от лукавого" - как важны эти простые слова для нас, грешников! Сатана бродит вокруг нас, как рыкающий лев, и имя Иисуса Христа - единственное имя, которым мы можем защититься от нападок врага. Каждый из нас искушаем. Диавол прибегает к разнообразным уловкам и тщательно маскирует их как наши собственные желания, стремления, мечты. Все самое ценное и чистое, что есть в жизни каждого из нас - все это подвергается бесовским атакам. Как просто потеряться во всех сложностях бытия! Святое Евангелие - наш единственный ориентир на жизненном пути, а имя Иисуса Христа - свет на нашей стезе. Только Бог может помочь нам бороться с диаволом, только во Христе наше спасение. В каких тяжелых обстоятельствах вы бы ни находились - ищите прощение в Боге, защиту и спасение в Иисусе Христе и вдохновение на борьбу в Духе Святом - и Они не оставят вас.

Покайтесь, примите Иисуса как вашего Спасителя, ибо наступают последние времена и время близко - стоит Судья у ворот. Поверьте, это не пустая метафора - включите телевизор, посмотрите новости. Прочтите в Библии описания последних времен. Подумайте - и вы со страхом увидите прочитанное библейское описание сходящим на вас ежедневной реальностью с "голубых экранов" и со страниц газет. Христиане всего мира провозглашают об этом. Во всех церквях всех христианских деноминаций всего мира на проповеди вы услышите эти слова: "Покайтесь! Приблизилось Царствие Небесное. Приготовься каждый к Страшному Суду!"

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

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


Вернемся к нашим техническим деталям.

Я предполагаю что уважаемый читатель владеет необходимыми знаниями и навыками использования Linux и Oracle, поэтому я буду очень краток. Цель этой заметки изложить подход к резервному копированию баз данных, являющийся на мой взгляд современным и простым. Данный подход применим ко всем комплектациям (editions) Оракла и будет работать во всех версиях, начиная с 10g.

Я также предполагаю, что в наличии имеется правильно установленный и работающий Oracle Express Edition, с существующей базой с именем XE. В моей статье я использую Oracle Unbreakable Linux 6.1 с ядром Oracle Unbreakable Enterprise Kernel как операционную систему.

Мы рассмотрим два варианта резервного копирования:

  • Простейший способ - сжатая копия (compressed backupset)
  • Эффективный способ - полная копия (RMAN-created image copy)
  • Естественно, каждый вариант имеет достоинства и недостатки, о которых я скажу ниже. Все действия будут выполнены исключительно из командной строки и не будут требовать графического интерфейса.

    Простейший способ - сжатая копия (compressed backupset)

    Достоинства - минимальное место на диске, простота, не требуется архивирование online логов базы данных.

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

    Проверим какие версии продуктов установлены в нашей системе.

    ......... == Второе послание к Коринфянам святого апостола Павла == ............
    === Глава 5, Стих 14 ===
    14 Ибо любовь Христова  объемлет  нас,  рассуждающих  так:  если  один  умер  за
    всех, то все умерли.
    15 А Христос за  всех  умер,  чтобы  живущие  уже  не  для  себя  жили,  но  для
    умершего за них и воскресшего.
    16 Потому отныне мы никого не  знаем  по  плоти;  если  же  и  знали  Христа  по
    плоти, то ныне уже не знаем.
    17 Итак, кто во Христе, _тот_ новая тварь;  древнее  прошло,  теперь  все новое.
    18 Все же от Бога, Иисусом Христом  примирившего  нас  с  Собою  и  давшего  нам
    служение примирения,
    19 потому  что  Бог  во  Христе  примирил  с  Собою  мир,  не   вменяя   _людям_
    преступлений их, и дал нам слово примирения.
    20 Итак мы -- посланники от имени Христова, и как бы  Сам  Бог  увещевает  через
    нас; от имени Христова просим: примиритесь с Богом.
    
    (b+/b-, c+/c-, +/-, *) >
    
    [oracle@OUL6 ~]$ id -a
    uid=500(oracle) gid=500(dba) groups=500(dba) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    [oracle@OUL6 ~]$ uname -a
    Linux OUL6.domain1 2.6.32-100.34.1.el6uek.i686 #1 SMP Wed May 25 17:28:36 GMT 2011 i686 i686 i386 GNU/Linux
    [oracle@OUL6 ~]$ free -m
    total       used       free     shared    buffers     cached
    Mem:           497        484         13          0         18        387
    -/+ buffers/cache:         77        419
    Swap:         1023          0       1023
    [oracle@OUL6 ~]$ ps -ef | grep xe
    oracle     934     1  0 12:23 ?        00:00:00 /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/tnslsnr
    oracle    1703     1  0 13:26 ?        00:00:00 xe_pmon_XE
    oracle    1705     1  0 13:26 ?        00:00:00 xe_psp0_XE
    oracle    1707     1  0 13:26 ?        00:00:00 xe_mman_XE
    oracle    1709     1  0 13:26 ?        00:00:00 xe_dbw0_XE
    oracle    1711     1  0 13:26 ?        00:00:00 xe_lgwr_XE
    oracle    1713     1  0 13:26 ?        00:00:01 xe_ckpt_XE
    oracle    1715     1  0 13:26 ?        00:00:01 xe_smon_XE
    oracle    1717     1  0 13:26 ?        00:00:00 xe_reco_XE
    oracle    1719     1  0 13:26 ?        00:00:01 xe_cjq0_XE
    oracle    1721     1  0 13:26 ?        00:00:02 xe_mmon_XE
    oracle    1723     1  0 13:26 ?        00:00:02 xe_mmnl_XE
    oracle    1731     1  0 13:27 ?        00:00:00 xe_qmnc_XE
    oracle    1739     1  0 13:27 ?        00:00:00 xe_q000_XE
    oracle    1741     1  0 13:27 ?        00:00:00 xe_q001_XE
    oracle    1809  1051  0 13:48 pts/0    00:00:00 grep xe
    [oracle@OUL6 ~]$ sqlplus
    SQL*Plus: Release 10.2.0.1.0 - Production on Sat Aug 27 13:49:24 2011
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    Enter user-name: / as sysdba
    Connected to:
    Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
    Elapsed: 00:00:00.03
    13:50:32 SQL> Disconnected from Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
    

    Как видно, система имеет весьма ограниченные ресурсы - пол-гигабайта памяти, всего один 32-битный процессор и 8 гигабайт дискового пространства. Очевидно, что система с подобными характеристиками может быть легко размещена на VPS хостинге, что делает возможным использование Oracle Express как базы данных для web-приложений.

    Заметьте, что я не использую диспетчеры и виртуальные серверы (shared server architecture) для пользовательских подключений - к сожалению, Оракл Экспресс имеет ошибки в коде процесса "D00", вызывающие периодическое потребление этим процессом всех доступных ресурсов процессора.

    Создадим сжатую резервную копию базы данных

    Самый простой способ бэкапа данных - использование Oracle Recovery Manager (RMAN) для копирования данных из существующих дата файлов в сжатый бэкап файл.

    ........... == Первое соборное послание святого апостола Петра == ..............
    === Глава 3, Стих 10 ===
    10 Ибо, кто любит жизнь и хочет видеть  добрые  дни,  тот  удерживай  язык  свой
    от зла и уста свои от лукавых речей;
    11 уклоняйся  от  зла  и  делай   добро;   ищи   мира   и   стремись   к   нему,
    12 потому что очи Господа _обращены_ к праведным и уши  Его  к  молитве  их,  но
    лице Господне против делающих зло, (чтобы истребить их с земли).
    
    (b+/b-, c+/c-, +/-, *) >
    
    [oracle@OUL6 ~]$ rman
    Recovery Manager: Release 10.2.0.1.0 - Production on Sat Aug 27 13:50:40 2011
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    RMAN> connect target
    connected to target database: XE (DBID=2637837781)
    
    RMAN> shutdown
    using target database control file instead of recovery catalog
    database closed
    database dismounted
    Oracle instance shut down
    
    RMAN> startup mount
    connected to target database (not started)
    Oracle instance started
    database mounted
    
    Total System Global Area     188743680 bytes
    Fixed Size                     1257932 bytes
    Variable Size                109055540 bytes
    Database Buffers              75497472 bytes
    Redo Buffers                   2932736 bytes
    
    RMAN> report schema;
    Report of database schema
    
    List of Permanent Datafiles
    ===========================
    File Size(MB) Tablespace           RB segs Datafile Name
    ---- -------- -------------------- ------- ------------------------
    1    340      SYSTEM               ***     /usr/lib/oracle/xe/oradata/XE/system.dbf
    2    175      UNDO                 ***     /usr/lib/oracle/xe/oradata/XE/undo.dbf
    3    440      SYSAUX               ***     /usr/lib/oracle/xe/oradata/XE/sysaux.dbf
    4    4330     USERS                ***     /usr/lib/oracle/xe/oradata/XE/users.dbf
    
    RMAN> list backup;
    
    RMAN> list copy;
    specification does not match any archive log in the recovery catalog
    
    RMAN> backup as compressed backupset database
    format='/tmp/offline_backup1_%U.bckp';		-- Также можно указать %F
    
    Starting backup at 27-AUG-11
    allocated channel: ORA_DISK_1
    channel ORA_DISK_1: sid=1092 devtype=DISK
    channel ORA_DISK_1: starting compressed full datafile backupset
    channel ORA_DISK_1: specifying datafile(s) in backupset
    input datafile fno=00004 name=/usr/lib/oracle/xe/oradata/XE/users.dbf
    input datafile fno=00003 name=/usr/lib/oracle/xe/oradata/XE/sysaux.dbf
    input datafile fno=00001 name=/usr/lib/oracle/xe/oradata/XE/system.dbf
    input datafile fno=00002 name=/usr/lib/oracle/xe/oradata/XE/undo.dbf
    channel ORA_DISK_1: starting piece 1 at 27-AUG-11
    channel ORA_DISK_1: finished piece 1 at 27-AUG-11
    piece handle=/tmp/offline_backup1_01ml20i7_1_1.bckp tag=TAG20110827T135519 comment=NONE
    channel ORA_DISK_1: backup set complete, elapsed time: 00:04:55
    channel ORA_DISK_1: starting compressed 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 27-AUG-11
    channel ORA_DISK_1: finished piece 1 at 27-AUG-11
    piece handle=/tmp/offline_backup1_02ml20rf_1_1.bckp tag=TAG20110827T135519 comment=NONE
    channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02
    Finished backup at 27-AUG-11
    
    RMAN> list backup;
    List of Backup Sets
    ===================
    
    BS Key  Type LV Size       Device Type Elapsed Time Completion Time
    ------- ---- -- ---------- ----------- ------------ ---------------
    1       Full    242.44M    DISK        00:04:55     27-AUG-11
    BP Key: 1   Status: AVAILABLE  Compressed: YES  Tag: TAG20110827T135519
    Piece Name: /tmp/offline_backup1_01ml20i7_1_1.bckp
    List of Datafiles in backup set 1
    File LV Type Ckp SCN    Ckp Time  Name
    ---- -- ---- ---------- --------- ----
    1       Full 722312     27-AUG-11 /usr/lib/oracle/xe/oradata/XE/system.dbf
    2       Full 722312     27-AUG-11 /usr/lib/oracle/xe/oradata/XE/undo.dbf
    3       Full 722312     27-AUG-11 /usr/lib/oracle/xe/oradata/XE/sysaux.dbf
    4       Full 722312     27-AUG-11 /usr/lib/oracle/xe/oradata/XE/users.dbf
    
    BS Key  Type LV Size       Device Type Elapsed Time Completion Time
    ------- ---- -- ---------- ----------- ------------ ---------------
    2       Full    1.03M      DISK        00:00:02     27-AUG-11
    BP Key: 2   Status: AVAILABLE  Compressed: YES  Tag: TAG20110827T135519
    Piece Name: /tmp/offline_backup1_02ml20rf_1_1.bckp
    Control File Included: Ckp SCN: 722312       Ckp time: 27-AUG-11
    SPFILE Included: Modification time: 27-AUG-11
    
    RMAN> list copy;
    specification does not match any archive log in the recovery catalog
    

    Обратите внимание, что я остановил базу и затем смонтировал ее, не открывая. Без перевода базы данных в archivelog режим это единственный вариант. Резервная копия была сжата - посмотрите на вывод команды "list backup", там имеется запись: "Compressed: YES". Tablespace "TEMP" не включается в резервную копию - в большинстве случаев временные файлы надо добавлять туда вручную после восстановления.

    Обратите внимание на соответствие SCN в обоих Backup Sets: 722312. Это означает, что control file синхронизирован с файлами данных и база может быть восстановлена из этого бэкапа без дополнительных действий.

    В Backup Set #2 включены бинарные копии файла параметров и control file. Этого может быть достаточно в большинстве случаев, но мы сделаем еще одну резервную копию control файла в текстовом виде:

    .................. == От Матфея святое благовествование == .....................
    === Глава 26, Стих 12 ===
    10 Но Иисус, уразумев сие, сказал им: что  смущаете  женщину?  она  доброе  дело
    сделала для Меня:
    11 ибо   нищих   всегда   имеете   с   собою,   а   Меня   не   всегда   имеете;
    12 возлив  миро  сие  на  тело  Мое,  она   приготовила   Меня   к   погребению;
    13 истинно говорю вам: где ни будет проповедано  Евангелие  сие  в  целом  мире,
    сказано будет в память ее и о том, что она сделала.
    
    (b+/b-, c+/c-, +/-, *) >
    
    [oracle@OUL6 ~]$ sqlplus
    SQL*Plus: Release 10.2.0.1.0 - Production on Sat Aug 27 14:10:27 2011
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    Enter user-name: / as sysdba
    
    Connected to:
    Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
    
    Elapsed: 00:00:00.03
    14:10:30 SQL> alter database backup controlfile to trace;
    
    Database altered.
    
    Elapsed: 00:00:00.03
    14:10:41 SQL> create pfile='/tmp/init.ora.bckp' from spfile;
    
    File created.
    
    Elapsed: 00:00:00.03
    
    14:10:44 SQL> Disconnected from Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
    
    [oracle@OUL6 ~]$ ls -latrh /usr/lib/oracle/xe/app/oracle/admin/XE/udump/| tail -2
    drwxr-xr-x. 2 oracle dba  12K Aug 27 14:10 .
    -rw-r-----. 1 oracle dba 5.5K Aug 27 14:10 xe_ora_1874.trc
    [oracle@OUL6 ~]$ cp /usr/lib/oracle/xe/app/oracle/admin/XE/udump/xe_ora_1874.trc /tmp/crtctl.sql
    [oracle@OUL6 ~]$ grep "CREATE CONTROLFILE" /tmp/crtctl.sql
    CREATE CONTROLFILE REUSE DATABASE "XE" NORESETLOGS  NOARCHIVELOG
    CREATE CONTROLFILE REUSE DATABASE "XE" RESETLOGS  NOARCHIVELOG
    [oracle@OUL6 ~]$
    

    Как видно, текстовый файл содержит инструкции для создания control file "с нуля" - они могут пригодиться для восстановления базы данных в нестандартном случае. Также нам может очень пригодиться текстовая копия файла инициализационных параметров "/tmp/init.ora.bckp". В дополнение, необходимо хранить под рукой (вероятно, в виде RMAN лог файла) значение DBID. Наиболее удобный способ это использовать format specifiers %F или %I - я использовал только %U.

    Протестируем процесс востановления базы

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

    [oracle@OUL6 ~]$ ls /usr/lib/oracle/xe/oradata/XE/
    control.dbf  onlineloga.log  onlinelogb.log  sysaux.dbf  system.dbf  temp.dbf  undo.dbf  users.dbf
    [oracle@OUL6 ~]$
    [oracle@OUL6 ~]$ rm -f /usr/lib/oracle/xe/oradata/XE/*
    [oracle@OUL6 ~]$ ls /usr/lib/oracle/xe/oradata/XE/
    ...
    14:28:54 SQL> select open_mode from v$database;
    select open_mode from v$database
    *
    ERROR at line 1:
    ORA-00210: cannot open the specified control file
    ORA-00202: control file: '/usr/lib/oracle/xe/oradata/XE/control.dbf'
    ORA-27041: unable to open file
    Linux Error: 2: No such file or directory
    Additional information: 3
    
    Elapsed: 00:00:00.03
    14:29:06 SQL> alter system checkpoint;
    alter system checkpoint
    *
    ERROR at line 1:
    ORA-01109: database not open
    
    Elapsed: 00:00:00.02
    14:29:16 SQL>
    

    Ужасное случилось - наша база данных безвозвратно потеряна! Вернем ее к жизни:

    .................. == От Иоанна святое благовествование == .....................
    === Глава 14, Стих 12 ===
    12 Истинно, истинно говорю вам: верующий в Меня, дела, которые  творю  Я,  и  он
    сотворит, и больше сих сотворит, потому что Я к Отцу Моему иду.
    
    (b+/b-, c+/c-, +/-, *) >
    
    [oracle@OUL6 ~]$ rman
    Recovery Manager: Release 10.2.0.1.0 - Production on Sat Aug 27 14:57:11 2011
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    RMAN> connect target
    connected to target database (not started)
    
    RMAN> startup nomount
    Oracle instance started
    
    Total System Global Area     188743680 bytes
    Fixed Size                     1257932 bytes
    Variable Size                109055540 bytes
    Database Buffers              75497472 bytes
    Redo Buffers                   2932736 bytes
    
    RMAN> set DBID=2637837781;
    executing command: SET DBID
    
    RMAN> restore controlfile from '/tmp/offline_backup1_02ml20rf_1_1.bckp';
    
    Starting restore at 27-AUG-11
    using channel ORA_DISK_1
    
    channel ORA_DISK_1: restoring control file
    channel ORA_DISK_1: restore complete, elapsed time: 00:00:03
    output filename=/usr/lib/oracle/xe/oradata/XE/control.dbf
    Finished restore at 27-AUG-11
    
    RMAN> sql 'alter database mount';
    
    using target database control file instead of recovery catalog
    sql statement: alter database mount
    
    RMAN> restore database;
    
    Starting restore at 27-AUG-11
    using channel ORA_DISK_1
    
    channel ORA_DISK_1: starting datafile backupset restore
    channel ORA_DISK_1: specifying datafile(s) to restore from backup set
    restoring datafile 00001 to /usr/lib/oracle/xe/oradata/XE/system.dbf
    restoring datafile 00002 to /usr/lib/oracle/xe/oradata/XE/undo.dbf
    restoring datafile 00003 to /usr/lib/oracle/xe/oradata/XE/sysaux.dbf
    restoring datafile 00004 to /usr/lib/oracle/xe/oradata/XE/users.dbf
    channel ORA_DISK_1: reading from backup piece /tmp/offline_backup1_01ml20i7_1_1.bckp
    channel ORA_DISK_1: restored backup piece 1
    piece handle=/tmp/offline_backup1_01ml20i7_1_1.bckp tag=TAG20110827T135519
    channel ORA_DISK_1: restore complete, elapsed time: 00:04:17
    Finished restore at 27-AUG-11
    
    RMAN> sql 'alter database open resetlogs';
    
    sql statement: alter database open resetlogs
    
    RMAN>
    Recovery Manager complete.
    [oracle@OUL6 ~]$ sqlplus
    SQL*Plus: Release 10.2.0.1.0 - Production on Sat Aug 27 15:28:25 2011
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    Enter user-name: / as sysdba
    
    Connected to:
    Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
    Elapsed: 00:00:00.05
    15:28:28 SQL> select open_mode from v$database;
    
    OPEN_MODE
    ----------
    READ WRITE
    
    1 row selected.
    
    Elapsed: 00:00:00.12
    15:28:36 SQL> select logins from v$instance;
    
    LOGINS
    ----------
    ALLOWED
    
    1 row selected.
    
    Elapsed: 00:00:00.01
    15:28:45 SQL>
    

    Теперь понятно, почему так важно хранить значение DBID - без него восстановление control file из бинарной копии становится нетривиальной задачей. Если все-таки значение DBID утеряно, можно воспользоваться тесктовой копией (в нашем случае "/tmp/crtctl.sql") и создать control file заново.

    Как видим, база может быть открыта (с переформатированием online логов) непосредственно после восстановления из бэкапа - шаг "recovery" не нужен. Тем не менее, мы были вынуждены ждать почти пять минут, пока данные физически копировались из бэкапа (файл "/tmp/offline_backup1_01ml20i7_1_1.bckp") во вновь созданные файлы данных в каталоге "/usr/lib/oracle/xe/oradata/XE". Во многих случаях такое ожидание (пропорциональное размеру базы данных) неприемлемо.

    Эффективный способ - полная копия (RMAN-created image copy)

    Достоинства - минимально возможное время восстановления работоспособности базы данных. Базу можно "вернуть назад" во времени без использования flashback logs (и связанных с ними потерями производительности). Также база может быть "продвинута вперед" с использованием архивных лог файлов. Резервное копирование может происходить в "горячем режиме".

    Недостатки - неэффективно используется дисковое пространство, база данных обязательно должна быть переведена в archivelog режим.

    Использование полных копий ("image copies") при резервном копировании полностью устраняет необходимость последующего копирования данных из бэкапа обратно в дата файлы - таким образом, наиболее длительный по времени этап "restore" исключается из процесса восстановления базы.

    Наша база уже переведена в archivelog режим, создадим таблицу с тестовой записью:

    ............ == Послание к Колоссянам святого апостола Павла == ................
    === Глава 3, Стих 8 ===
    8 А теперь вы отложите все: гнев, ярость,  злобу,  злоречие,  сквернословие  уст
    ваших;
    9 не  говорите  лжи  друг  другу,  совлекшись  ветхого  человека  с  делами  его
    10 и облекшись в нового, который обновляется в  познании  по  образу  Создавшего
    его,
    11 где нет ни Еллина, ни Иудея, ни обрезания, ни  необрезания,  варвара,  Скифа,
    раба, свободного, но все и во всем Христос.
    
    (b+/b-, c+/c-, +/-, *) >
    
    [oracle@OUL6 ~]$ sqlplus
    SQL*Plus: Release 10.2.0.1.0 - Production on Sat Aug 27 13:49:24 2011
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    Enter user-name: / as sysdba
    Connected to:
    Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
    15:54:58 SQL> archive log list
    Database log mode              Archive Mode
    Automatic archival             Enabled
    Archive destination            USE_DB_RECOVERY_FILE_DEST
    Oldest online log sequence     1
    Next log sequence to archive   2
    Current log sequence           2
    15:55:11 SQL>  create table t1 (dt timestamp, msg varchar2(400))
    
    Table created.
    
    Elapsed: 00:00:00.34
    
    16:01:55 SQL> insert into t1 values (systimestamp, 'Test 1 - initial row');
    
    1 row created.
    
    Elapsed: 00:00:00.02
    16:02:14 SQL> commit;
    
    Commit complete.
    
    Elapsed: 00:00:00.04
    16:02:16 SQL>
    
    16:03:52 SQL> select * from t1;
    
    DT                                                                          MSG
    --------------------------------------------------------------------------- -------------------------
    27-AUG-11 04.02.14.374409 PM                                                Test 1 - initial row
    
    1 row selected.
    
    Elapsed: 00:00:00.02
    16:03:56 SQL>
    

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

    ......................... == Книга пророка Ионы == .............................
    === Глава 3, Стих 10 ===
    10 И увидел Бог дела их, что они обратились от  злого  пути  своего,  и  пожалел
    Бог о бедствии, о котором сказал, что наведет на них, и не навел.
    
    (b+/b-, c+/c-, +/-, *) >
    
    [oracle@OUL6 ~]$ rman
    
    Recovery Manager: Release 10.2.0.1.0 - Production on Sat Aug 27 16:09:29 2011
    
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    RMAN> connect target
    
    connected to target database: XE (DBID=2637837781)
    
    RMAN> shutdown immediate
    
    using target database control file instead of recovery catalog
    database closed
    database dismounted
    Oracle instance shut down
    
    RMAN> startup mount
    
    connected to target database (not started)
    Oracle instance started
    database mounted
    
    Total System Global Area     188743680 bytes
    
    Fixed Size                     1257932 bytes
    Variable Size                109055540 bytes
    Database Buffers              75497472 bytes
    Redo Buffers                   2932736 bytes
    
    RMAN>
    RMAN> backup as copy database format='/tmp/snapshot1_%U.dbf';
    
    Starting backup at 27-AUG-11
    allocated channel: ORA_DISK_1
    channel ORA_DISK_1: sid=1092 devtype=DISK
    channel ORA_DISK_1: starting datafile copy
    input datafile fno=00004 name=/usr/lib/oracle/xe/oradata/XE/users.dbf
    output filename=/tmp/snapshot1_data_D-XE_I-2637837781_TS-USERS_FNO-4_04ml28iu.dbf
    tag=TAG20110827T161213 recid=5 stamp=760292171
    channel ORA_DISK_1: datafile copy complete, elapsed time: 00:04:05
    channel ORA_DISK_1: starting datafile copy
    input datafile fno=00003 name=/usr/lib/oracle/xe/oradata/XE/sysaux.dbf
    output filename=/tmp/snapshot1_data_D-XE_I-2637837781_TS-SYSAUX_FNO-3_05ml28qj.dbf
    tag=TAG20110827T161213 recid=6 stamp=760292205
    channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:35
    channel ORA_DISK_1: starting datafile copy
    input datafile fno=00001 name=/usr/lib/oracle/xe/oradata/XE/system.dbf
    output filename=/tmp/snapshot1_data_D-XE_I-2637837781_TS-SYSTEM_FNO-1_06ml28rn.dbf
    tag=TAG20110827T161213 recid=7 stamp=760292235
    channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:25
    channel ORA_DISK_1: starting datafile copy
    input datafile fno=00002 name=/usr/lib/oracle/xe/oradata/XE/undo.dbf
    output filename=/tmp/snapshot1_data_D-XE_I-2637837781_TS-UNDO_FNO-2_07ml28sg.dbf
    tag=TAG20110827T161213 recid=8 stamp=760292250
    channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:15
    channel ORA_DISK_1: starting datafile copy
    copying current control file
    output filename=/tmp/snapshot1_cf_D-XE_id-2637837781_08ml28sv.dbf
    tag=TAG20110827T161213 recid=9 stamp=760292256
    channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:02
    channel ORA_DISK_1: starting full datafile backupset
    channel ORA_DISK_1: specifying datafile(s) in backupset
    including current SPFILE in backupset
    channel ORA_DISK_1: starting piece 1 at 27-AUG-11
    channel ORA_DISK_1: finished piece 1 at 27-AUG-11
    piece handle=/tmp/snapshot1_09ml28t1_1_1.dbf tag=TAG20110827T161213 comment=NONE
    channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
    Finished backup at 27-AUG-11
    

    Ключевое отличие - в команде "backup as copy". Естественно, ни о каком сжатии резервных копий разговор не идет - бэкап будет иметь полный размер исходной базы, представляя ее "образ" ("snapshot"). Я решил остановить базу и перемонтировать ее без открытия, как было сделано в первом сценарии. Такой подход позволит мне получить "синхронизированные" копии файлов базы данных и сократить ( а возможно и исключить) этап "recover" при восстановлении базы данных после сбоя. С таким же успехом можно сделать "горячие" копии файлов с данными - но в таком случае команда "recover" становится необходимостью. Это означает, что будет необходимо хранить соответствующее количество archive logs.

    Просмотрим результаты нашего копирования и откроем базу для пользователей:

    ................................ == Исход == ...................................
    === Глава 20, Стих 2 ===
    2 Я Господь,  Бог  твой,  Который  вывел  тебя  из  земли  Египетской,  из  дома
    рабства;
    3 да    не    будет    у    тебя    других    богов    пред    лицем       Моим.
    
    (b+/b-, c+/c-, +/-, *) >
    
    [oracle@OUL6 ~]$ rman
    
    Recovery Manager: Release 10.2.0.1.0 - Production on Sat Aug 27 16:09:29 2011
    
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    
    RMAN> list backup;
    
    List of Backup Sets
    ===================
    
    BS Key  Type LV Size       Device Type Elapsed Time Completion Time
    ------- ---- -- ---------- ----------- ------------ ---------------
    2       Full    80.00K     DISK        00:00:00     27-AUG-11
    BP Key: 2   Status: AVAILABLE  Compressed: NO  Tag: TAG20110827T161213
    Piece Name: /tmp/snapshot1_09ml28t1_1_1.dbf
    SPFILE Included: Modification time: 27-AUG-11
    
    RMAN> list copy;
    
    specification does not match any archive log in the recovery catalog
    
    List of Datafile Copies
    Key  File S Completion  Ckp SCN Ckp Time  Name
    ---- ---- - ----------- ------- --------- ----
    7    1    A 27-AUG-11   724041  27-AUG-11 /tmp/snapshot1_data_D-XE_I-2637837781_TS-SYSTEM_FNO-1_06ml28rn.dbf
    8    2    A 27-AUG-11   724041  27-AUG-11 /tmp/snapshot1_data_D-XE_I-2637837781_TS-UNDO_FNO-2_07ml28sg.dbf
    6    3    A 27-AUG-11   724041  27-AUG-11 /tmp/snapshot1_data_D-XE_I-2637837781_TS-SYSAUX_FNO-3_05ml28qj.dbf
    5    4    A 27-AUG-11   724041  27-AUG-11 /tmp/snapshot1_data_D-XE_I-2637837781_TS-USERS_FNO-4_04ml28iu.dbf
    
    List of Control File Copies
    Key     S Completion Time Ckp SCN    Ckp Time        Name
    ------- - --------------- ---------- --------------- ----
    9       A 27-AUG-11       724041     27-AUG-11       /tmp/snapshot1_cf_D-XE_id-2637837781_08ml28sv.dbf
    
    RMAN>
    
    
    RMAN> startup
    
    database is already started
    database opened
    
    RMAN>
    

    Заметьте, что файлы с данными показаны как копии, а не как "Backup Sets". Также заметьте соответствие SCN файлов данных и control file - 724041. В этом случае этап "recover" не требуется (также как и "restore") и база может быть открыта (с опцией "resetlogs") немедленно после "восстановления". Значение DBID (2637837781) включается в имя файла-копии по умолчанию.

    Добавим новые записи в таблицу

    Как только мы "откроем" базу, пользователи начнут добавлять и изменять данные, так что наша копия останется "в прошлом" времени, соответствующему SCN 724041 и имеющему только одну запись в таблице "T1". Я также переключу лог файлы несколько раз.

    16:19:26 SQL> archive log list;
    Database log mode	       Archive Mode
    Automatic archival	       Enabled
    Archive destination	       USE_DB_RECOVERY_FILE_DEST
    Oldest online log sequence     1
    Next log sequence to archive   2
    Current log sequence	       2
    16:19:36 SQL> alter system switch logfile;
    
    System altered.
    
    Elapsed: 00:00:00.36
    16:20:05 SQL> /
    
    System altered.
    
    Elapsed: 00:00:05.15
    16:20:11 SQL> /
    
    System altered.
    
    Elapsed: 00:00:00.45
    16:20:13 SQL> archive log list;
    Database log mode	       Archive Mode
    Automatic archival	       Enabled
    Archive destination	       USE_DB_RECOVERY_FILE_DEST
    Oldest online log sequence     4
    Next log sequence to archive   5
    Current log sequence	       5
    16:20:19 SQL>
    
    16:20:19 SQL> insert into t1 values (systimestamp, 'Test 2 - after image copy backup');
    
    1 row created.
    
    Elapsed: 00:00:00.12
    16:21:05 SQL> commit;
    
    Commit complete.
    
    Elapsed: 00:00:00.06
    16:21:07 SQL>
    16:22:21 SQL> select * from t1;
    
    DT					      MSG
    --------------------------------------------- ---------------------------------------------
    27-AUG-11 04.02.14.374409 PM		      Test 1 - initial row
    27-AUG-11 04.21.05.364685 PM		      Test 2 - after image copy backup
    
    2 rows selected.
    
    Elapsed: 00:00:00.01
    16:22:22 SQL>
    
    
    16:22:47 SQL> select NAME, SEQUENCE#, FIRST_CHANGE#, NEXT_CHANGE#
    16:23:15   2  from v$archived_log;
    
    NAME
    --------------------------------------------------------------------------------------------------
    SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
    ---------- ------------- ------------
    /usr/lib/oracle/xe/app/oracle/flash_recovery_area/XE/archivelog/2011_08_27/o1_mf_1_2_75k34ojl_.arc
    2	  723332       724147
    
    /usr/lib/oracle/xe/app/oracle/flash_recovery_area/XE/archivelog/2011_08_27/o1_mf_1_3_75k34vys_.arc
    3	  724147       724151
    
    /usr/lib/oracle/xe/app/oracle/flash_recovery_area/XE/archivelog/2011_08_27/o1_mf_1_4_75k34x4q_.arc
    4	  724151       724153
    
    
    4 rows selected.
    
    Elapsed: 00:00:00.03
    16:23:21 SQL>
    
    16:24:17 SQL> select FILE#, TABLESPACE_NAME, CHECKPOINT_CHANGE#
    16:24:29   2  from v$datafile_header;
    
    FILE# TABLESPACE_NAME		  CHECKPOINT_CHANGE#
    ---------- ------------------------------ ------------------
    1 SYSTEM				      724153
    2 UNDO 				      724153
    3 SYSAUX				      724153
    4 USERS				      724153
    
    4 rows selected.
    
    Elapsed: 00:00:00.03
    16:24:36 SQL>
    

    Быстрое восстановление работоспособности базы данных

    После добавления записи и переключения логов, наша база продвинулась до SCN 724153. Предположим, что где-то после SCN 724041 в таблицах базы были сделаны множественные ошибочные изменения и потеряны файлы данных. Нам необходимо восстановить работу базы и вернуть ее к "безошибочному" состоянию (т.е. к SCN 724041).

    ....................... == Книга пророка Аввакума == ...........................
    === Глава 2, Стих 4 ===
    4 Вот, душа  надменная  не  успокоится,  а  праведный  своею  верою  жив  будет.
    
    (b+/b-, c+/c-, +/-, *) >
    
    [oracle@OUL6 ~]$ rman
    -- Восстановим базу из "образа" ("snapshot")
    
    Recovery Manager: Release 10.2.0.1.0 - Production on Sat Aug 27 16:25:35 2011
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    RMAN> connect target
    connected to target database: XE (DBID=2637837781)
    
    RMAN> shutdown immediate
    using target database control file instead of recovery catalog
    database closed
    database dismounted
    Oracle instance shut down
    
    RMAN> startup mount
    connected to target database (not started)
    Oracle instance started
    database mounted
    
    Total System Global Area     188743680 bytes
    Fixed Size                     1257932 bytes
    Variable Size                109055540 bytes
    Database Buffers              75497472 bytes
    Redo Buffers                   2932736 bytes
    
    RMAN> switch database to copy;  -- Все, что потребовалось для "восстановления" из бэкапа.
    
    datafile 1 switched to datafile copy "/tmp/snapshot1_data_D-XE_I-2637837781_TS-SYSTEM_FNO-1_06ml28rn.dbf"
    datafile 2 switched to datafile copy "/tmp/snapshot1_data_D-XE_I-2637837781_TS-UNDO_FNO-2_07ml28sg.dbf"
    datafile 3 switched to datafile copy "/tmp/snapshot1_data_D-XE_I-2637837781_TS-SYSAUX_FNO-3_05ml28qj.dbf"
    datafile 4 switched to datafile copy "/tmp/snapshot1_data_D-XE_I-2637837781_TS-USERS_FNO-4_04ml28iu.dbf"
    
    ...
    -- Если необходимо, именно здесь можно "продвинуть" базу вперед, используя архивные копии логов.
    -- Мы не будем этого делать и откроем базу немедленно.
    ...
    
    16:28:47 SQL> recover database until cancel;
    ORA-00279: change 724041 generated at 08/27/2011 16:09:48 needed for thread 1
    ORA-00289: suggestion :
    /usr/lib/oracle/xe/app/oracle/flash_recovery_area/XE/archivelog/2011_08_27/o1_mf_1_2_%u_.arc
    ORA-00280: change 724041 for thread 1 is in sequence #2
    
    16:28:57 Specify log: {=suggested | filename | AUTO | CANCEL}
    cancel
    Media recovery cancelled.
    
    16:29:19 SQL> alter database open resetlogs;
    
    Database altered.
    
    Elapsed: 00:00:14.79
    16:29:40 SQL>
    
    16:30:19 SQL> select * from t1;
    
    DT					      MSG
    --------------------------------------------- ---------------------------------------------
    27-AUG-11 04.02.14.374409 PM		      Test 1 - initial row
    
    1 row selected.
    
    Elapsed: 00:00:00.03
    16:30:22 SQL>
    

    Заметьте - физическое восстановление (т.е. копирование данных из) бэкапа не потребовалось, мы просто "зарегистрировали" сделанные ранее копии как реальные файлы данных. Это позволило опустить шаг "restore". В нашем случае шаг "recover" также не понадобился - все файлы-копии уже имели один и тот же SCN 724041.

    Если все необходимые архивные копии лог файлов сохранены, мы могли бы "продвинуть" наши файлы-копии вперед до любого SCN, предшествующего вводу ошибочных данных. Таким образом, обе проблемы были бы решены - база данных "восстановлена" из бэкапа и все новые данные добавлены из лог файлов, вплоть до момента "логического повреждения" данных в таблицах.

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

    Назад в будущее?

    Предположим невозможное :-) Ложная тревога - оказывается, все данные были введены правильно, никакого логического повреждения не случилось и все произошедшее объясняется просто - директория "/usr/lib/oracle/xe/oradata/XE/" была смонтирована через NFS и временный перебой в работе сети привел к исчезновению всех файлов. Сейчас они появились, целые и невредимые. Все наши действия были трагической ошибкой ... нам надо срочно вернуть базу к SCN 724153 (две записи в таблице T1).

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

    ............... == Книга Премудрости Иисуса, сына Сирахова == ..................
    === Глава 3, Стих 22 ===
    22 Что заповедано тебе,  о  том  размышляй;  ибо  не  нужно  тебе,  что сокрыто.
    
    (b+/b-, c+/c-, +/-, *) >
    
    [oracle@OUL6 ~]$ cat /tmp/ctl.last.sql
    CREATE CONTROLFILE REUSE DATABASE "XE" RESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 292
    LOGFILE
    GROUP 1 '/usr/lib/oracle/xe/oradata/XE/onlineloga.log'  SIZE 50M,
    GROUP 2 '/usr/lib/oracle/xe/oradata/XE/onlinelogb.log'  SIZE 50M
    -- STANDBY LOGFILE
    DATAFILE
    '/usr/lib/oracle/xe/oradata/XE/system.dbf',
    '/usr/lib/oracle/xe/oradata/XE/sysaux.dbf',
    '/usr/lib/oracle/xe/oradata/XE/undo.dbf',
    '/usr/lib/oracle/xe/oradata/XE/users.dbf'
    CHARACTER SET AL32UTF8
    ;
    
    [oracle@OUL6 ~]$ sqlplus
    
    SQL*Plus: Release 10.2.0.1.0 - Production on Sat Aug 27 17:13:14 2011
    
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    
    Enter user-name: / as sysdba
    Connected to an idle instance.
    
    alter session set NLS_DATE_FORMAT='DD-MON-RR HH24:MI'
    *
    ERROR at line 1:
    ORA-01034: ORACLE not available
    
    Elapsed: 00:00:00.00
    17:13:17 SQL> startup nomount
    ORACLE instance started.
    
    Total System Global Area  188743680 bytes
    Fixed Size                  1257932 bytes
    Variable Size             109055540 bytes
    Database Buffers           75497472 bytes
    Redo Buffers                2932736 bytes
    17:13:23 SQL> @/tmp/ctl.last.sql
    
    Control file created.
    
    Elapsed: 00:00:02.11
    17:13:27 SQL> alter database open resetlogs;  -- Здесь мне повезло, файлы имеют одинаковый SCN
    
    Database altered.
    
    Elapsed: 00:00:08.12
    17:13:42 SQL>
    17:27:28 SQL> select * from t1;
    
    DT                                            MSG
    --------------------------------------------- ---------------------------------------------
    27-AUG-11 04.02.14.374409 PM                  Test 1 - initial row
    27-AUG-11 04.21.05.364685 PM                  Test 2 - after image copy backup
    
    2 rows selected.
    
    Elapsed: 00:00:00.04
    17:27:31 SQL>
    

    В примере вверху мне повезло - все файлы имеют один и тот же SCN, что свидетельствует о нормальном функционировании базы до самого сбоя в сети. Мне могло бы понадобиться ввести "recover database;" из командной строки SQL*Plus - и именно здесь пригодились бы "старые" копии лог файлов.

    Каков результат? База данных возвращена к исходному состоянию, опять же за секунды и без копирования данных. Все данные восстановлены - таблица T1 снова имеет две записи. База данных могла бы быть продвинута до последней записи последнего архивированного лога.

    А теперь ...

    ... сделайте "свежую" резервную копию!

    Резервное копирование является критическим моментом в использовании любой базы данных. Я рекомендую вам использовать оба подхода - image copies для быстрого "переключения" базы данных с поврежденных файлов на исправные копии, и compressed backupsets для хранения копий ваших данных на USB дисках или магнитных лентах где-нибудь вдали от серверной комнаты.

    Спасибо что зашли,

    Будьте благословенны!
    Денис