しばちょう先生の試して納得!DBAへの道 indexページ▶▶

 


みなさん、こんにちは。”しばちょう”こと柴田長(しばた つかさ)です。

7/1に開催されたOracle Database Technology Night ~集え!オラクルの力(チカラ)~に足を運んで頂いた方、本当にありがとうございました!5月のOracle Database Connect 2016で話切れなかった部分まで触れることが出来たので、無事にリベンジを果たすことが出来たのではと感じております。ちなみに、Oracle Database Technology Nightは7/1を皮切りに、今後ほぼ毎月一回のペースで日本オラクルが誇る技術者陣が現場で今すぐ使える技術情報を皆様にお届けさせて頂く予定です。また、皆様からのご質問にダイレクトに回答させて頂いたり、ディスカッションさせて頂ければと考えております。是非、皆さんとDatabase Technologyを盛り上げていきたいと思いますので、ご参加のほどよろしくお願い致します。次回の8/1(月)では、津島博士にパフォーマンス・チューニングを語って頂く予定です。(申し込みはこちら

さて、今回は前回に引き続き、Recovery Manager(以降、RMAN)の機能をご紹介させて頂きます。従来からRecovery Managerでは「表領域のPoint-in-Timeリカバリ(TSPITR)」を提供していましたが、これは対象表領域内の全てのオブジェクト(表や索引等)が対象となる為、最適なソリューションではありませんでした。そして、Oracle Database 12c Release 1から機能が拡張されて、これを簡単に実現するRMANのコマンドが実装されています。私が講演するセミナー等では何度か紹介させて頂いておりますが、改めて、こちらの連載でも体験して頂ければと思います!!以下の演習をOracle Database 12c Release 1のデータベースで試してみてください。

なお、Oracle Database 12c Release 1 (12.1.0.2) の単一インスタンス・データベースのインストレーション・ガイド及び、Oracle VM VirtualBoxを用いたOracle Database 12c Release 1 環境の構築ガイドが、Oracle Technology Networkのこちらのページに公開されておりますので、参考にしてみてください。

  • 【今回ご紹介するネタ一覧(逆引き)】
  • ✓ 表領域のPoint-in-Timeリカバリ(演習4)
  • ✓ 表単位のリカバリ(演習8)
  • ✓ しばちょう流 – 表単位のリカバリ with Data Guard(演習10)


1. RMANにおいて、Level0のオンライン・バックアップが実行できるように設定をして下さい。
これらの設定が完了した後に、100MBの表領域”TBS46″を作成し、その表領域上に100レコードが格納された表”TAB461″と表”TAB462″を作成して下さい。

$ sqlplus / as sysdba
SQL> -- RMAN バックアップの為に、アーカイブ・ログ・モードと高速リカバリ領域の設定
shutdown immediate ;
startup mount ;
alter database archivelog ;
alter system set DB_RECOVERY_FILE_DEST_SIZE = 8g ;
alter system set DB_RECOVERY_FILE_DEST = '+FRA' ;
alter database open ; 

-- 確認
archive log list

Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     502
Next log sequence to archive   504
Current log sequence           504

show parameter db_recovery

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string      +FRA
db_recovery_file_dest_size           big integer 8G


-- TBS46表領域と、この表領域をデフォルト表領域とするTRYユーザーの作成
create tablespace TBS46 datafile '+DATA(DATAFILE)' size 100m uniform size 1m ;
create user TRY identified by TRY12345 default tablespace TBS46 ;
grant connect, resource, dba to TRY ;

-- 2つの表の作成とデータ・ローディング
connect TRY/TRY12345
create table TAB461 (COL1 number NOT NULL, COL2 char(1000)) pctfree 10 ;
create table TAB462 (COL1 number NOT NULL, COL2 char(1000)) pctfree 10 ;

insert all into TAB461 into TAB462 
  select LEVEL, 'hoge'||to_char(LEVEL) from DUAL connect by LEVEL <= 100 ;
commit;

select count(*) from TAB461 ;

  COUNT(*)
----------
       100

select count(*) from TAB462 ;

  COUNT(*)
----------
       100

 

さあ今回も張り切って行きましょう!こちらの演習は、既に何度も行って頂いていると思いますので詳しい解説は省略させて頂きますね。

ちなみに、私はRMANバックアップの保存先として高速リカバリ領域を使用することをお薦めします。その理由は大きく二つあります。一つ目はRMANバックアップやアーカイブ・ログの保存先を明示的に設定する必要が無い事(デフォルトで高速リカバリ領域となる)であり、これは非常に便利であると言えるでしょう。二つ目は高速リカバリ領域には二つのポリシー(BACKUP RETENTION POLICYとARCHIVELOG DELETION POLICY)に従って、領域が不足した場合に自動的にファイルを削除する機能が実装されているからですね。また、高速リカバリ領域を使用する為には、データファイルを格納するASMディスク・グループとは別で用意する必要があるのか?と良く質問を受けますのが、答えは「いいえ、必須ではありません」になります。もちろん、お薦めは別にした方が可用性や管理性の観点から良いのですが、一つのASMディスク・グループしか用意できない場合にはディレクトリを切って指定する方法(DB_RECOVERY_FILE_DEST = ‘+DATA/FRA’)でも良いかと思います。

二つのポリシーに関しては、【Oracle DBA & Developer Day 2014】しばちょう先生による特別講義! RMANバックアップの運用と高速化チューニング 【PDF】を参考にしてみて下さい。


2. RMANを使用して、全てデータファイルのイメージ・コピー・バックアップを取得してください。

$ export NLS_DATE_FORMAT="YYYY/MM/DD HH24:MI:SS";
$ rman target /
connected to target database: ORCL (DBID=1369356044)
RMAN>
backup as copy database ;

Starting backup at 2016/07/21 04:09:11
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=271 device type=DISK
allocated channel: ORA_DISK_2
channel ORA_DISK_2: SID=27 device type=DISK
channel ORA_DISK_1: starting datafile copy
input datafile file number=00001 name=+DATA/ORCL/DATAFILE/system.261.841575323
channel ORA_DISK_2: starting datafile copy
input datafile file number=00002 name=+DATA/ORCL/DATAFILE/sysaux.262.841575331
output file name=+FRA/ORCL/DATAFILE/system.307.917755755 tag=TAG20160721T040913 RECID=120 STAMP=917755778
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:25
channel ORA_DISK_1: starting datafile copy
input datafile file number=00006 name=+DATA/ORCL/DATAFILE/undotbs.267.896676927
output file name=+FRA/ORCL/DATAFILE/sysaux.261.917755755 tag=TAG20160721T040913 RECID=119 STAMP=917755769
channel ORA_DISK_2: datafile copy complete, elapsed time: 00:00:26
channel ORA_DISK_2: starting datafile copy
input datafile file number=00003 name=+DATA/ORCL/DATAFILE/tbs46.263.917755687
output file name=+FRA/ORCL/DATAFILE/tbs46.267.917755781 tag=TAG20160721T040913 RECID=121 STAMP=917755785
channel ORA_DISK_2: datafile copy complete, elapsed time: 00:00:07
channel ORA_DISK_2: starting datafile copy
input datafile file number=00004 name=+DATA/ORCL/DATAFILE/users.265.841575363
output file name=+FRA/ORCL/DATAFILE/undotbs.308.917755781 tag=TAG20160721T040913 RECID=122 STAMP=917755786
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:08
channel ORA_DISK_1: starting datafile copy
copying current control file
output file name=+FRA/ORCL/CONTROLFILE/backup.293.917755787 tag=TAG20160721T040913 RECID=123 STAMP=917755787
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
including current SPFILE in backup set
channel ORA_DISK_1: starting piece 1 at 2016/07/21 04:09:48
channel ORA_DISK_1: finished piece 1 at 2016/07/21 04:09:49
piece handle=+FRA/ORCL/BACKUPSET/2016_07_21/nnsnf0_tag20160721t040913_0.288.917755789 tag=TAG20160721T040913 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
output file name=+FRA/ORCL/DATAFILE/users.282.917755787 tag=TAG20160721T040913 RECID=124 STAMP=917755790
channel ORA_DISK_2: datafile copy complete, elapsed time: 00:00:05
Finished backup at 2016/07/21 04:09:51

 

上記は、シンプルにデータベースのフルバックアップを取得するコマンド(backup as copy database ;)を実行している例であり、これ以外でも問題はありません。逆に、例として書いている自分が言うのも変なのですが、このコマンドで本番運用は難しいかなと正直思います。と言うのは、増分バックアップに対応出来ないですからね。毎回フルバックアップする運用であれば良いかもしれませんが、数百GBや数TB級のデータベースでは、高速増分バックアップでの運用がお薦めです。是非、第21回第22回の記事を参考にして頂ければ幸いです。


3. 障害を想定し、表TAB461をTRUNCATEすることで全レコードを削除して下さい。合わせて、表TAB462側には一件INSERTをして下さい。

$ sqlplus /nolog
SQL>
-- 検証目的として、障害発生前のSCNを確認しておく
connect / as sysdba
select CURRENT_SCN from V$DATABASE ;

CURRENT_SCN
-----------
    2364317

-- 障害を発生させる
connect TRY/TRY12345
truncate table TAB461 ;
insert into TAB462 values(0, 'add') ;
commit ;

select count(*) from TAB461 ;

  COUNT(*)
----------
         0

select count(*) from TAB462 ;

  COUNT(*)
----------
       101

 

こちらの演習では誤って表をTRUNCATEしてしまったという障害シナリオを想定しています。以降の演習を進める上で、気に留めておいて頂きたいのは、表TAB461はTRUNCATEしてレコードがゼロ件になっている点と、そのTRUNCATE後に、同じ表領域上に作成されている表TAB462に対して、一件のレコードが追加されている点の2つです。

さて、このTRUNCATE処理をどのように取り消せば良いでしょうか?DROP処理では無いのでFlashback Drop機能は使えませんから、TRUNCATE処理が行われる前の時点へ不完全リカバリが必要になるでしょう。しかし、一つの表をリカバリする為にデータベース全体を不完全リカバリしてしまったら、他の表も過去の時点に戻ってしまうことになってしまいます。悩みますよね~

と言う事で、Oracle Database 12c Release 1から登場した「表単位のリカバリ」を今回の連載記事でご紹介させて頂くのですが、もう一段回上の単位(データベース全体 > 表領域単位 > 表単位)である、11g Release 2まででも使用可能な表領域の不完全リカバリ(TableSpace Point-In-Time Recovery: TSPITR)を体験してみましょう。


4. 演習3で発生させた障害を復旧するために、表TAB461が格納されている表領域TBS46に対して、表領域のPoint-in-Timeリカバリ(TSPITR)を実行して下さい。

 

$ sqlplus /nolog
SQL> connect as sysdba

-- 表領域TBS46が自己完結型で、SYSのオブジェクトが表領域内に無いことを確認
begin
  dbms_tts.transport_set_check('TBS46', TRUE, TRUE) ;
end ;
/
PL/SQL procedure successfully completed.

select * from TRANSPORT_SET_VIOLATIONS ;
no rows selected


-- TSPITRの実行後に消失するオブジェクトの確認
select OWNER, NAME, TABLESPACE_NAME, to_char(CREATION_TIME,'YYYY/MM/DD HH24:MI:SS')
  from TS_PITR_OBJECTS_TO_BE_DROPPED
 where TABLESPACE_NAME in ('TBS46')
   and CREATION_TIME > to_date(to_char(SCN_TO_TIMESTAMP(2364317),
                         'YYYY/MM/DD HH24:MI:SS'), 'YYYY/MM/DD HH24:MI:SS')
 order by CREATION_TIME, OWNER, NAME ;

no rows selected


-- 表領域のPoint-in-Timeリカバリ(TSPITR)
$ rman target /
RMAN>
recover tablespace TBS46
  until scn 2364317
  auxiliary destination '+FRA' ;

Starting recover at 2016/07/21 04:43:35
...(省略)...
Finished recover at 2016/07/21 04:47:02


RMAN> -- リカバリした表領域をONLINE化
SQL "alter tablespace TBS46 online" ;

 

はい、如何でしょうか?以前からある機能ではありますが、意外と本気で実行した経験のある方は少ないのではないでしょうか?

TSPITRを実行する前には、対象とする表領域が自己完結型であることやSYSユーザーがOWNERであるオブジェクトが含まれていない事を確認する必要があり、dbms_ttsパッケージのtransport_set_checkプロシージャを実行して、TRANSPORT_SET_VIOLATIONSビューで結果を確認する手順を踏みます。自己完結型とは、例えばパーティション表が理解し易いかと思います。パーティション表は複数のパーティションから構成されますが、各パーティションを格納する表領域を使い分けることが可能です。つまり、一つのパーティション表が複数の表領域にまたがって構成されていると、これは自己完結型とは言えません。この場合にはそれら全ての表領域も同時にTSPITRの対象として扱う必要が出てきますので、注意が必要です。

次に、目標とする過去の時点へ対象の表領域をリカバリした際に、消えてしまうオブジェクトが無いのかを確認しておきます。これは必須ではありませんが、もし消えてしまって困るオブジェクトがあれば、TSPITRの実行前にデータ・ポンプ・エクスポート・ユーティリティを使用してエクスポートしておくことをお薦めします。TSPITR後にインポートすることで消失を回避できますからね。

そして、ようやくTSPITRを実行することになりますが、コマンドの引数としては3つ。一つ目は対象の表領域名(複数指定可能)二つ目はリカバリ目標時点(上記の例はTRUNCATE前のSCN番号)、三つ目はTSPITRの処理の作業領域です。この作業領域が必要になる理由は、マニュアルにも記載がある通り、TSPITRの処理では自動的に起動することになる補助インスタンスを起動させて、一部のバックアップをリストア+リカバリする事になるからです。詳しくはマニュアルと以下に張り付けたTSPITR実行時の標準出力を参考に、内部的にどのような事を実施しているのかを読み解いてみると面白いと思います。(私はこう言う事が大好きです)でもって、最後にリカバリした表領域はOFFLINE状態になっているので、ONLINE化して完了となります。

RMAN>
recover tablespace TBS46
  until scn 2364317
  auxiliary destination '+FRA' ;

Starting recover at 2016/07/21 04:43:35
using channel ORA_DISK_1
using channel ORA_DISK_2
RMAN-05026: WARNING: presuming following set of tablespaces applies to specified Point-in-Time

List of tablespaces expected to have UNDO segments
Tablespace SYSTEM
Tablespace UNDOTBS

Creating automatic instance, with SID='Dkpn'

initialization parameters used for automatic instance:
db_name=ORCL
db_unique_name=Dkpn_pitr_ORCL
compatible=12.1.0.0.0
db_block_size=8192
db_files=200
diagnostic_dest=/u01/app/oracle
_system_trig_enabled=FALSE
sga_target=1184M
processes=200
db_create_file_dest=+FRA
log_archive_dest_1='location=+FRA'
#No auxiliary parameter file used


starting up automatic instance ORCL

Oracle instance started

Total System Global Area    1241513984 bytes

Fixed Size                     2923872 bytes
Variable Size                335544992 bytes
Database Buffers             889192448 bytes
Redo Buffers                  13852672 bytes
Automatic instance created
Running TRANSPORT_SET_CHECK on recovery set tablespaces
TRANSPORT_SET_CHECK completed successfully

contents of Memory Script:
{
# set requested point in time
set until  scn 2364317;
# restore the controlfile
restore clone controlfile;

# mount the controlfile
sql clone 'alter database mount clone database';

# archive current online log
sql 'alter system archive log current';
# avoid unnecessary autobackups for structural changes during TSPITR
sql 'begin dbms_backup_restore.AutoBackupFlag(FALSE); end;';
}
executing Memory Script

executing command: SET until clause

Starting restore at 2016/07/21 04:44:00
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=165 device type=DISK
allocated channel: ORA_AUX_DISK_2
channel ORA_AUX_DISK_2: SID=177 device type=DISK

channel ORA_AUX_DISK_1: restoring control file
channel ORA_AUX_DISK_1: copied control file copy
input file name=+FRA/ORCL/CONTROLFILE/backup.293.917755787
output file name=+FRA/ORCL/CONTROLFILE/current.281.917757843
Finished restore at 2016/07/21 04:44:03

sql statement: alter database mount clone database

sql statement: alter system archive log current

sql statement: begin dbms_backup_restore.AutoBackupFlag(FALSE); end;

contents of Memory Script:
{
# set requested point in time
set until  scn 2364317;
# set destinations for recovery set and auxiliary set datafiles
set newname for clone datafile  1 to new;
set newname for clone datafile  6 to new;
set newname for clone datafile  2 to new;
set newname for clone tempfile  1 to new;
set newname for datafile  3 to
 "+DATA/ORCL/DATAFILE/tbs46.263.917755687";
# switch all tempfiles
switch clone tempfile all;
# restore the tablespaces in the recovery set and the auxiliary set
restore clone datafile  1, 6, 2, 3;

switch clone datafile all;
}
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

renamed tempfile 1 to +FRA in control file

Starting restore at 2016/07/21 04:44:08
using channel ORA_AUX_DISK_1
using channel ORA_AUX_DISK_2

channel ORA_AUX_DISK_1: restoring datafile 00001
input datafile copy RECID=120 STAMP=917755778 file name=+FRA/ORCL/DATAFILE/system.307.917755755
destination for restore of datafile 00001: +FRA
channel ORA_AUX_DISK_2: restoring datafile 00006
input datafile copy RECID=122 STAMP=917755786 file name=+FRA/ORCL/DATAFILE/undotbs.308.917755781
destination for restore of datafile 00006: +FRA
channel ORA_AUX_DISK_2: copied datafile copy of datafile 00006
output file name=+FRA/ORCL/DATAFILE/undotbs.284.917757849 RECID=123 STAMP=917757857
channel ORA_AUX_DISK_2: restoring datafile 00002
input datafile copy RECID=119 STAMP=917755769 file name=+FRA/ORCL/DATAFILE/sysaux.261.917755755
destination for restore of datafile 00002: +FRA
channel ORA_AUX_DISK_1: copied datafile copy of datafile 00001
output file name=+FRA/ORCL/DATAFILE/system.266.917757849 RECID=124 STAMP=917757874
channel ORA_AUX_DISK_1: restoring datafile 00003
input datafile copy RECID=121 STAMP=917755785 file name=+FRA/ORCL/DATAFILE/tbs46.267.917755781
destination for restore of datafile 00003: +DATA/ORCL/DATAFILE/tbs46.263.917755687
channel ORA_AUX_DISK_2: copied datafile copy of datafile 00002
output file name=+FRA/ORCL/DATAFILE/sysaux.273.917757865 RECID=125 STAMP=917757877
channel ORA_AUX_DISK_1: copied datafile copy of datafile 00003
output file name=+DATA/ORCL/DATAFILE/tbs46.263.917755687 RECID=0 STAMP=0
Finished restore at 2016/07/21 04:44:46

datafile 1 switched to datafile copy
input datafile copy RECID=126 STAMP=917757886 file name=+FRA/ORCL/DATAFILE/system.266.917757849
datafile 6 switched to datafile copy
input datafile copy RECID=127 STAMP=917757887 file name=+FRA/ORCL/DATAFILE/undotbs.284.917757849
datafile 2 switched to datafile copy
input datafile copy RECID=128 STAMP=917757887 file name=+FRA/ORCL/DATAFILE/sysaux.273.917757865

contents of Memory Script:
{
# set requested point in time
set until  scn 2364317;
# online the datafiles restored or switched
sql clone "alter database datafile  1 online";
sql clone "alter database datafile  6 online";
sql clone "alter database datafile  2 online";
sql clone "alter database datafile  3 online";
# recover and open resetlogs
recover clone database tablespace  "TBS46", "SYSTEM", "UNDOTBS", "SYSAUX" delete archivelog;
alter clone database open resetlogs;
}
executing Memory Script

executing command: SET until clause

sql statement: alter database datafile  1 online

sql statement: alter database datafile  6 online

sql statement: alter database datafile  2 online

sql statement: alter database datafile  3 online

Starting recover at 2016/07/21 04:44:47
using channel ORA_AUX_DISK_1
using channel ORA_AUX_DISK_2

starting media recovery

archived log for thread 1 with sequence 508 is already on disk as file +FRA/ORCL/ARCHIVELOG/2016_07_21/thread_1_seq_508.286.917755889
archived log file name=+FRA/ORCL/ARCHIVELOG/2016_07_21/thread_1_seq_508.286.917755889 thread=1 sequence=508
media recovery complete, elapsed time: 00:00:01
Finished recover at 2016/07/21 04:44:50

database opened

contents of Memory Script:
{
# make read only the tablespace that will be exported
sql clone 'alter tablespace  TBS46 read only';
# create directory for datapump import
sql "create or replace directory TSPITR_DIROBJ_DPDIR as ''
+FRA''";
# create directory for datapump export
sql clone "create or replace directory TSPITR_DIROBJ_DPDIR as ''
+FRA''";
}
executing Memory Script

sql statement: alter tablespace  TBS46 read only

sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''+FRA''

sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''+FRA''

Performing export of metadata...
   EXPDP> Starting "SYS"."TSPITR_EXP_Dkpn_tcvr":
   EXPDP> Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK
   EXPDP> Processing object type TRANSPORTABLE_EXPORT/TABLE
   EXPDP> Processing object type TRANSPORTABLE_EXPORT/TABLE_STATISTICS
   EXPDP> Processing object type TRANSPORTABLE_EXPORT/STATISTICS/MARKER
   EXPDP> Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
   EXPDP> Master table "SYS"."TSPITR_EXP_Dkpn_tcvr" successfully loaded/unloaded
   EXPDP> ******************************************************************************
   EXPDP> Dump file set for SYS.TSPITR_EXP_Dkpn_tcvr is:
   EXPDP>   +FRA/tspitr_dkpn_65630.dmp
   EXPDP> ******************************************************************************
   EXPDP> Datafiles required for transportable tablespace TBS46:
   EXPDP>   +DATA/ORCL/DATAFILE/tbs46.263.917755687
   EXPDP> Job "SYS"."TSPITR_EXP_Dkpn_tcvr" successfully completed at Thu Jul 21 04:46:16 2016 elapsed 0 00:00:38
Export completed


contents of Memory Script:
{
# shutdown clone before import
shutdown clone abort
# drop target tablespaces before importing them back
sql 'drop tablespace  TBS46 including contents keep datafiles cascade constraints';
}
executing Memory Script

Oracle instance shut down

sql statement: drop tablespace  TBS46 including contents keep datafiles cascade constraints

Performing import of metadata...
   IMPDP> Master table "SYS"."TSPITR_IMP_Dkpn_ibho" successfully loaded/unloaded
   IMPDP> Starting "SYS"."TSPITR_IMP_Dkpn_ibho":
   IMPDP> Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK
   IMPDP> Processing object type TRANSPORTABLE_EXPORT/TABLE
   IMPDP> Processing object type TRANSPORTABLE_EXPORT/TABLE_STATISTICS
   IMPDP> Processing object type TRANSPORTABLE_EXPORT/STATISTICS/MARKER
   IMPDP> Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
   IMPDP> Job "SYS"."TSPITR_IMP_Dkpn_ibho" successfully completed at Thu Jul 21 04:46:58 2016 elapsed 0 00:00:07
Import completed


contents of Memory Script:
{
# make read write and offline the imported tablespaces
sql 'alter tablespace  TBS46 read write';
sql 'alter tablespace  TBS46 offline';
# enable autobackups after TSPITR is finished
sql 'begin dbms_backup_restore.AutoBackupFlag(TRUE); end;';
}
executing Memory Script

sql statement: alter tablespace  TBS46 read write

sql statement: alter tablespace  TBS46 offline

sql statement: begin dbms_backup_restore.AutoBackupFlag(TRUE); end;

Removing automatic instance
Automatic instance removed
auxiliary instance file +FRA/ORCL/TEMPFILE/temp.301.917757893 deleted
auxiliary instance file +FRA/ORCL/ONLINELOG/group_3.302.917757893 deleted
auxiliary instance file +FRA/ORCL/ONLINELOG/group_2.303.917757891 deleted
auxiliary instance file +FRA/ORCL/ONLINELOG/group_1.304.917757891 deleted
auxiliary instance file +FRA/ORCL/DATAFILE/sysaux.273.917757865 deleted
auxiliary instance file +FRA/ORCL/DATAFILE/undotbs.284.917757849 deleted
auxiliary instance file +FRA/ORCL/DATAFILE/system.266.917757849 deleted
auxiliary instance file +FRA/ORCL/CONTROLFILE/current.281.917757843 deleted
auxiliary instance file tspitr_Dkpn_65630.dmp deleted
Finished recover at 2016/07/21 04:47:02


5. 演習4により、表TAB461と表TAB462が障害発生前の状態に戻っていることを確認して下さい。

$ sqlplus /nolog
SQL> connect TRY/TRY12345
select count(*) from TAB461 ;

  COUNT(*)
----------
       100

select count(*) from TAB462 ;

  COUNT(*)
----------
       100

 

と言う事で、表TAB461をTRUNCATEする前の状態にリカバリ出来ていることが確認できたかと思います。TRUNCATEする前とは、二つの表共に100件のレコードが格納されている状態でしたよね?ここで覚えておいて頂きたいポイントは、TRUNCATEした表は元に戻ってOKなのですが、もう一つの表TAB462も同時に戻ってしまっている(TRUNCATE後に一件INSERTしたレコードが消えてしまっている)点です。これは表TAB462が、TSPITRの対象とした表領域TBS46上に存在していたから仕方が無いのですね。

しかし、この「仕方が無い」で終わらないのがOracle Database 12c の凄みであり、新機能である表単位のリカバリを使えば解決出来るのです。さあ、続きも頑張りましょう。


6. 再びフルバックアップを取得して下さい。(必要に応じて、演習2で取得したバックアップは消して頂いて問題ありません)

$ rman target /
RMAN>
delete noprompt datafilecopy all ;
delete noprompt backupset ;
backup as copy database ;

 

はい、こちらは準備ですので、解説は省略させて頂きますね。


7. 障害を想定し、表TAB461をTRUNCATE + 一件INSERTして下さい。合わせて、表TAB462側には一件INSERTをして下さい。

$ sqlplus /nolog
SQL> 
-- 検証目的として、障害発生前のSCNを確認しておく
connect / as sysdba
select CURRENT_SCN from V$DATABASE ;

CURRENT_SCN
-----------
    2372111

-- 障害を発生させる
connect TRY/TRY12345
truncate table TAB461 ;
insert into TAB461 values(0, 'add') ;
insert into TAB462 values(0, 'add') ;
commit ;

select count(*) from TAB461 ;

  COUNT(*)
----------
         1

select count(*) from TAB462 ;

  COUNT(*)
----------
       101

 

演習3で作りだした障害から少しだけ変えてあることにお気付きでしょうか?はい、そうですね。表TAB461をTRUNCATEするだけでは無く一件レコードをINSERTしています。こちらの方が現実的な障害かもしれませんね。TRUNCATE後に直ぐに気付いてDBAが対処できれば良いのですが、業務アプリケーションは動き続けているわけで新たなレコードがINSERTされてくる事は普通に想定される事でしょう。そして、DBAに求められることは「TRUNCATEされたレコードを元に戻す」だけでは無く、「TRUNCATE後にINSERTされたレコードは保持すること」も同時に求められる事になるでしょう。

さて、この矛盾していそうな要件を同時に満たす為にはどうすべきか?追加されてしまったレコードを別にエクスポートしておいて、先ほどのTSPITRを行っても良さそうですが、その表領域内の全オブジェクトが過去の時点に戻ってしまうので、影響のある表が多くなればなるほど、エクスポートしておくべき表が多くなり・・・正直苦しいですよね。でも安心して下さい。次の演習を体験することで、業務アプリのチームから絶対的な信頼を得られるDBAへ成長することが出来ると私は思います。


8. 演習7で発生させた障害でTRUNCATEされたレコードを復旧するため、表TAB461に限定して表単位のリカバリを実行して下さい。ただし、TRUNCATE後にINSERTされたレコードは残して下さい。

$ rman target /
RMAN>
RECOVER TABLE TRY.TAB461
  UNTIL SCN 2372111
  AUXILIARY DESTINATION '+FRA'
  DATAPUMP DESTINATION '/tmp'
  DUMP FILE 'try_tab461_exp.dmp'
  NOTABLEIMPORT;

Starting recover at 2016/07/21 05:01:37
...(省略)...
Finished recover at 2016/07/21 05:05:04


$ sqlplus /nolog
SQL> 
-- ダンプファイルのディレクトリを確認(自動的に作成されているはず)
connect / as sysdba
set linesize 150 pages 5000
col OWNER for a12
col DIRECTORY_NAME for a24
col DIRECTORY_PATH for a12
select OWNER, DIRECTORY_NAME, DIRECTORY_PATH from DBA_DIRECTORIES
 where DIRECTORY_NAME like 'TSPITR%' ;

OWNER        DIRECTORY_NAME           DIRECTORY_PA
------------ ------------------------ ------------
SYS          TSPITR_DIROBJ_DPDIR      /tmp


### 既存レコードを残しつつ、TRUNCATEされたレコードを表TAB461へインポート
$ impdp system TABLES='TRY.TAB461' CONTENT=DATA_ONLY TABLE_EXISTS_ACTION=APPEND DIRECTORY=TSPITR_DIROBJ_DPDIR DUMPFILE=try_tab461_exp.dmp

Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Advanced Analytics and Real Application Testing options
Master table "SYSTEM"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_IMPORT_TABLE_01":  system/******** TABLES=TRY.TAB461 CONTENT=DATA_ONLY TABLE_EXISTS_ACTION=APPEND DIRECTORY=TSPITR_DIROBJ_DPDIR DUMPFILE=try_tab461_exp.dmp
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "TRY"."TAB461"                              104.1 KB     100 rows
Job "SYSTEM"."SYS_IMPORT_TABLE_01" successfully completed at Thu Jul 21 05:10:47 2016 elapsed 0 00:00:09

 

凄いですよね!!Oracle Database 12cの表単位のリカバリは最高ですよね。

RECOVER TABLEコマンドで「戻したい表(TRY.TAB461)」、「戻したい時点(UNTIL SCN 2372111)」、「補助インスタンス用の領域(+FRA)」、「ダンプファイルの出力場所(/tmp)」、「ダンプファイル名」を指定します。ダンプファイルとは、そう、データ・ポンプ・エクスポート・ユーティリティで生成されるダンプファイルです。つまり、このRECOVER TABLEコマンドを実行すると指定した時点の表データがダンプファイルとして抽出されるのですね。なんか凄い事をやってそうですよね。ちなみに、上記コマンド例では「NOTABLEIMPORT」オプションを追加しており、これによりダンプファイルを抽出するところまでで止めています。このオプションを指定しない場合は、RECOVER TABLEコマンドを実行するだけで、対象表にインポートが行われて過去の時点に戻ります。

何故、NOTABLEIMPORTオプションを指定したのか?それは、自動的にインポートされる場合には表内の既存レコードをTRUNCATEしてしまうからですね。今回のリカバリ要件としては、「TRUNCATEされたレコードを元に戻す」だけでは無く「TRUNCATE後にINSERTされたレコードは保持すること」を同時に満たさなければならない為、それは避けなければなりません。

よって、NOTABLEIMPORTオプションでダンプファイルだけ抽出し、後から「CONTENT=DATA_ONLY」と「TABLE_EXISTS_ACTION=APPEND」の二つのオプションを明示的に指定したインポートを手動で実行しているのです。

ちなみに、RECOVER TABLEコマンドの中で、ダンプファイルが出力されるディレクトリ「TSPITR_DIROBJ_DPDIR」が自動的に生成される動作を私の環境では確認出来ていますので、この辺りも把握しておくと非常に役立つと思います。

また、私の環境でRECOVER TABLEコマンドを実行した際の標準出力を以下に掲載しておきますので、内部的にどのような処理が動いているのかを把握する為に役立てられるかと思います。とは言いつつ、マニュアルに書いてあったりします。それもOracle Database 12cのマニュアルでは無く、Oracle Database 11g Release 2のマニュアル「30 ユーザー管理のリカバリの実行: 高度な例(フラッシュバック機能を使用しない、削除された表のリカバリ)」の中に。え?ですよね。実は、複雑な手順ではあるのですが、この表単位のリカバリを手動で行う方法は以前から提供させて頂いていたのです。それを簡単に実行出来るようにしたのが、Oracle Database 12cのRECOVER TABLEコマンドなのですね。ちょっと得意げに書いてしまいましたが、ご存知の方がいらっしゃったらスイマセン。でも、知っている方は本当に凄いデータベース技術者だと思いますよ!!私は最近まで知らなかったです。。。

RMAN>
RECOVER TABLE TRY.TAB461
  UNTIL scn 2372111
  AUXILIARY DESTINATION '+FRA'
  DATAPUMP DESTINATION '/tmp'
  DUMP FILE 'try_tab461_exp.dmp'
  NOTABLEIMPORT;

Starting recover at 2016/07/21 05:01:37
using target database control file instead of recovery catalog
current log archived
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=270 device type=DISK
allocated channel: ORA_DISK_2
channel ORA_DISK_2: SID=33 device type=DISK
RMAN-05026: WARNING: presuming following set of tablespaces applies to specified Point-in-Time

List of tablespaces expected to have UNDO segments
Tablespace SYSTEM
Tablespace UNDOTBS

Creating automatic instance, with SID='oDzz'

initialization parameters used for automatic instance:
db_name=ORCL
db_unique_name=oDzz_pitr_ORCL
compatible=12.1.0.0.0
db_block_size=8192
db_files=200
diagnostic_dest=/u01/app/oracle
_system_trig_enabled=FALSE
sga_target=1184M
processes=200
db_create_file_dest=+FRA
log_archive_dest_1='location=+FRA'
#No auxiliary parameter file used


starting up automatic instance ORCL

Oracle instance started

Total System Global Area    1241513984 bytes

Fixed Size                     2923872 bytes
Variable Size                335544992 bytes
Database Buffers             889192448 bytes
Redo Buffers                  13852672 bytes
Automatic instance created

contents of Memory Script:
{
# set requested point in time
set until  scn 2372111;
# restore the controlfile
restore clone controlfile;

# mount the controlfile
sql clone 'alter database mount clone database';

# archive current online log
sql 'alter system archive log current';
}
executing Memory Script

executing command: SET until clause

Starting restore at 2016/07/21 05:01:59
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=14 device type=DISK
allocated channel: ORA_AUX_DISK_2
channel ORA_AUX_DISK_2: SID=15 device type=DISK

channel ORA_AUX_DISK_1: restoring control file
channel ORA_AUX_DISK_1: copied control file copy
input file name=+FRA/ORCL/CONTROLFILE/backup.288.917758765
output file name=+FRA/ORCL/CONTROLFILE/current.284.917758921
Finished restore at 2016/07/21 05:02:02

sql statement: alter database mount clone database

sql statement: alter system archive log current

contents of Memory Script:
{
# set requested point in time
set until  scn 2372111;
# set destinations for recovery set and auxiliary set datafiles
set newname for clone datafile  1 to new;
set newname for clone datafile  6 to new;
set newname for clone datafile  2 to new;
set newname for clone tempfile  1 to new;
# switch all tempfiles
switch clone tempfile all;
# restore the tablespaces in the recovery set and the auxiliary set
restore clone datafile  1, 6, 2;

switch clone datafile all;
}
executing Memory Script

executing command: SET until clause

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

renamed tempfile 1 to +FRA in control file

Starting restore at 2016/07/21 05:02:08
using channel ORA_AUX_DISK_1
using channel ORA_AUX_DISK_2

channel ORA_AUX_DISK_1: restoring datafile 00001
input datafile copy RECID=131 STAMP=917758756 file name=+FRA/ORCL/DATAFILE/system.307.917758733
destination for restore of datafile 00001: +FRA
channel ORA_AUX_DISK_2: restoring datafile 00006
input datafile copy RECID=133 STAMP=917758763 file name=+FRA/ORCL/DATAFILE/undotbs.267.917758757
destination for restore of datafile 00006: +FRA
channel ORA_AUX_DISK_2: copied datafile copy of datafile 00006
output file name=+FRA/ORCL/DATAFILE/undotbs.303.917758929 RECID=134 STAMP=917758937
channel ORA_AUX_DISK_2: restoring datafile 00002
input datafile copy RECID=130 STAMP=917758747 file name=+FRA/ORCL/DATAFILE/sysaux.308.917758733
destination for restore of datafile 00002: +FRA
channel ORA_AUX_DISK_1: copied datafile copy of datafile 00001
output file name=+FRA/ORCL/DATAFILE/system.304.917758929 RECID=135 STAMP=917758957
channel ORA_AUX_DISK_2: copied datafile copy of datafile 00002
output file name=+FRA/ORCL/DATAFILE/sysaux.302.917758943 RECID=136 STAMP=917758958
Finished restore at 2016/07/21 05:02:48

datafile 1 switched to datafile copy
input datafile copy RECID=137 STAMP=917758968 file name=+FRA/ORCL/DATAFILE/system.304.917758929
datafile 6 switched to datafile copy
input datafile copy RECID=138 STAMP=917758969 file name=+FRA/ORCL/DATAFILE/undotbs.303.917758929
datafile 2 switched to datafile copy
input datafile copy RECID=139 STAMP=917758969 file name=+FRA/ORCL/DATAFILE/sysaux.302.917758943

contents of Memory Script:
{
# set requested point in time
set until  scn 2372111;
# online the datafiles restored or switched
sql clone "alter database datafile  1 online";
sql clone "alter database datafile  6 online";
sql clone "alter database datafile  2 online";
# recover and open database read only
recover clone database tablespace  "SYSTEM", "UNDOTBS", "SYSAUX";
sql clone 'alter database open read only';
}
executing Memory Script

executing command: SET until clause

sql statement: alter database datafile  1 online

sql statement: alter database datafile  6 online

sql statement: alter database datafile  2 online

Starting recover at 2016/07/21 05:02:49
using channel ORA_AUX_DISK_1
using channel ORA_AUX_DISK_2

starting media recovery

archived log for thread 1 with sequence 514 is already on disk as file +FRA/ORCL/ARCHIVELOG/2016_07_21/thread_1_seq_514.266.917758899
archived log file name=+FRA/ORCL/ARCHIVELOG/2016_07_21/thread_1_seq_514.266.917758899 thread=1 sequence=514
media recovery complete, elapsed time: 00:00:00
Finished recover at 2016/07/21 05:02:52

sql statement: alter database open read only

contents of Memory Script:
{
   sql clone "create spfile from memory";
   shutdown clone immediate;
   startup clone nomount;
   sql clone "alter system set  control_files =
  ''+FRA/ORCL/CONTROLFILE/current.284.917758921'' comment=
 ''RMAN set'' scope=spfile";
   shutdown clone immediate;
   startup clone nomount;
# mount database
sql clone 'alter database mount clone database';
}
executing Memory Script

sql statement: create spfile from memory

database closed
database dismounted
Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area    1241513984 bytes

Fixed Size                     2923872 bytes
Variable Size                352322208 bytes
Database Buffers             872415232 bytes
Redo Buffers                  13852672 bytes

sql statement: alter system set  control_files =   ''+FRA/ORCL/CONTROLFILE/current.284.917758921'' comment= ''RMAN set'' scope=spfile

Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area    1241513984 bytes

Fixed Size                     2923872 bytes
Variable Size                352322208 bytes
Database Buffers             872415232 bytes
Redo Buffers                  13852672 bytes

sql statement: alter database mount clone database

contents of Memory Script:
{
# set requested point in time
set until  scn 2372111;
# set destinations for recovery set and auxiliary set datafiles
set newname for datafile  3 to new;
# restore the tablespaces in the recovery set and the auxiliary set
restore clone datafile  3;

switch clone datafile all;
}
executing Memory Script

executing command: SET until clause

executing command: SET NEWNAME

Starting restore at 2016/07/21 05:04:02
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=15 device type=DISK
allocated channel: ORA_AUX_DISK_2
channel ORA_AUX_DISK_2: SID=165 device type=DISK

channel ORA_AUX_DISK_1: restoring datafile 00003
input datafile copy RECID=132 STAMP=917758763 file name=+FRA/ORCL/DATAFILE/tbs46.282.917758759
destination for restore of datafile 00003: +FRA
channel ORA_AUX_DISK_1: copied datafile copy of datafile 00003
output file name=+FRA/ODZZ_PITR_ORCL/DATAFILE/tbs46.299.917759043 RECID=140 STAMP=917759046
Finished restore at 2016/07/21 05:04:06

datafile 3 switched to datafile copy
input datafile copy RECID=141 STAMP=917759047 file name=+FRA/ODZZ_PITR_ORCL/DATAFILE/tbs46.299.917759043

contents of Memory Script:
{
# set requested point in time
set until  scn 2372111;
# online the datafiles restored or switched
sql clone "alter database datafile  3 online";
# recover and open resetlogs
recover clone database tablespace  "TBS46", "SYSTEM", "UNDOTBS", "SYSAUX" delete archivelog;
alter clone database open resetlogs;
}
executing Memory Script

executing command: SET until clause

sql statement: alter database datafile  3 online

Starting recover at 2016/07/21 05:04:07
using channel ORA_AUX_DISK_1
using channel ORA_AUX_DISK_2

starting media recovery

archived log for thread 1 with sequence 514 is already on disk as file +FRA/ORCL/ARCHIVELOG/2016_07_21/thread_1_seq_514.266.917758899
archived log file name=+FRA/ORCL/ARCHIVELOG/2016_07_21/thread_1_seq_514.266.917758899 thread=1 sequence=514
media recovery complete, elapsed time: 00:00:00
Finished recover at 2016/07/21 05:04:09

database opened

contents of Memory Script:
{
# create directory for datapump import
sql "create or replace directory TSPITR_DIROBJ_DPDIR as ''
/tmp''";
# create directory for datapump export
sql clone "create or replace directory TSPITR_DIROBJ_DPDIR as ''
/tmp''";
}
executing Memory Script

sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''/tmp''

sql statement: create or replace directory TSPITR_DIROBJ_DPDIR as ''/tmp''

Performing export of tables...
   EXPDP> Starting "SYS"."TSPITR_EXP_oDzz_rygu":
   EXPDP> Estimate in progress using BLOCKS method...
   EXPDP> Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
   EXPDP> Total estimation using BLOCKS method: 1024 KB
   EXPDP> Processing object type TABLE_EXPORT/TABLE/TABLE
   EXPDP> Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
   EXPDP> Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
   EXPDP> . . exported "TRY"."TAB461"                              104.1 KB     100 rows
   EXPDP> Master table "SYS"."TSPITR_EXP_oDzz_rygu" successfully loaded/unloaded
   EXPDP> ******************************************************************************
   EXPDP> Dump file set for SYS.TSPITR_EXP_oDzz_rygu is:
   EXPDP>   /tmp/try_tab461_exp.dmp
   EXPDP> Job "SYS"."TSPITR_EXP_oDzz_rygu" successfully completed at Thu Jul 21 05:04:52 2016 elapsed 0 00:00:26
Export completed

Not performing table import after point-in-time recovery

Removing automatic instance
shutting down automatic instance
Oracle instance shut down
Automatic instance removed
auxiliary instance file +FRA/ORCL/TEMPFILE/temp.301.917758973 deleted
auxiliary instance file +FRA/ODZZ_PITR_ORCL/ONLINELOG/group_3.296.917759053 deleted
auxiliary instance file +FRA/ODZZ_PITR_ORCL/ONLINELOG/group_2.297.917759051 deleted
auxiliary instance file +FRA/ODZZ_PITR_ORCL/ONLINELOG/group_1.298.917759049 deleted
auxiliary instance file +FRA/ODZZ_PITR_ORCL/DATAFILE/tbs46.299.917759043 deleted
auxiliary instance file +FRA/ORCL/DATAFILE/sysaux.302.917758943 deleted
auxiliary instance file +FRA/ORCL/DATAFILE/undotbs.303.917758929 deleted
auxiliary instance file +FRA/ORCL/DATAFILE/system.304.917758929 deleted
auxiliary instance file +FRA/ORCL/CONTROLFILE/current.284.917758921 deleted
Finished recover at 2016/07/21 05:05:04

 


9. 演習7により、表TAB461においてTRUNCATEされたレコード(100件)と追加されたレコード(1件)の合計101件のレコードが格納されていることを確認して下さい。

$ sqlplus /nolog
SQL> connect TRY/TRY12345
select count(*) from TAB461 ;

  COUNT(*)
----------
       101
       
select count(*) from TAB462 ;

  COUNT(*)
----------
       101

 

こちらは念のための確認となります。問題無いですよね?

「TRUNCATEされたレコード(100件)を元に戻す」+「TRUNCATE後にINSERTされたレコード(1件)は保持すること」、つまり、100+1=101件のレコードがTAB461に格納されているので、目的は果たせましたね。さらに前段で体験したTSPITRでは同じ表領域内に格納されているTAB462のレコード数も100件に戻ってしまっていましたが、今回はリカバリの影響を受けていませんね。

と言う事で、Oracle Database 12c Release 1の新機能である「表単位のリカバリ」の有効性を体感して頂けたかと思います。

最後にオマケとして、Data Guard環境でPhysical Standby Databaseを持っているという条件が必要ではありますが、同じような表単位のリカバリを行う方法をご紹介しておきます。補助インスタンスを起動させるためのメモリやディスク領域が不要ですので、私個人としては非常に気に入っているソリューションです。


10. (おまけ)Data GuardによるPhysical Standby Databaseを持っている場合に、演習7と同等の復旧を行うオペレーションは次の通りです。もし、検証環境があれば試してみてくださいね。

### Standby Database側
$ sqlplus /nolog
SQL> -- Standby Database(osaka)を巻き戻して、Snapshot Standbyモードで起動
shutdown immediate
startup mount
flashback database to <障害発生前へ> ;
alter database convert to snapshot standby ;
alter database open ;
exit ;


### TRUNCATE前の対象表のデータをエクスポート
$ expdp system@osaka TABLES='TRY.TAB461' DIRECTORY=DUMPDIR DUMPFILE=TAB461.dmp

### Primary Database(tokyo)へ追記型インポート
$ impdp system@tokyo TABLES='TRY.TAB461' DIRECTORY=DUMPDIR DUMPFILE=TAB461.dmp
    CONTENT=DATA_ONLY TABLE_EXISTS_ACTION=APPEND

### Standby Database側
$ sqlplus /nolog
SQL> -- Standby Database(osaka)をPhysical Standbyモードへ戻す
Shutdown immediate
Startup mount
alter database convert to physical standby ;
alter database recover managed standby database ;

 

前提条件としては、Data GuardのPhysical Standby Database側でFlashback Loggingを有効化しておけば良いだけです。

簡単な流れとしては、Flashback DatabaseでStandby Databaseを障害発生前(例えば、TRUNCATE処理の前)まで巻き戻し、データ・ポンプ・エクスポート・ユーティリティで対象表のデータを抽出します。そのダンプファイルをPrimary Database側へインポートすれば終わりです。注意点として、データ・ポンプ・エクスポート・ユーティリティを使用する為にはデータベースへ書込み可能な状態でなければならない為、Physical StandbyモードからSnapshot Standbyモードへ切り替えている点がですかね。Data GuardのStandby Database側を有効活用する一つの例としてご検討して頂けると、Data Guard好きな私としては嬉しい限りです。

さて、Oracle Database 12cの表単位のリカバリは如何でしたでしょうか?リカバリ範囲を極小化することで業務影響も極小化するというRecovery Managerの思想(私が勝手に思っている)に則った素晴らしい機能拡張だと私は思います。過去の時点に戻せるのは当たり前です。RMANはその先を行きましたよね?「TRUNCATEされたレコードを元に戻す」だけではなく、「TRUNCATE後にINSERTされたレコードも保持すること」という二つの要件を同時に満たすリカバリを簡単に実行することが出来るのは、Recovery Managerの大きな特徴です。障害範囲によっては表領域単位での不完全リカバリ(TSPITR)も有効なシーンがありますので、合わせて覚えておいて下さいね。もちろん、障害が無いことが一番だと思いますが、万が一の障害時にどれだけスピーディーに正確にリカバリ手順を示せるか?実行出来るのか?は、日頃からの訓練が問われると思いますので、是非、様々なリカバリ方法を経験しておくことをお薦めします。

今回も最後までお付き合い頂きましてありがとうございました。是非、感想や質問をお待ちしておりますね。次回以降もどうぞよろしくお願い致します。


ページトップへ戻る▲

 

しばちょう先生の試して納得!DBAへの道 indexページ▶▶