【Oracle】データファイルを別ディレクトリに移動する方法|12c MOVE DATAFILE・OFFLINE RENAME・REDO ログ・TEMP ファイルまで解説

【Oracle】データファイルを別ディレクトリに移動する方法|12c MOVE DATAFILE・OFFLINE RENAME・REDO ログ・TEMP ファイルまで解説 Oracle

ディスクの容量整理、高速ストレージへの移行、RAID 構成の変更などでデータファイルの物理的な場所を変更する必要が生じることがあります。Oracle 12c 以降ではオンライン(DB 稼働中)で移動でき、ダウンタイムなしで作業できます。

本記事では、12c MOVE DATAFILE(オンライン移動)、11g 以前の OFFLINE 方式REDO ログ / TEMP / 制御ファイルの移動手順まで解説します。

この記事でわかること
・12c ALTER DATABASE MOVE DATAFILE でオンライン移動する方法
・11g 以前の OFFLINE → OS コピー → RENAME FILE 方式
・REDO ログファイルの移動手順
・TEMP ファイルの移動手順
・制御ファイルの移動手順
・移動前後の確認 SQL
・2 方式のダウンタイム比較
スポンサーリンク

2 つの移動方式の比較

方式 バージョン ダウンタイム 手順
MOVE DATAFILE 12c 以降 なし(オンライン) 1 コマンドで完結
OFFLINE + RENAME 全バージョン あり(表領域 OFFLINE 中) OFFLINE → OS コピー → RENAME → ONLINE
12c 以降なら MOVE DATAFILE 一択
DB を稼働させたまま 1 コマンドでデータファイルを移動でき、DML もブロックされません。11g 以前では表領域を OFFLINE にする必要があるためダウンタイムが発生します。

12c MOVE DATAFILE(オンライン移動)

SQL(12c: オンラインでデータファイルを移動)
-- データファイルを別ディレクトリに移動(DB 稼働中に実行可能)
ALTER DATABASE MOVE DATAFILE
    '/oracle/oradata/ORCL/users01.dbf'
    TO '/oracle/new_disk/users01.dbf';

-- ファイル番号でも指定可能
ALTER DATABASE MOVE DATAFILE 4
    TO '/oracle/new_disk/users01.dbf';

-- 移動後の確認
SELECT file_name, tablespace_name FROM dba_data_files
WHERE tablespace_name = 'USERS';
SQL(KEEP オプション: 元ファイルを残す)
-- KEEP: 移動後に元ファイルを削除しない(コピー扱い)
ALTER DATABASE MOVE DATAFILE
    '/oracle/oradata/ORCL/users01.dbf'
    TO '/oracle/new_disk/users01.dbf'
    KEEP;

-- KEEP なし(デフォルト): 移動完了後に元ファイルは自動削除
オプション 動作
デフォルト(KEEP なし) 移動完了後に元ファイルを自動削除
KEEP 元ファイルを残す(バックアップとして保持)
REUSE 移動先に同名ファイルが既にある場合に上書き
MOVE DATAFILE は Enterprise Edition 専用(12c R1)
12c R1 では Enterprise Edition のみ利用可能です。12c R2 以降では Standard Edition でも使えるようになりました。バージョンとエディションを確認してから実行してください。
SQL(複数ファイルの一括移動: PL/SQL)
-- 特定の表領域の全データファイルを新ディレクトリに移動
BEGIN
    FOR rec IN (
        SELECT file_name FROM dba_data_files
        WHERE tablespace_name = 'USERS'
    ) LOOP
        EXECUTE IMMEDIATE
            'ALTER DATABASE MOVE DATAFILE ''' || rec.file_name || '''
             TO ''/oracle/new_disk/' || SUBSTR(rec.file_name, INSTR(rec.file_name, '/', -1) + 1) || '''';
    END LOOP;
END;
/

11g 以前: OFFLINE + OS コピー + RENAME

SQL(OFFLINE 方式の完全手順)
-- (1) 表領域を OFFLINE にする
ALTER TABLESPACE users OFFLINE;

-- (2) OS でファイルをコピー
-- $ cp /oracle/oradata/ORCL/users01.dbf /oracle/new_disk/users01.dbf

