SEQUENCE についての FAQ

シーケンスの欠番 ケース1

シーケンスは採番のたびにディクショナリにアクセスせずにメモリ上にバッファされている番号を戻す。 これはメモリ上に次の値と次回のディクショナリの更新値を保持しているのではないかと思う。
ディクショナリの値はシングルインスタンスに限れば、

前回のディクショナリの値 <= 現在値 < 現在のディクショナリの値
(現在のディクショナリの値 = 前回のディクショナリの値 + キャッシュサイズ)

となる。
このディクショナリの値は正常停止(シャットダウン)しても値が巻き戻ることはない。 そのため次回起動時にキャッシュ上に確保されていた番号分は欠番として再開されることになる。

以下の SQL でディクショナリの値は取得できる。

SELECT SEQUENCE_NAME, LAST_NUMBER FROM USER_SEQUENCES

シーケンスの欠番 ケース2

シーケンスは揮発性の共有プール(メモリ)に格納されている。そのため長期間使用されずに放置されたシーケンスの使用領域に期限切れが発生して共有プールから追い出されることがある。このときのメモリ上に確保された部分は消去される。
この原因の欠番発生を防ぐには DBMS_SHARED_POOL パッケージの KEEP プロシージャを使用する。 シーケンス名を指定し KEEP を呼び出すことで一度ローディングされたシーケンスは期限切れによるエージアウト(エージング・アウト)が発生しないようになる。

DBMS_SHARED_POOL パッケージの使用例

シーケンスの欠番 ケース3

上述のとおり、シーケンスはキャッシュをメモリ上に確保している。 稼動中にシーケンスのキャッシュが保存されている ディクショナリ・キャッシュ (SHARED_POOL) メモリをクリアする操作を行なうと メモリ上に確保された部分が消去される。つまりキャッシュに確保されたが使用しなかった番号はすべて欠番となる。

キャッシュを消してしまう命令の例

ALTER SYSTEM FLUSH SHARED_POOL ;
-- ※補足:ALTER SYSTEM FLUSH BUFFER_CACHE (10g) では欠番にならない

この2つの命令は結構インパクトが大きい。仕切り直しのつもりで安易に本番環境のバッチ処理(の前後)などに直接組み込んでしまうのはお勧めできない。使う場合でも使いどころを間違わないようにしたい。

シーケンスの欠番 ケース4

通常、シーケンスは決して逆戻りはしない(※)。トランザクションに含まれていても同様である。 これはトランザクションが ROLLBACK することで欠番が発生することをあらわす。

(※) リカバリ、シーケンスの再作成やインポートなどの場合を除く

シーケンスの現在値

インスタンス単位でのシーケンスの現在値を知ることはできない(※)。わかるのは自らが採番した後の現在値(=次の値)だけである。

(※) CURRVAL という擬似列で現セッション中で最後に採番した番号(=現在値と言い換えることもできる)を知ることはできる。そのセッションで採番 (NEXTVAL) を行なっていない場合には、CURRVAL 擬似列を参照することはできない。

ORA-08002: 順序 sequence_name.CURRVALはこのセッションではまだ定義されていません

のエラーが発生する。

RAC とシーケンスの飛び番

シーケンス・ジェネレータはインスタンス毎に存在する。すなわちキャッシュもインスタンス毎に用意される。 デフォルトのシーケンスの場合、キャッシュサイズ 20、NOORDER であるので、たとえば

インスタンスAのキャッシュ  1 〜 20 
インスタンスBのキャッシュ 21 〜 40 
ディクショナリの値 41 

のようにキャッシュされる。このため、NOORDER の場合に 1, 21, 2, 22 ... のように採番されることがある。
これは ORDER にして回避することができる。
しかしキャッシュはされなくなる。シングルインスタンスでなければ ORDER とキャッシュは両立しない。
ある特定のインスタンスから取得すれば両立するが、そのインスタンスが停止するとすべての採番が停止する。

シーケンスと PL/SQL

シーケンスオブジェクトは SQL からしかアクセスできない。そのため PL/SQL からシーケンスにアクセスするには SQL を経由する。〜 Oracle 10g
Oracle 11g からは PL/SQL で直接シーケンスオブジェクトにアクセスできる。

シーケンスの制限事項

シーケンスの最大値は 28 桁(10^28 -1)、負の場合は 27桁(10^27 -1)
ちなみに 0〜10^28-1 を増分1で使い切ろうとすると、毎秒 1000 万回採番して約3兆年かかるので、おうばん振る舞いしても大丈夫である。



 
カスタム検索
スポンサード リンク
日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ OTN Software Kit (開発者ライセンス)