Oracle 表を読み取り専用にする方法と移動手順【ALTER TABLE】

Oracle Master Silver

Oracle Databaseの運用において、マスタデータの誤更新を防ぎたい、あるいはディスク容量の都合でテーブルを別の場所へ移したい場面は頻繁に訪れます。

本記事では、Oracle 表 読み取り専用モードへの変更方法と、表領域間でのOracle 表 移動の手順を、初心者にも分かりやすく解説します。特に表の移動時に発生する「インデックス無効化」への対処は必須知識ですので、ぜひマスターしてください。

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

この記事で分かること

  • 特定の表を「読み取り専用(Read Only)」にしてデータを保護する方法
  • ALTER TABLE MOVE コマンドで表を別の表領域へ移動する方法
  • 移動後に必須となる「インデックスの再構築」手順

結論:やりたいこと別・最短コマンドリスト

急いでいる方向けの「やることリスト」です。

  • 表を読み取り専用にする
    ALTER TABLE 表名 READ ONLY;
  • 表を書き込み可能に戻す
    ALTER TABLE 表名 READ WRITE;
  • 表を別の表領域へ移動する
    ALTER TABLE 表名 MOVE TABLESPACE 新表領域名;
  • 移動後にインデックスを直す(必須)
    ALTER INDEX インデックス名 REBUILD;

1. 基礎知識:読み取り専用と表の移動とは?

手順に入る前に、それぞれの機能がどのような仕組みで動いているか、一口メモで解説します。

読み取り専用モード (Read Only)

表に対してこの属性を設定すると、INSERT, UPDATE, DELETE などのDML(データ操作言語)が一切禁止されます。

  • メリット: アプリケーションのバグやオペレーションミスによるデータ消失・改変をデータベースレベルで防げます。
  • 注意: DROP TABLE(表の削除)などの一部のDDL(データ定義言語)は実行可能です。

表の移動 (Move Tablespace)

表の実体データを、物理的に異なる「表領域(保管場所)」へ再配置します。

  • メリット: 高速なディスクへ移動してパフォーマンスを上げる、満杯になった表領域から退避する、といったストレージ最適化が可能です。
  • 副作用: データの物理的な位置(ROWID)が変わるため、その表を指している**インデックスがすべて「使用不可(UNUSABLE)」**になります。

2. 実践手順:表の読み取り専用化と移動

ここからは実機(SQL*Plus等)で試せる手順です。

前提として、操作対象の表 EMPLOYEES が存在し、移動先の表領域 NEW_TABLESPACE を作成する流れで解説します。

2.1 事前準備(テストデータ作成)

まず、実験用の表とインデックスを作成し、データを投入します。

-- 前提: 適切な権限を持つユーザーで実行
-- テスト用テーブルの作成
CREATE TABLE employees (
    employee_id NUMBER PRIMARY KEY,
    name        VARCHAR2(50),
    salary      NUMBER
);

-- データの挿入
INSERT INTO employees VALUES (1, 'Alice', 5000);
INSERT INTO employees VALUES (2, 'Bob', 6000);
COMMIT;

2.2 表を読み取り専用に設定する

重要なデータを保護するため、表を読み取り専用に変更します。

1.設定コマンドの実行

ALTER TABLE employees READ ONLY;

2.動作確認データを削除しようとすると、エラーになることを確認します。

DELETE FROM employees WHERE employee_id = 1; 
-- 結果: ORA-12081: update operation not allowed on table "SCHEMA"."EMPLOYEES"

3.状態の確認SQL

SELECT table_name, read_only
FROM   user_tables
WHERE  table_name = 'EMPLOYEES';
SQL> SELECT * FROM employees;

EMPLOYEE_ID NAME SALARY
----------- -------------------- ----------
1 Alice 5000
2 Bob 6000

SQL> ALTER TABLE employees READ ONLY;

Table altered.

SQL> DELETE FROM employees WHERE employee_id = 1;
DELETE FROM employees WHERE employee_id = 1
*
ERROR at line 1:
ORA-12081: update operation not allowed on table "SCOTT"."EMPLOYEES"


SQL> SELECT table_name, read_only FROM user_tables
2 WHERE table_name = 'EMPLOYEES';

TABLE_NAME REA
-------------------- ---
EMPLOYEES YES ★READ ONLY

解除方法:

元に戻す場合は ALTER TABLE employees READ WRITE; を実行します。

2.3 表を新しい表領域へ移動する

次に、この表を別の表領域へ物理移動させます。

1.移動先表領域の作成
※パスは環境に合わせて変更してください(例はLinux環境)。Windowsの場合は C:\app\… 等になります。

CREATE TABLESPACE new_tablespace
DATAFILE '/u01/app/oracle/oradata/ORCL/new_tablespace.dbf' 
SIZE 50M 
AUTOEXTEND ON;

2.表の移動コマンド実行読み取り専用モードのままでも移動(DDL)は可能です。

ALTER TABLE employees MOVE TABLESPACE new_tablespace;

3.移動の確認

SELECT table_name, tablespace_name
FROM   user_tables
WHERE  table_name = 'EMPLOYEES';
SQL> CREATE TABLESPACE new_tablespace
2 DATAFILE '/u01/app/oracle/oradata/ORCL/new_tablespace.dbf'
3 SIZE 50M
4 AUTOEXTEND ON;

Tablespace created.

SQL> ALTER TABLE employees MOVE TABLESPACE new_tablespace;

Table altered.

SQL> SELECT table_name, tablespace_name FROM user_tables
2 WHERE table_name = 'EMPLOYEES';