-- (3) 制御ファイル内のパスを更新
ALTER DATABASE RENAME FILE
    '/oracle/oradata/ORCL/users01.dbf'
    TO '/oracle/new_disk/users01.dbf';

-- (4) 表領域を ONLINE に戻す
ALTER TABLESPACE users ONLINE;

-- (5) 元ファイルを削除(確認後)
-- $ rm /oracle/oradata/ORCL/users01.dbf

-- (6) 確認
SELECT file_name FROM dba_data_files WHERE tablespace_name = 'USERS';
SYSTEM / UNDO 表領域は OFFLINE にできない
SYSTEM / SYSAUX / UNDO 表領域は OFFLINE にできないため、この方式では移動できません。これらの表領域を移動するには DB を SHUTDOWNSTARTUP MOUNT で MOUNT モードにしてから RENAME する必要があります。12c 以降の MOVE DATAFILE なら SYSTEM / SYSAUX もオンラインで移動可能です。
SQL(SYSTEM 表領域の移動: DB MOUNT モード)
-- SYSTEM / SYSAUX / UNDO を移動する場合(全バージョン)

-- (1) DB を停止
SQL> SHUTDOWN IMMEDIATE;

-- (2) OS でファイルをコピー
-- $ cp /oracle/oradata/ORCL/system01.dbf /oracle/new_disk/system01.dbf

-- (3) MOUNT モードで起動
SQL> STARTUP MOUNT;

-- (4) RENAME
SQL> ALTER DATABASE RENAME FILE
    '/oracle/oradata/ORCL/system01.dbf'
    TO '/oracle/new_disk/system01.dbf';

-- (5) OPEN
SQL> ALTER DATABASE OPEN;

-- (6) 元ファイルを削除
-- $ rm /oracle/oradata/ORCL/system01.dbf

REDO ログファイルの移動

REDO ログファイルは表領域のデータファイルとは異なり、ALTER DATABASE MOVE DATAFILE では移動できません。DB を MOUNT モードにして RENAME します。

SQL(REDO ログファイルの移動)
-- (1) 現在の REDO ログファイルを確認
SELECT group#, member FROM v$logfile ORDER BY group#;

-- (2) DB を停止
SQL> SHUTDOWN IMMEDIATE;

-- (3) OS でファイルをコピー
-- $ cp /oracle/oradata/ORCL/redo01.log /oracle/new_disk/redo01.log
-- $ cp /oracle/oradata/ORCL/redo02.log /oracle/new_disk/redo02.log
-- $ cp /oracle/oradata/ORCL/redo03.log /oracle/new_disk/redo03.log

-- (4) MOUNT モードで起動
SQL> STARTUP MOUNT;

-- (5) RENAME
SQL> ALTER DATABASE RENAME FILE
    '/oracle/oradata/ORCL/redo01.log' TO '/oracle/new_disk/redo01.log';
SQL> ALTER DATABASE RENAME FILE
    '/oracle/oradata/ORCL/redo02.log' TO '/oracle/new_disk/redo02.log';
SQL> ALTER DATABASE RENAME FILE
    '/oracle/oradata/ORCL/redo03.log' TO '/oracle/new_disk/redo03.log';

-- (6) OPEN
SQL> ALTER DATABASE OPEN;

-- (7) 確認
SELECT group#, member FROM v$logfile ORDER BY group#;

TEMP ファイルの移動

TEMP ファイルの移動は「DROP + 再作成」が最もシンプルです。TEMP は一時データのため、RENAME する必要はありません。

SQL(TEMP ファイルの移動: DROP + 再作成)
-- (1) 別の TEMPFILE を追加
ALTER TABLESPACE temp ADD TEMPFILE
    '/oracle/new_disk/temp01.dbf' SIZE 1G AUTOEXTEND ON;

-- (2) 旧 TEMPFILE を DROP
ALTER TABLESPACE temp DROP TEMPFILE '/oracle/oradata/ORCL/temp01.dbf';

