ディスクの容量整理、高速ストレージへの移行、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 方式のダウンタイム比較
・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 にする必要があるためダウンタイムが発生します。
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 でも使えるようになりました。バージョンとエディションを確認してから実行してください。
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 を
SYSTEM / SYSAUX / UNDO 表領域は OFFLINE にできないため、この方式では移動できません。これらの表領域を移動するには DB を
SHUTDOWN → STARTUP 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 稼働中に実行でき、ダウンタイムは発生しません。
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 + 再作成が最速です。
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)完全ガイド」も併せて参照してください。

