Oracle Databaseで共有プール(SHARED POOL)にキャッシュされている情報をフラッシュしたい場合、使用するSQLとして代表的なのがALTER SYSTEM FLUSH SHARED_POOL;です。
ただし、「SHARED_POOLを消去する」という表現には注意が必要です。このコマンドは共有プールというメモリー領域そのものを削除したり、SGAからSHARED_POOLをなくしたりするものではありません。共有プールからフラッシュ可能なキャッシュ情報をクリアする操作と理解するのが適切です。
また、本番環境で安易に実行するとSQLの再解析などによって一時的に負荷が上昇する可能性があります。ここではALTER SYSTEM FLUSH SHARED_POOLの意味、対象、必要な権限、実行時の影響、似ているコマンドとの違いを整理します。
- SHARED_POOLのフラッシュにはALTER SYSTEM FLUSH SHARED_POOLを使う
- そもそもSHARED POOLとは何か
- FLUSH SHARED_POOLは「共有プール自体を削除」する操作ではない
- フラッシュするとSQLはどうなる?
- 実行中・使用中のものまで必ず全部消えるわけではない
- 実行にはALTER SYSTEM権限が必要
- BUFFER_CACHEのフラッシュとは別物
- 性能テスト目的で実行するときにも注意が必要
- 特定のSQLだけが問題なら共有プール全体を消す必要がない場合もある
- 「共有プール不足」の対策としてFLUSHするのは慎重に
- 本番環境では安易に実行しない
- RAC環境ではインスタンスの範囲にも注意する
- SHARED_POOLをフラッシュする前に確認したいこと
- まとめ:ALTER SYSTEM FLUSH SHARED_POOLでフラッシュできるが「完全削除」とは違う
SHARED_POOLのフラッシュにはALTER SYSTEM FLUSH SHARED_POOLを使う
Oracle Databaseで共有プールをフラッシュする基本構文は次のとおりです。
ALTER SYSTEM FLUSH SHARED_POOL;
Oracle DatabaseのSQL Language Referenceでは、FLUSH SHARED_POOLについて共有プール内のすべての情報をクリアするための句として説明されており、実行中のSQLやPL/SQLなど一部の項目はフラッシュされないことも明記されています。[参照] Oracle Database SQL Language Reference「ALTER SYSTEM」
したがって「共有プールにあるキャッシュをフラッシュしたい」という目的なら、ALTER SYSTEM FLUSH SHARED_POOL;が該当するコマンドです。ただし「メモリー上のものが例外なく完全にゼロになる」という意味ではありません。
そもそもSHARED POOLとは何か
Shared PoolはOracle DatabaseのSGA(System Global Area)を構成する重要な領域の一つです。OracleのDatabase Conceptsでは、Shared Poolにライブラリキャッシュ、データディクショナリキャッシュなどが含まれることが説明されています。[参照] Oracle Database Concepts「Memory Architecture」
ライブラリキャッシュにはSQL文やPL/SQLなどの実行に利用される情報が保持されます。一度解析したSQLに関する情報を再利用できれば、同じSQLを実行するたびに最初からすべて処理する必要がなくなります。
つまりShared Poolは単なる「不要データ置き場」ではありません。Oracleの処理効率を高めるために積極的に再利用されるキャッシュを含む領域なので、フラッシュには性能上の影響が伴います。
FLUSH SHARED_POOLは「共有プール自体を削除」する操作ではない
ALTER SYSTEM FLUSH SHARED_POOLという名称から、SHARED_POOL_SIZEで確保されたメモリーそのものを解放するように見えるかもしれませんが、そうではありません。
この操作の中心は、共有プールにキャッシュされているフラッシュ可能な情報をクリアすることです。共有プールというSGA内の構造自体をなくす命令ではありません。
そのため「SHARED_POOLを消去したい」という場合には、実際の目的を明確にする必要があります。「キャッシュされたSQLを再利用させたくない」のか、「特定SQLをキャッシュから外したい」のか、「共有プールのサイズを変更したい」のかによって適切な操作は異なります。
フラッシュするとSQLはどうなる?
共有プールをフラッシュすると、ライブラリキャッシュに保存されていた再利用可能なSQL情報などが失われます。その後にSQLが再実行されれば、Oracleは必要に応じて再解析などを行い、再び共有プールへ情報を蓄積していきます。
例えば、あるSQLが通常はライブラリキャッシュ上の既存カーソルを利用できていたとします。共有プールをフラッシュした後に再度実行すれば、そのキャッシュが利用できず、ハードパースが必要になる可能性があります。
そのため、本番環境で多数のセッションが稼働している時間帯に共有プール全体をフラッシュすると、一時的にハードパースが増え、CPU負荷などへ影響する可能性があります。単なる「掃除」の感覚で定期実行するものではありません。
実行中・使用中のものまで必ず全部消えるわけではない
Oracle公式のALTER SYSTEMリファレンスでは、FLUSH SHARED_POOLを実行しても、現在実行中のSQLやPL/SQLパッケージなど、現在実行されている項目はフラッシュされないと説明されています。[参照] Oracle Database SQL Language Reference
また、DBMS_SHARED_POOLのKEEPプロシージャを使用して保持するよう指定された項目についても、通常のフラッシュとは扱いが異なります。
したがって「FLUSHを実行したのに対象が残っているように見える」という場合でも、直ちにコマンドが失敗したとは限りません。対象が実行中・使用中・KEEP対象などではないかを確認する必要があります。
実行にはALTER SYSTEM権限が必要
ALTER SYSTEM文を実行するには、基本的にALTER SYSTEMシステム権限が必要です。通常のアプリケーションユーザーへ無条件に付与するような権限ではありません。
SQL*PlusやSQL Developerなどから、必要な権限を持つユーザーで次のように実行します。
ALTER SYSTEM FLUSH SHARED_POOL;
権限不足の場合はOracleエラーになります。本番データベースではDBAや運用担当者の管理対象となっていることが一般的なので、権限がないからといって自分のユーザーへ強い権限を追加するのではなく、管理ルールに従って対応します。
BUFFER_CACHEのフラッシュとは別物
Oracleには似た名前のコマンドとして、次のものがあります。
ALTER SYSTEM FLUSH BUFFER_CACHE;
これはFLUSH SHARED_POOLとは対象が異なります。Shared PoolとDatabase Buffer CacheはどちらもSGAに含まれますが、役割は同じではありません。
| コマンド | 主な対象 |
|---|---|
ALTER SYSTEM FLUSH SHARED_POOL; |
共有プールのフラッシュ可能なキャッシュ情報 |
ALTER SYSTEM FLUSH BUFFER_CACHE; |
データベースバッファキャッシュ |
Oracle公式リファレンスではFLUSH BUFFER_CACHEについて、バッファキャッシュ内のすべてのバッファを無効化するもので、dirty bufferについてはディスクへ書き込まれた後に無効化されると説明されています。[参照] Oracle Database SQL Language Reference
「キャッシュを消したい」という言葉だけでコマンドを選ばず、ライブラリキャッシュ等を対象にしたいのか、データブロックのバッファキャッシュを対象にしたいのかを区別しましょう。
性能テスト目的で実行するときにも注意が必要
SQLの性能測定で「キャッシュを消して毎回同じ条件から測定したい」という理由からFLUSH SHARED_POOLを使いたくなることがあります。しかし、Shared PoolをフラッシュするだけでOracle Database全体が「完全な初期状態」に戻るわけではありません。
例えばShared PoolとBuffer Cacheは別ですし、OS側にもファイルシステムキャッシュなど別レイヤーのキャッシュが存在し得ます。また、統計情報やその他のデータベース状態もフラッシュ前後で同一になるとは限りません。
そのため性能テストでは「何をコールド状態にしたいのか」を明確にし、測定方法そのものを設計する必要があります。Shared Poolのフラッシュだけを「完全なキャッシュクリア」とみなすのは避けましょう。
特定のSQLだけが問題なら共有プール全体を消す必要がない場合もある
ある1本のSQLについてキャッシュされたカーソルを無効化したい、あるいは特定のオブジェクトだけを共有プールから取り除きたいという目的なら、共有プール全体のフラッシュは影響範囲が大きすぎる場合があります。
OracleにはDBMS_SHARED_POOLパッケージがあり、共有プール内のオブジェクトを管理するためのPURGE、KEEP、UNKEEPなどの機能が提供されています。[参照] Oracle Database PL/SQL Packages and Types Reference「DBMS_SHARED_POOL」
特定のカーソルやオブジェクトだけを対象にできるのであれば、データベース全体へ影響するALTER SYSTEM FLUSH SHARED_POOLより限定的な方法を検討する価値があります。ただしPURGEの対象指定などにはOracle内部の識別情報に関する理解が必要なので、実行前に利用中バージョンの公式ドキュメントを確認してください。
「共有プール不足」の対策としてFLUSHするのは慎重に
共有プール関連のエラーやメモリー不足が起きた際、「一度FLUSH SHARED_POOLすれば直るのでは」と考えることがあります。フラッシュによって一時的に状況が変化する場合はありますが、それが根本的な解決とは限りません。
例えばSQLがリテラル値の違いによって大量の別カーソルとして生成されている、共有プールのサイズに問題がある、アプリケーションのSQL設計に問題がある、といった原因なら、フラッシュ後にも同じ状態が再発する可能性があります。
継続的な問題であれば、共有プールの利用状況、ライブラリキャッシュ、SQLの共有状況、SGA設定などを調査し、原因を特定する必要があります。フラッシュは原因分析の代替ではありません。
本番環境では安易に実行しない
ALTER SYSTEM FLUSH SHARED_POOL;は短いSQLなので簡単な操作に見えます。しかし、影響範囲は現在接続している自分のセッションだけではありません。
共有プールに存在したSQLなどの再利用可能な情報がフラッシュされれば、その後の処理で再解析が必要になり得ます。利用者の多いデータベースでは、多数のSQLが短時間に再解析されることで負荷が変動する可能性があります。
特に本番環境では「キャッシュをきれいにしておこう」という理由だけで定期的に実行するのではなく、実行目的と影響を確認し、必要性がある場合にDBAの管理下で行うことが重要です。
RAC環境ではインスタンスの範囲にも注意する
Oracle Real Application Clusters(RAC)のように複数インスタンスで構成される環境では、SGAはインスタンスごとに存在します。そのため単一インスタンスの感覚で「データベース全体の共有プールを消した」と判断しないことが重要です。
ALTER SYSTEMにはRAC環境でインスタンスを指定するためのSID句などがありますが、指定可能な句や動作は操作内容によって異なります。実際の環境で共有プールをフラッシュする場合は、使用中のOracle Databaseバージョンの公式ALTER SYSTEMリファレンスを確認してください。
検証環境と本番環境で構成が異なる場合にも注意が必要です。単一インスタンスの検証機で期待どおりだった操作を、そのままRAC本番環境へ適用するのは避けましょう。
SHARED_POOLをフラッシュする前に確認したいこと
実行前には少なくとも次のような点を整理しておくと、安全性とトラブルシューティングの精度が上がります。
| 確認項目 | ポイント |
|---|---|
| 目的 | なぜ共有プールをフラッシュする必要があるのか |
| 対象 | 全体なのか特定SQL・オブジェクトなのか |
| 環境 | 開発・検証・本番のどれか |
| 負荷 | フラッシュ後の再解析による影響を許容できるか |
| 構成 | 単一インスタンスかRACか |
| 権限 | ALTER SYSTEMを実行できる適切な管理ユーザーか |
| 根本原因 | メモリー問題などをフラッシュだけで済ませようとしていないか |
開発・検証環境でSQLの挙動を調査する目的と、本番環境で障害対応として実行する場合ではリスクが大きく異なります。コマンドが正しいことと、その場面で実行することが適切であることは別問題です。
まとめ:ALTER SYSTEM FLUSH SHARED_POOLでフラッシュできるが「完全削除」とは違う
Oracle DatabaseのShared Poolをフラッシュする基本コマンドは、ALTER SYSTEM FLUSH SHARED_POOL;です。Oracle公式のSQL Language Referenceにも記載されている正規のALTER SYSTEM操作です。
ただし、このコマンドはSHARED POOLというメモリー領域そのものを削除するものではなく、共有プール内のフラッシュ可能なキャッシュ情報をクリアするものです。実行中のSQLやPL/SQLなど、フラッシュされない項目もあります。
また、Shared Poolをフラッシュするとキャッシュされていた情報を再利用できなくなり、その後のSQLでハードパースなどが発生する可能性があります。そのため、本番環境で理由なく実行することはおすすめできません。
特定のSQLやオブジェクトだけが目的ならDBMS_SHARED_POOL.PURGEなど、より限定的な方法が適している場合があります。また、Buffer Cacheをフラッシュしたい場合は別のALTER SYSTEM FLUSH BUFFER_CACHEであり、対象を混同しないことも重要です。
「SHARED_POOLを消去したい」というときは、まず「何を消して、何を確認したいのか」を明確にし、その目的に応じて共有プール全体のFLUSH、特定オブジェクトのPURGE、あるいは根本的なSQL・メモリー設定の調査を選択するのが適切です。


コメント