-- (3) 確認
SELECT file_name FROM dba_temp_files;
TEMP ファイルはバックアップ不要・RENAME 不要
TEMP は一時データしか格納しないため、DROP + 新規作成が最もシンプルです。DB 稼働中に実行でき、ダウンタイムは発生しません。

制御ファイルの移動

SQL(制御ファイルの移動)
-- (1) 現在の制御ファイルのパスを確認
SQL> SHOW PARAMETER control_files;

-- (2) SPFILE のパラメータを変更
SQL> ALTER SYSTEM SET control_files=
    '/oracle/new_disk/control01.ctl',
    '/oracle/fra/ORCL/control02.ctl'
    SCOPE=SPFILE;

-- (3) DB を停止
SQL> SHUTDOWN IMMEDIATE;

-- (4) OS で制御ファイルをコピー
-- $ cp /oracle/oradata/ORCL/control01.ctl /oracle/new_disk/control01.ctl

-- (5) DB を起動
SQL> STARTUP;

-- (6) 確認
SELECT name FROM v$controlfile;

移動前後の確認 SQL

SQL(移動前に全ファイルのパスを記録)
-- データファイル
SELECT 'DATAFILE' AS type, file_name, tablespace_name FROM dba_data_files
UNION ALL
-- TEMP ファイル
SELECT 'TEMPFILE', file_name, tablespace_name FROM dba_temp_files
UNION ALL
-- REDO ログ
SELECT 'REDO', member, TO_CHAR(group#) FROM v$logfile
UNION ALL
-- 制御ファイル
SELECT 'CONTROL', name, NULL FROM v$controlfile
ORDER BY 1, 2;
SQL(移動後の検証: ファイルが正しいパスにあるか)
-- データファイルのステータス確認
SELECT file#, name, status FROM v$datafile ORDER BY file#;
-- status = ONLINE / SYSTEM / RECOVER(正常は ONLINE か SYSTEM)

-- ファイルの物理的な存在を V$DATAFILE_HEADER で確認
SELECT file#, name, status, error FROM v$datafile_header;
-- error が空欄ならファイルは正常に読み取り可能

ファイル種類別の移動方法まとめ

ファイル種類 12c 以降 11g 以前 DB 停止
データファイル(通常表領域) MOVE DATAFILE(オンライン) OFFLINE → コピー → RENAME → ONLINE 12c: 不要 / 11g: 表領域 OFFLINE 中
データファイル(SYSTEM / SYSAUX / UNDO) MOVE DATAFILE(オンライン) SHUTDOWN → MOUNT → RENAME → OPEN 12c: 不要 / 11g: DB 停止
REDO ログファイル SHUTDOWN → MOUNT → RENAME → OPEN 同左 DB 停止
TEMP ファイル ADD TEMPFILE → DROP TEMPFILE 同左 不要(オンライン)
制御ファイル SPFILE 変更 → SHUTDOWN → コピー → STARTUP 同左 DB 停止
12c MOVE DATAFILE は REDO ログ / 制御ファイルには使えない
MOVE DATAFILE はデータファイル専用です。REDO ログと制御ファイルは従来通り DB を MOUNT モードにして RENAME する必要があります。TEMP ファイルは DROP + 再作成が最速です。

実務パターン集

パターン(1): 12c で全データファイルを新ディスクに移動

SQL
-- 新ディスク /oracle/ssd/ に全データファイルを移動
BEGIN
    FOR rec IN (
        SELECT file_name,
               REPLACE(file_name, '/oracle/oradata/ORCL/', '/oracle/ssd/') AS new_name
        FROM dba_data_files
        WHERE file_name LIKE '/oracle/oradata/ORCL/%'
    ) LOOP
        EXECUTE IMMEDIATE
            'ALTER DATABASE MOVE DATAFILE ''' || rec.file_name || ''' TO ''' || rec.new_name || '''';
        DBMS_OUTPUT.PUT_LINE('Moved: ' || rec.file_name || ' -> ' || rec.new_name);
    END LOOP;
END;
/

パターン(2): 11g で特定表領域のファイルを移動

SQL
-- (1) OFFLINE
ALTER TABLESPACE app_data OFFLINE;

-- (2) OS コピー
-- $ cp /oracle/disk1/app_data01.dbf /oracle/disk2/app_data01.dbf

-- (3) RENAME
ALTER DATABASE RENAME FILE
    '/oracle/disk1/app_data01.dbf'
    TO '/oracle/disk2/app_data01.dbf';

-- (4) ONLINE
ALTER TABLESPACE app_data ONLINE;

パターン(3): 全 REDO ログを新ディスクに移動

SQL
-- MOUNT モードで全 REDO ログを移動
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;

-- OS コピー + RENAME(ログファイルごとに実行)
ALTER DATABASE RENAME FILE '/oracle/oradata/ORCL/redo01.log' TO '/oracle/ssd/redo01.log';
ALTER DATABASE RENAME FILE '/oracle/oradata/ORCL/redo02.log' TO '/oracle/ssd/redo02.log';
ALTER DATABASE RENAME FILE '/oracle/oradata/ORCL/redo03.log' TO '/oracle/ssd/redo03.log';

ALTER DATABASE OPEN;

パターン(4): TEMP ファイルを SSD に移動

SQL
-- SSD に新 TEMPFILE を作成して旧ファイルを DROP
ALTER TABLESPACE temp ADD TEMPFILE '/oracle/ssd/temp01.dbf'
    SIZE 2G AUTOEXTEND ON NEXT 200M MAXSIZE 10G;
ALTER TABLESPACE temp DROP TEMPFILE '/oracle/oradata/ORCL/temp01.dbf';

よくある質問

QMOVE DATAFILE 中に DML はブロックされますか?
Aブロックされません。12c の ALTER DATABASE MOVE DATAFILE はオンラインで実行され、移動中もテーブルへの INSERT / UPDATE / DELETE / SELECT は通常通り継続できます。
QMOVE DATAFILE は Standard Edition で使えますか?
A12c R1 では Enterprise Edition のみです。12c R2 以降では Standard Edition でも使えます。バージョンを確認してください。11g 以前では OFFLINE 方式を使います。
QREDO ログファイルも MOVE DATAFILE で移動できますか?
Aできません。MOVE DATAFILE はデータファイル専用です。REDO ログファイルは DB を SHUTDOWN → STARTUP MOUNT してから ALTER DATABASE RENAME FILE で移動します。
Q移動先のディレクトリの権限は何が必要ですか?
AOracle プロセスの OS ユーザー(通常 oracle)に読み書き権限が必要です。移動先ディレクトリが存在し、oracle ユーザーが書き込めることを事前に確認してください。
QMOVE DATAFILE に失敗した場合はどうなりますか?
A移動が完了するまで元のファイルは保持されるため、データが失われることはありません。エラーが発生した場合は元のファイルがそのまま使用されます。エラーの原因(ディスク空き不足、権限不足等)を修正してリトライしてください。
QASM 環境でもファイルを移動できますか?
Aはい。12c の MOVE DATAFILE は ASM ディスクグループ間の移動にも対応しています。ALTER DATABASE MOVE DATAFILE '+DATA/...' TO '+DATA2/...' のように指定します。

まとめ

データファイルの移動方法をまとめます。

やりたいこと 方法
データファイルをオンラインで移動(12c+) ALTER DATABASE MOVE DATAFILE ‘/old/file.dbf’ TO ‘/new/file.dbf’
データファイルを移動(11g 以前) OFFLINE → OS コピー → ALTER DATABASE RENAME FILE → ONLINE
SYSTEM / UNDO を移動(11g) SHUTDOWN → STARTUP MOUNT → RENAME → OPEN
REDO ログを移動 SHUTDOWN → STARTUP MOUNT → OS コピー → RENAME → OPEN
TEMP ファイルを移動 ADD TEMPFILE(新パス)→ DROP TEMPFILE(旧パス)
制御ファイルを移動 ALTER SYSTEM SET control_files(SPFILE) → SHUTDOWN → OS コピー → STARTUP
全データファイルを一括移動 PL/SQL で dba_data_files をループして MOVE DATAFILE

データファイルの追加は「データファイルを追加・変更する方法」、表領域全般は「表領域(Tablespace)完全ガイド」も併せて参照してください。