Oracle Databaseでは、表領域(tablespace)をREAD ONLY、つまり読み取り専用に変更できます。履歴データや更新する必要のない大量データを保護したい場合などに利用される機能です。
結論として、READ ONLYになった表領域に格納されているデータを変更するUPDATE・INSERT・DELETEなどのDML操作は基本的に許可されません。Oracle公式ドキュメントでも、表領域を読み取り専用にすると、その表領域のデータファイルへの書き込みが防止され、表領域内の表を更新できなくなることが説明されています。
ただし、「読み取り専用」という言葉からSELECT以外のSQLがすべて禁止されると考えると正確ではありません。DDLや既存トランザクションの扱いなどには注意点があります。ここではOracle DatabaseのREAD ONLY表領域がどのように動作するのかを具体例とともに整理します。
表領域をREAD ONLYにするとデータ更新は拒否される
Oracle Databaseでは、通常の表領域はREAD WRITEとして作成され、読み書きができます。これをREAD ONLYへ変更すると、その表領域のデータファイルに対する書き込みが防止されます。
Oracle Database 19cの管理者ガイドには、読み取り専用にすると表領域内のすべての表に対する更新が防止され、ユーザーが持つ更新権限のレベルにかかわらず変更できなくなることが明記されています。[参照] Oracle Database 19c Administrator’s Guide
つまり、ユーザーに対象表へのUPDATE権限が与えられていても、表領域自体がREAD ONLYなら、その権限だけでデータを書き換えることはできません。
READ ONLY表領域でUPDATEするとどうなる?
例えば、APP_DATAという表領域にSALES_HISTORYという表が格納されているとします。最初は通常のREAD WRITE状態ですが、管理者が次のSQLを実行すると読み取り専用へ変更できます。
ALTER TABLESPACE APP_DATA READ ONLY;
OracleのSQLリファレンスによると、READ ONLYへの移行後は新たなDML操作が許可されません。[参照] Oracle Database SQL Language Reference
この状態で、例えば次のように対象表のデータを変更しようとします。
UPDATE SALES_HISTORY SET AMOUNT = 5000 WHERE SALES_ID = 100;
表領域のデータファイルを書き換える必要があるため、このような更新は成功しません。READ ONLYは単なる表示上の属性ではなく、実際に表領域への書き込みを防止する仕組みです。
INSERT・UPDATE・DELETEはいずれも基本的に不可
READ ONLY表領域ではUPDATEだけでなく、表領域内のデータを変更するDML全般が対象になります。代表的にはINSERT、UPDATE、DELETEなどです。
| 操作 | READ ONLY表領域 | 理由 |
|---|---|---|
| SELECT | 可能 | データを読み取るだけだから |
| INSERT | 不可 | 新しいデータを書き込むため |
| UPDATE | 不可 | 既存データを書き換えるため |
| DELETE | 不可 | 既存データを変更するため |
| SELECT … FOR UPDATE | 用途・対象状態に注意 | 通常の単純なSELECTとは異なり更新を前提とするため |
例えば過去年度の売上データを保存した表領域をREAD ONLYにしておけば、アプリケーション側で誤ってUPDATEやDELETEを発行した場合にも、表領域の読み取り専用状態がデータ変更を防ぐ防御層になります。
更新権限を持つユーザーでも書き換えられない
READ ONLY表領域を理解するときに重要なのが、ユーザー権限との違いです。例えばユーザーAにSALES_HISTORY表へのUPDATE権限が付与されていたとしても、表領域がREAD ONLYなら通常どおり更新できるわけではありません。
Oracle公式ドキュメントでは、READ ONLYにすると表領域内のすべての表について、ユーザーの更新権限レベルに関係なく更新を防止すると説明されています。つまり「UPDATE権限があるか」というアクセス制御と「表領域が書き込み可能か」という状態は別の問題です。
権限がある=必ず更新できる、ではありません。SQLを実行する権限があっても、書き込み先となる表領域がREAD ONLYなら実際のデータ変更は制限されます。
READ ONLYへの切り替え中は既存トランザクションに注意
ALTER TABLESPACE ... READ ONLYを実行した瞬間に、実行中だったすべてのトランザクションが強制終了するわけではありません。この点は運用上重要です。
Oracleの管理者ガイドでは、READ ONLYへの変更命令を発行すると表領域は移行状態となり、先に開始されていて対象表領域に未コミットの変更を持つトランザクションについて、コミットまたはロールバックを待つことが説明されています。一方、それ以降の新たなDMLによる変更は許可されません。
そのため、大量更新処理などが実行中の表領域に対してREAD ONLYを設定すると、ALTER TABLESPACEがなかなか完了しないことがあります。この場合は「READ ONLYが壊れている」と判断するのではなく、先行トランザクションが残っていないか確認する必要があります。
読み取り専用を解除すれば再び更新できる
READ ONLYは永久的な設定ではありません。必要になった場合は、管理権限を持つユーザーが表領域をREAD WRITEへ戻せます。
例えばAPP_DATA表領域を再び書き込み可能にする場合は、次のように指定します。
ALTER TABLESPACE APP_DATA READ WRITE;
READ WRITEへ正常に変更されれば、権限などほかの条件を満たしているユーザーは再びINSERT・UPDATE・DELETEなどを実行できるようになります。そのため、履歴データを一定期間だけ固定し、後からメンテナンスのために書き込み可能へ戻すといった運用も考えられます。
READ ONLY表領域はバックアップ運用でもメリットがある
READ ONLY表領域は誤更新防止だけを目的とした機能ではありません。Oracleでは、大量の静的データについてバックアップやリカバリの負担を軽減することも主な用途として説明しています。
例えば過去年度の確定済みデータが数TBあり、今後変更されないのであれば、その部分をREAD ONLYにする設計が考えられます。内容が変化しないため、読み取り専用の状態が維持されている期間について、変更され続ける通常の表領域とは異なるバックアップ戦略を採用できます。
Oracle公式ドキュメントでも、READ ONLYへ変更した後にバックアップすることが推奨されており、その後READ ONLYのままならデータが変更されないという特性を活用できます。
READ ONLYでも「すべての操作が完全禁止」ではない
注意したいのは、表領域のREAD ONLYを「その表領域に関係するSQLがSELECT以外すべて実行不可能になる機能」と単純化しないことです。Oracleのドキュメントでは、読み取り専用表領域にある表や索引などをDROPできる場合があるほか、データディクショナリ上の記述を変更する一部の操作についても例外的な挙動が説明されています。
したがって、READ ONLYの中心的な意味は「その表領域のデータファイルへの書き込みを防止する」ことだと理解すると正確です。「データベース内のあらゆるメタデータ変更を禁止する」という意味ではありません。
また、表単体をREAD ONLYにする機能と表領域全体をREAD ONLYにする機能も区別しましょう。今回のような表領域の設定では、その表領域に格納されている複数のオブジェクトへ影響します。
表領域が本当にREAD ONLYか確認する方法
「更新できない原因がREAD ONLYなのか」を調べる場合は、推測するのではなくデータディクショナリビューで表領域の状態を確認するのが確実です。権限のある環境では、例えば次のようなSQLで確認できます。
SELECT TABLESPACE_NAME, STATUS FROM DBA_TABLESPACES;
対象の表がどの表領域にあるかも確認し、表領域の状態と照合すると切り分けしやすくなります。更新時にエラーが発生した場合はエラー番号・メッセージも確認してください。OracleのORA-00372は、変更できないファイルを変更しようとした場合に発生し、その原因の一つとしてREAD ONLY表領域が公式に挙げられています。[参照] Oracle ORA-00372
ただし、更新できない原因はREAD ONLYだけではありません。ユーザー権限、表自体のREAD ONLY設定、ロック、制約、トリガー、アプリケーション側の制御などもあるため、実際の障害調査ではエラーメッセージを起点に切り分けます。
まとめ:READ ONLY表領域ではデータ更新操作は拒否される
Oracle Databaseで表領域をREAD ONLYにすると、その表領域のデータファイルへの書き込みが防止されます。そのため、対象表へのINSERT・UPDATE・DELETEなど、データを変更するDML操作は基本的に拒否されます。
これはユーザーにUPDATE権限がある場合でも同様です。一方、SELECTによる読み取りは可能であり、一部のDDLやデータディクショナリに関係する操作には単純な「全部禁止」では説明できない例外があります。
読み取り専用を解除して再びデータを変更する必要がある場合は、適切な権限でALTER TABLESPACE 表領域名 READ WRITE;を実行します。READ ONLYは、更新が不要になった履歴データの保護や、大規模な静的データのバックアップ運用などで有効なOracle Databaseの機能です。


コメント