しばちょう先生の試して納得!DBAへの道 indexページ▶▶
みなさん、こんにちは。”しばちょう”こと柴田長(しばた つかさ)です。
いやー時間が経つのは本当に早いですねー。7/1に開催されたOracle Database Technology Night ~集え!オラクルの力(チカラ)~でお話させて頂いたばかりだと思っていたら第三回(9/5)の開催が迫って来ているでは無いですか。。。こちらの原稿を書き終えたら直ぐにそちらの資料の作成に取り掛からなくてはーと、いつものことながら一人で慌てています。

※ Oracle Database Technology Nightは7/1を皮切りに、今後ほぼ毎月一回のペースで日本オラクルが誇る技術者陣が現場で今すぐ使える技術情報を皆様にお届けさせて頂く予定です。また、皆様からのご質問にダイレクトに回答させて頂いたり、ディスカッションさせて頂ければと考えております。是非、皆さんとDatabase Technologyを盛り上げていきたいと思いますので、ご参加のほどよろしくお願い致します。次回の9/5(月)では、私がASMについて語らせて頂く予定です。(申し込みはこちら)
さて今回は、オンライン・データファイルの移動を体験して頂きましょう。えっ?オンラインで?データファイルを移動?どうやって?と思わざるを得ない機能ですよね。不思議でなりません。この機能はOracle Database 12c Release1から実装された機能であり、以前のバージョンでは表領域を一時的にオフライン状態にしたり、もしくは、インスタンスがマウント・モードの状態で作業を実施したりする必要がありました。もちろん、「表のオンライン再定義」を使えば、業務処理にホトンド影響無く表を移動することは出来ることは何度かご紹介させて頂いてきましたが、オンラインでデータファイルを移動したい!という要望には応えられていませんでしたね。本当に動くのか?と言うところから幾つかのTIPSを交えて、今回もお届けさせて頂きますね!以下の演習をOracle Database 12c Release 12.1.0.2 のデータベースで試してみてください。
なお、Oracle Database 12c Release 1 (12.1.0.2) の単一インスタンス・データベースのインストレーション・ガイド 及び、Oracle VM VirtualBoxを用いたOracle Database 12c Release 1 環境の構築ガイドが、Oracle Technology Networkのこちらのページに公開されておりますので、参考にしてみてください。
- 【今回ご紹介するネタ一覧(逆引き)】
- ✓ レイヤー毎のデータ移動方法(演習2)
- ✓ オフライン・データファイルの移動(演習3)
- ✓ オンライン・データファイルの移動(演習4)
- ✓ オンライン・データファイルの移動と更新処理(演習5)
- ✓ オンライン・データファイルの移動とバッファ・キャッシュの関係(演習6)
- ✓ alter database move文のKEEP句(演習7)
1. ASMディスク・グループ”+DATA”上の1GBのデータファイル一つで構成される表領域”TBS47″を作成し、その表領域上に約200MBの表”TAB47″と索引を作成して下さい。
$ sqlplus / as sysdba
SQL>
-- 表領域の作成
create tablespace TBS47 datafile '+DATA(DATAFILE)' size 1g uniform size 1m ;
set pages 5000 linesize 150
col TABLESPACE_NAME for a10
col FILE_NAME for a50
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +DATA/ORCL/DATAFILE/tbs47.263.920524989
-- その表領域をデフォルト表領域とするユーザーの作成
create user TRY identified by TRY12345 default tablespace TBS47 ;
grant CONNECT, RESOURCE, DBA to TRY ;
-- 表の作成とデータ・ローディング
connect TRY/TRY12345
create table TAB47 (COL1 number, COL2 date, COL3 char(1000));
insert /*+append */ into TAB47 select LEVEL, SYSDATE, 'hoge'
from dual connect by LEVEL <=7*128*200 ;
commit ;
alter table TAB47 add primary key (COL1) ;
create index IDX_TAB47_COL3 on TAB47(COL3) ;
set linesize 120 pages 500
col SEGMENT_NAME for a20
select SEGMENT_NAME, SEGMENT_TYPE, BYTES/1024/1024 from USER_SEGMENTS ;
SEGMENT_NAME SEGMENT_TYPE BYTES/1024/1024
-------------------- ------------------ ---------------
TAB47 TABLE 202
SYS_C005878 INDEX 3
IDX_TAB47_COL3 INDEX 231
さて、こちらの演習は何も問題無いでしょう。過去の記事でも解説していますので、今回の解説は完全に省略させて頂きますね。
2. もし高速なディスクを利用可能になった場合に、そのデバイス上に既存のデータを移動する方法案をオンラインでの実施有無も含めて検討して下さい。