TABLE_NAME TABLESPACE_NAME
-------------------- ------------------------------
EMPLOYEES NEW_TABLESPACE

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

2.4 【重要】インデックスの再構築

表を移動(MOVE)すると、ROWIDが変更されるため、主キーなどのインデックスは「無効」状態になります。必ず再構築(REBUILD)が必要です。

1.インデックスの状態確認

SELECT index_name, status 
FROM   user_indexes 
WHERE  table_name = 'EMPLOYEES';

2.インデックスの再構築(Rebuild)インデックスも新しい表領域へ移すのが一般的です。

-- 主キー制約で自動作成されたインデックス名を指定して実行
-- (実際の名前は上のSELECT結果を確認してください。ここでは例として employees_pk とします)
ALTER INDEX <索引名> REBUILD TABLESPACE new_tablespace;
SQL> SELECT index_name, status FROM user_indexes
2 WHERE table_name = 'EMPLOYEES';

INDEX_NAME STATUS
-------------------- --------
SYS_C007538 UNUSABLE

SQL> ALTER INDEX SYS_C007538 REBUILD TABLESPACE new_tablespace;

Index altered.

SQL> SELECT index_name, status FROM user_indexes
2 WHERE table_name = 'EMPLOYEES';

INDEX_NAME STATUS
-------------------- --------
SYS_C007538 VALID

3. 図解:操作の流れと状態変化

一連の操作による表の状態変化と、インデックスへの影響を図解します。

+-----------------------+       +-----------------------+
|   (1) 初期状態        |       |     インデックス      |
| 表領域: USERS         | <---- | 状態: VALID (有効)    |
| 属性: READ WRITE      |       |                       |
+-----------------------+       +-----------------------+
           |
           v (2) ALTER TABLE ... READ ONLY
           |
+-----------------------+
|   (3) 読み取り専用    |       DML(Insert/Update)不可
| 表領域: USERS         |       SELECT は可能
| 属性: READ ONLY       |
+-----------------------+
           |
           v (4) ALTER TABLE ... MOVE TABLESPACE ...
           |
+-----------------------+       +-----------------------+
|   (5) 移動完了        |       |     インデックス      |
| 表領域: NEW_TABLESPACE| <x--- | 状態: UNUSABLE (無効) |
| 属性: READ ONLY       |       | ※アクセス不可になる  |
+-----------------------+       +-----------------------+
           |
           v (6) ALTER INDEX ... REBUILD
           |
+-----------------------+       +-----------------------+
|   (7) 完全復旧        |       |     インデックス      |
| 表領域: NEW_TABLESPACE| <---- | 状態: VALID (有効)    |
| 属性: READ ONLY       |       |                       |
+-----------------------+       +-----------------------+

4. トラブルシューティング

操作中によく遭遇するエラーとその対処法です。

エラーコードエラーメッセージ(概要)原因と対処
ORA-12081update operation not allowed…原因: 読み取り専用表にDMLを実行した。
対処: 仕様通りです。更新が必要なら READ WRITE に戻してください。
ORA-01502index ‘…’ or partition of such index is in unusable state原因: MOVE 後にインデックス再構築を忘れている。
対処: 対象インデックスを REBUILD してください。
ORA-01950no privileges on tablespace原因: 移動先表領域へのクォータ(使用権)がない。
対処: ALTER USER ユーザー名 QUOTA UNLIMITED ON 表領域名; 等で権限を付与。

5. 運用・監視・セキュリティ上の注意

業務時間外での実施を推奨

ALTER TABLE MOVE 実行中、表は排他ロック(Exclusive Lock)されます。完了するまで他のユーザーはその表を検索・更新できません。

  • ※Oracle Enterprise Editionの ONLINE オプションを使えば回避可能ですが、Standard Editionでは停止時間を設ける必要があります。

統計情報の再取得

表を移動したりインデックスを再構築した後は、オプティマイザ統計情報が古くなっている可能性があります。パフォーマンス維持のため、最後に統計情報を取得することをお勧めします。

EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'<スキーマ名>', TABNAME=>'<テーブル名>');

6. よくある質問 (FAQ)

Q1. 読み取り専用の表を DROP(削除)できますか?

A. はい、できます。

READ ONLY はあくまでデータの中身(行)に対する変更を防ぐもので、表そのものの定義削除(DROP)は防げません。誤削除も防ぎたい場合は、トリガーなどでDDLを制限する必要があります。

Q2. 表の移動中に電源が落ちたらどうなりますか?

A. ロールバックされます。

DDLは完了するか失敗するかのどちらかです。中途半端にデータが移動することはありませんが、再実行が必要です。

Q3. パーティション表でも同じ手順ですか?

A. 基本は同じですが、パーティション単位での移動が可能です。

ALTER TABLE … MOVE PARTITION … を使用します。この場合も、グローバルインデックスが無効になる可能性があるため注意が必要です。


7. まとめ

Oracle Databaseにおける表の保護と移動について解説しました。

  1. READ ONLY はデータの誤更新・削除を確実に防ぐ強力な機能。
  2. MOVE TABLESPACE でストレージの最適化ができる。
  3. 注意点: 移動後は必ずインデックスの状態確認と再構築 (REBUILD) をセットで行う。

これらの基本操作を組み合わせることで、堅牢かつ効率的なデータベース運用が可能になります。まずはテスト環境で、エラー発生も含めて挙動を確認してみてください。


本記事は Oracle Database 19c を対象に解説します(他バージョンは画面や既定値が異なる場合があります)。


[参考]
Oracle Database SQL言語リファレンス 19c

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

コメント

タイトルとURLをコピーしました