如何でしょうか?皆さんはいくつ思いつきましたか?
もう少し綺麗に整理したかったのですが、ひとまずこの表で許して下さい。Oracle Databaseでは複数の階層(Level)でのデータ移動を実現する機能が実装されており、要件・範囲において適切な階層(Level)での移動方法を選択することが可能であることが上記の表からご理解頂けると思います。一つの表を移動するだけであればオンライン再定義を使用すれば良いですが、何十、何百と言う数の表を移動する場合には不便なので表領域単位(データファイル単位)で移動をさせたくなる気持ちが分かりますよね。と言う事で、今回の連載で扱う「オンライン・データファイルの移動」= alter database move datafile文が欲しくなります!!
と、その前に、次の演習3にて「オフライン・データファイルの移動」=alter tablespace rename datafile文を復習しておきましょう。
3. Oracle Database 11g Release2を想定し、オフライン・データファイルの移動を試してみましょう。TBS47表領域のデータファイルを別のASMディスク・グループ上へ移動(+DATA –> +FRA)して下さい。
-- 移動対象データファイルを含む表領域のオフライン化
$ sqlplus /nolog
SQL> connect / as sysdba
alter tablespace TBS47 offline normal ;
set pages 5000 linesize 150
col TABLESPACE_NAME for a10
select TABLESPACE_NAME, STATUS from DBA_TABLESPACES where TABLESPACE_NAME = 'TBS47' ;
TABLESPACE STATUS
---------- ---------
TBS47 OFFLINE
col FILE_NAME for a50
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +DATA/ORCL/DATAFILE/tbs47.263.920524989
-- asmcmdユーティリティで対象ASMファイル(データファイル)のコピー
$ asmcmd
ASMCMD>
mkdir +FRA/ORCL/DATAFILE
cp +DATA/ORCL/DATAFILE/tbs47.263.920524989 +FRA/ORCL/DATAFILE/tbs47.dbf
copying +DATA/ORCL/DATAFILE/tbs47.263.920524989 -> +FRA/ORCL/DATAFILE/tbs47.dbf
cd +FRA/ORCL/DATAFILE
ls -lt
Type Redund Striped Time Sys Name
DATAFILE UNPROT COARSE AUG 22 05:00:00 N tbs47.dbf => +FRA/ASM/DATAFILE/tbs47.dbf.355.920525789
-- データベースの制御ファイル内のポインタを変更後にオンライン化
$ sqlplus /nolog
SQL> connect / as sysdba
alter tablespace TBS47
rename datafile '+DATA/ORCL/DATAFILE/tbs47.263.920524989'
to '+FRA/ORCL/DATAFILE/tbs47.dbf' ;
alter tablespace TBS47 online ;
select TABLESPACE_NAME, STATUS from DBA_TABLESPACES where TABLESPACE_NAME = 'TBS47' ;
TABLESPACE STATUS
---------- ---------
TBS47 ONLINE
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +FRA/ORCL/DATAFILE/tbs47.dbf
はい、こちらは基本的にはマニュアル通りのオペレーションで問題無く実行出来たかと思います。(Oracle Database管理者ガイド 12cリリース1 (12.1) 14 データファイルおよび一時ファイルの管理 オフライン・データファイルの名前変更と再配置)
まず、移動対象のデータファイルを含む表領域全体を「alter tablespace」文にてオフライン化します。この作業によって、その表領域の全てのデータファイルへの変更が不可能となりますので、業務処理を一時的に停止する調整を行わなければならないでしょう。また、Oracleデータベースから更新不可にするからこそ、より下の層(例えばOSレベル)で対象のデータファイルをコピーして移動することが可能にもなるのですね。
今回の検証環境はASM環境でしたので、ASMCMDユーティリティを使用してASMファイル(= データファイル)をASMディスク・グループ”+DATA”上から”+FRA”上へコピーしています。
少々クセのあるユーティリティですので、色々試して頂ければと思います。一点お伝えしておくと、今回は「+FRA/ORCL/DATAFILE/tbs47.dbf」へコピーするコマンドを実行していますが、実は・・・OSで言う所のシンボリック・リンクであるASMエイリアス名として「+FRA/ORCL/DATAFILE/tbs47.dbf」が作成されており、実態として作成されたASMファイル「+FRA/ASM/DATAFILE/tbs47.dbf.355.920525789」にリンクされていることが、ASMCMDユーティリティの「ls –lコマンド」で確認することが可能です。
次に、「alter tablespace rename datafile (移動元データファイルのフルパス) to (移動先データファイルのフルパス) ;」を実行して、制御ファイル内のポインタ情報を書き換えます。イメージとしては、FILE_ID=3のデータファイルのフルパスをxxxxへ変更しています。と言う事は、DBA_DATA_FILESビューの出力結果からも理解し易いかと思います。
最後に、作業の為にオフライン化していた表領域をオンライン化して完了です。
よって、この従来のオフライン・データファイルの移動方法では、データファイルをコピーしている間は表領域をオフライン状態にしておく必要がありますので、データファイルのサイズが大きくなったり個数が増えたりすれば、メンテナンス時間が長時間化することが懸念されますね。
ちなみに、上記のオペレーションを全て実行した後、元のデータファイル(= ASMファイル)がゴミとして残ってしまっているのでは?と気付いた方は非常に注意力の高い方だと思います。と言う事で、ASMCMDユーティリティの「rm」コマンドで消去を試行すると?実は、既に消えているのですね。このような動作になることを知っているのと知らないのとでは大きな違いなのですが、実機を触っていないと知れない部分だと思います。
-- 移動元のASMファイル(データファイル)を消そうとすると既に無い $ asmcmd ASMCMD> rm +DATA/ORCL/DATAFILE/tbs47.263.920524989 ASMCMD-8002: entry 'tbs47.263.920524989' does not exist in directory '+DATA/ORCL/DATAFILE/'
前置きが長くなりましたが、いよいよ、Oracle Database 12c Release1の新機能である、オンライン・データファイルの移動を試してみましょう。まずは演習4でコマンドを把握しましょう。
4. Oracle Database 12c Release1から使用可能となった、オンライン・データファイルの移動を試してみましょう。TBS47表領域のデータファイルを別のASMディスク・グループ上へ移動(+FRA –> +DATA)して下さい。
$ sqlplus /nolog
SQL> connect / as sysdba
set pages 5000 linesize 150
col TABLESPACE_NAME for a10
col FILE_NAME for a50
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +FRA/ORCL/DATAFILE/tbs47.dbf
alter database move datafile 3 to '+DATA(DATAFILE)' ;
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +DATA/ORCL/DATAFILE/tbs47.263.920526109
いやー素晴らしく簡単ですね!!
まずは、alter database move datafile文を理解する為に、Oracle Database SQL言語リファレンス 12cリリース1 (12.1) を参照するクセを付けておきましょう。今回は、ALTER DATABASE文の「move_datafile_clause::=」句ですね。
実行する為に必要な情報は、移動するデータファイル番号or データファイルのフルパスですから、今回はDBA_DATA_FILESビューを参照してみています。後は、その情報を含めて実行するだけですね。演習3で復習したオフライン・データファイルの移動では、対象表領域をオフライン化する等、色々と面倒な作業が多い印象でしたが、非常にシンプルに実行出来てしまいますよね。
しかし、この演習だけでは本当にオンラインで移動できているのか?という疑問は残りますね。データベース・インスタンスはオープン状態で表領域もオンライン状態なのは分かったけど、コマンド実行中は、結局、表に対して更新処理が実行出来ないんじゃないの?と疑い深い事が良いDBAでもあると私は勝手に思っているので、そういう人、好きです(笑)
と言う事で、次の演習に行ってみましょう!
5. オンライン・データファイルの移動中に、TAB47表に対してINSERT処理を行う事が可能であるのかを実機で確認して下さい。
$ sqlplus /nolog
SQL> -- sessionA
connect TRY/TRY12345
set timing on time on
-- 0.1秒間に一件INSERT+コミットするPL/SQL(約1分間継続)
begin
for i in 10000001..10000600 loop
insert into TAB47 values(i,SYSDATE, 'sibacho');
commit;
DBMS_LOCK.SLEEP(0.1);
end loop;
end;
/
$ sqlplus /nolog
SQL> -- sessionB
connect / as sysdba
set timing on time on
set pages 5000 linesize 150
col TABLESPACE_NAME for a10
col FILE_NAME for a50
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +DATA/ORCL/DATAFILE/tbs47.263.920526109
05:43:50 SQL> alter database move datafile 3 to '+FRA(DATAFILE)' ;
Database altered.
Elapsed: 00:00:29.61
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +FRA/ORCL/DATAFILE/tbs47.355.920526231
上記では、TBS47表領域のデータファイルに対してalter database move datafile文を実行する前に、別のセッション(sessionA)からTBS47表領域上のTAB47表へ0.1秒に1件INSERTするPL/SQLの実行を開始しています。また上記の実行結果から、alter database move datafile文は5時43分50秒に開始して約29秒間で完了していることが確認できるかと思います。
と言う事を頭に入れた上で、MOVE中にINSERTされたTAB47表のレコード数を確認してみましょう。
$ sqlplus /nolog SQL> connect TRY/TRY12345 set linesize 150 pages 5000 select to_char(COL2, 'HH24:MI:SS'), min(COL1), max(COL1), count(*) from TAB47 where COL1 >= 10000001 group by COL2 order by 1 ; TO_CHAR( MIN(COL1) MAX(COL1) COUNT(*) -------- ---------- ---------- ---------- 05:43:45 10000005 10000014 10 05:43:46 10000015 10000024 10 05:43:47 10000025 10000033 9 05:43:48 10000034 10000043 10 05:43:49 10000044 10000053 10 05:43:50 10000054 10000062 9 <-- Begin Time 05:43:51 10000063 10000072 10 05:43:52 10000073 10000082 10 05:43:53 10000083 10000091 9 05:43:54 10000092 10000101 10 05:43:55 10000102 10000110 9 05:43:56 10000111 10000120 10 05:43:57 10000121 10000129 9 05:43:58 10000130 10000139 10 05:43:59 10000140 10000149 10 05:44:00 10000150 10000158 9 05:44:01 10000159 10000168 10 05:44:02 10000169 10000178 10 05:44:03 10000179 10000187 9 05:44:04 10000188 10000197 10 05:44:05 10000198 10000207 10 05:44:06 10000208 10000216 9 05:44:07 10000217 10000226 10 05:44:08 10000227 10000236 10 05:44:09 10000237 10000245 9 05:44:10 10000246 10000255 10 05:44:11 10000256 10000265 10 05:44:12 10000266 10000274 9 05:44:13 10000275 10000284 10 05:44:14 10000285 10000294 10 05:44:15 10000295 10000303 9 05:44:16 10000304 10000313 10 05:44:17 10000314 10000323 10 05:44:18 10000324 10000332 9 05:44:19 10000333 10000342 10 <-- End Time 05:44:20 10000343 10000352 10 05:44:21 10000353 10000362 10 05:44:22 10000363 10000372 10 05:44:23 10000373 10000381 9 05:44:24 10000382 10000391 10 05:44:25 10000392 10000401 10
さて、如何でしょうか?
alter database move datafile文を実行する前(05:43:50の前)、実行中(05:43:50 ~ 05:44:19の間)、実行後(05:44:19以降)の3つのフェーズに区切ってみても、秒間にINSERTされたレコード件数は9件 or 10件で傾向に違いはありません。PL/SQL文を見て頂くとご理解頂けますが、一件INSERT+COMMITする度に0.1秒間スリープさせている為、1秒間で9件しかINSERT出来ないタイミングが定期的に生まれてしまうのは私のPL/SQLのせいですね。スイマセン。もう少し上手にお見せ出来れば良いのですが・・・
とは言え、データファイルを移動中にもINSERT+COMMIT処理を受け付けていることは一目瞭然ですよね。素晴らしいです!
しかーし、ここで検証を終わらせてはなりません。より実際のデータベース運用を想定した検証を継続させる必要があるのです。例えば、バッチ処理のような大量データ・ロード処理とブツケテみるとかですが、ディスクのI/O性能の観点からは、バッチ処理とデータファイルの移動がバッティングしないようにDBAが制御した方が良いとは思います。と言う事で、今回の連載で最後に扱う検証は、オンライン・データファイルの移動がバッファ・キャッシュ上のキャッシュ・データに与える影響です!!
データファイルの移動によって、当たり前ですがデータファイルの場所が変更されます。と言う事は、移動前にバッファ・キャッシュ上にキャッシュされていたブロックは一旦クリアされてしまうのでは?つまり、一時的にキャッシュ・ヒット率が下がってしまうのでは?と私は疑問に思ったのです。疑問に思ったら検証するしかないですよ!!
6. オンライン・データファイルの移動前にバッファ・キャッシュ上にキャッシュされていたブロックが、移動後にも残っているのか否かを確認して下さい。
-- 検証目的の為、インスタンスを再起動してバッファ・キャッシュをクリア
$ srvctl stop database -db orcl -stopoption IMMEDIATE
$ srvctl start database -db orcl
$ sqlplus /nolog
SQL>
-- 移動対象のデータファイル上に格納されている索引を明示的にキャッシュ
connect TRY/TRY12345
select /*+index_ffs(T, IDX_TAB47_COL3) */ count(COL3) from TAB47 T;
-- キャッシュされたブロックの確認
connect / as sysdba
set pages 5000 lines 100
col OWNER for a8
col OBJECT_NAME for a16
select O.OWNER, O.OBJECT_NAME, B.STATUS, count(*)
from V$BH B, DBA_OBJECTS O
where B.OBJD = O.DATA_OBJECT_ID and O.OWNER = 'TRY'
group by O.OWNER, O.OBJECT_NAME, rollup(B.STATUS) ;
OWNER OBJECT_NAME STATUS COUNT(*)
-------- ---------------- ---------- ----------
TRY IDX_TAB47_COL3 xcur 29487
TRY IDX_TAB47_COL3 29487
-- オンライン・データファイルの移動
connect / as sysdba
set pages 5000 linesize 150
col TABLESPACE_NAME for a10
col FILE_NAME for a50
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +FRA/ORCL/DATAFILE/tbs47.355.920526231
alter database move datafile 3 to '+DATA(DATAFILE)' ;
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +DATA/ORCL/DATAFILE/tbs47.263.920526657
-- キャッシュされたブロックの確認
connect / as sysdba
select O.OWNER, O.OBJECT_NAME, B.STATUS, count(*)
from V$BH B, DBA_OBJECTS O
where B.OBJD = O.DATA_OBJECT_ID and O.OWNER = 'TRY'
group by O.OWNER, O.OBJECT_NAME, rollup(B.STATUS) ;
OWNER OBJECT_NAME STATUS COUNT(*)
-------- ---------------- ---------- ----------
TRY IDX_TAB47_COL3 xcur 29487
TRY IDX_TAB47_COL3 29487
バッファ・キャッシュ上にキャッシュされているオブジェクト(表や索引)のブロック数はV$BHビューで確認することが可能です。それさえ知っていれば、alter database move datafile文の前後でV$BHビューを確認すれば良いだと検証方法が思いつきますよね。そして、実行した結果が上記の回答例の通りです。如何でしょう?なんと信じられない事に、バッファ・キャッシュ上にキャッシュされていたブロックは、そのまま生き残って(キャッシュされたままの状態)いますね。これは本当に使い勝手が良さそうですね!
ちなみに、V$BH.STATUSの値の意味はきちんと理解しておくことをお薦めします。まずは、リファレンス・マニュアルを参照してみて下さいね。(あえて、直接リンクを張り付けないでおきますね)
7. (おまけ)alter database move文においてKEEP句を使用した場合の動きを確認しておきましょう。
$ sqlplus / as sysdba
SQL>
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +DATA/ORCL/DATAFILE/tbs47.263.920526657
-- ASM(ASMエイリアス無し)--> ASM(ASMエイリアス無し)
$ sqlplus / as sysdba
SQL> alter database move datafile 3 to '+FRA(DATAFILE)' keep ;
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +FRA/ORCL/DATAFILE/tbs47.355.920526807
$ asmcmd
ASMCMD> ls -l +DATA/ORCL/DATAFILE/tbs47.263.920526657
ASMCMD-8002: entry 'tbs47.263.920526657' does not exist in directory '+DATA/ORCL/DATAFILE/'
-- ASM(ASMエイリアス無し)--> ASM(ASMエイリアス有り)
$ sqlplus / as sysdba
SQL> alter database move datafile 3 to '+DATA/ORCL/DATAFILE/TBS47.dbf' keep ;
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +DATA/ORCL/DATAFILE/tbs47.dbf
$ asmcmd
ASMCMD> ls -l +FRA/ORCL/DATAFILE/tbs47.355.920526807
ASMCMD-8002: entry 'tbs47.355.920526807' does not exist in directory '+FRA/ORCL/DATAFILE/'
-- ASM(ASMエイリアス名有り)--> ASM(ASMエイリアス無し)
$ sqlplus / as sysdba
SQL> alter database move datafile 3 to '+FRA(DATAFILE)' keep ;
select FILE_ID, STATUS, TABLESPACE_NAME, FILE_NAME from DBA_DATA_FILES
where TABLESPACE_NAME = 'TBS47' ;
FILE_ID STATUS TABLESPACE FILE_NAME
---------- --------- ---------- ---------------------------------------
3 AVAILABLE TBS47 +FRA/ORCL/DATAFILE/tbs47.355.920527001
$ asmcmd
ASMCMD> ls -l +DATA/ORCL/DATAFILE/tbs47.dbf
Type Redund Striped Time Sys Name
DATAFILE MIRROR COARSE AUG 22 05:00:00 N tbs47.dbf => +DATA/ORCL/DATAFILE/TBS47.263.920526925
はい、こちらは準備ですので、解説は省略させて頂きますね。
はい、最後にalter database move datafile文に指定可能なKEEP句について、そのクセを理解しておきましょう。上述したSQLリファレンスでは次のような記載があります。「KEEP句指定すると、元のデータファイルがMOVE DATAFILE操作後に維持されるようになります。元のデータファイルがOracle Managed Fileの場合には、KEEPを指定できません。新しいデータファイルがOracle Managed Fileの場合には、KEEPを指定できます。」KEEP句で元のデータファイルを残すことが出来そうだけど、条件次第では出来ないこともありそうですね。その条件がAND条件なのか、OR条件なのか、どちらの条件が強いのかが記載からは分からないので、試してみた結果が上記の回答例となります。
ASM上にデータファイルを配置する場合は、基本的にはOracle Managed File(OMF)となります。「TBS47.263.920526925」のように、Oracleが自動的に生成した数字が埋め込まれています。このOMFで元のデータファイルが管理されている場合はKEEP句の効果はありません。この場合、たとえ新しいデータファイルがOMFであってもNGです。では、KEEP句の効果があるASM環境での「例外」は?と言うと、ASMエイリアス名を作成してASMファイル(データファイル)を管理している場合です。
これらを実機で検証した結果が上記の回答例ですので、参考にしてみて下さいね。(すいません、雑な解説で・・・)
さて、Oracle Database 12c Release1からの新機能であるオンライン・データファイルの移動を試して頂きましたが、如何でしたでしょうか?非常に興味深い機能であり、その内部動作が非常に気になりますよね。表レベルじゃなく、データファイルレベルで元と先のデータの同期をどのように取っているのか?知りたいですよね、本当に。演習では掲載しませんでしたが、こう言う場合にEvent 10046トレースを取得して確認してみるのも一つの分析方法です。ご興味があれば是非お試しくださいね。また、簡単ではありますが、私が新機能を試す場合に、どれだけ疑い深く一つずつ検証しているのかも少しだけお見せさせて頂いたつもりですので、少しでも参考になったのであれば幸いです。
今回も最後までお付き合い頂きましてありがとうございました。是非、感想や質問をお待ちしておりますね。次回以降もどうぞよろしくお願い致します。
