12章 UNDO管理
では本章ではUNDOについて学んでいきましょう。
UNDOとは
UNDOとは変更前のデータです。
UPDATE文が実行されると行はデータは更新されます。
しかしDML文はロールバックにより、データを前のデータに戻すことがあります。
この為、OracleデータベースはDML文によるデータ更新をする前に
変更前のデータを一定時間保持しています。
その変更前データをUNDOデータと呼んでいます。
このUNDOデータはデータがコミットされるまでは必ず保持されます。
理由はROLLBACK実行時に元に戻せるようにするためです。
COMMIT後はUNDOデータは上書き可能となります。
上書き可能となったUNDOデータは新規UNDOデータにより上書きされます。
UNDO_RETENTION
UNDOはロールバックに使用されるだけではなく以下のタイミングで使用されます。
・ロールバック時
・読み取り一貫性
・フラッシュバック機能
それでは読み取り一貫性とフラッシュバック機能について確認していきましょう。
読み取り一貫性
未COMMITのデータをSELECTするとき、変更前のデータを取得
変更されたら変更中のデータを表示するのが普通ではないかと
疑問に思う方もいるでしょう。
理由は変更中のデータはまだ確定したデータではないからです。
トランザクション内の変更は最後にCOMMITかROLLBACKを発行し
データの確定もしくは取り消しを行う必要があります。
確定していない変更中のデータを取得後、ROLLBACKが実行されたら、
取得したデータは誤ったデータとなってしまいます。
その為、未確定なデータ表示させない仕様となっています。
この未確定なデータを見せるかどうかは「トランザクション分離レベル」と
言われており、データベースでは重要な話となります。
このトランザクション分離レベルは、データベース管理システムで動作が異なります。
では、読み取り一貫性についてご紹介しましたが、
以下のような場合にも読み取り一貫性は使用されます。
SELECT文 10:00-11:00
UPDATE文,COMMIT 10:05
上記はSELECT文が10時に実行されて終了するまで60分所要する場合に、
SELECT最中にデータが変更され、コミットされた場合も、
COMMIT後ではなく、SELECT文実行時の10時の時点のデータが取得されます。
これも読み取り一貫性の機能です。この時にはUNDOが使用されています。
つまり、
COMMIT後でも長時間かかるSELECT文が発行されると、
UNDOが使用される可能性があります。
もしCOMMIT後、上書き可能となったUNDOが長時間かかるSELECT文によって
使用されるとき、その上書き可能となったUNDOが、新規UNDOによって
上書きされてしまった場合はSELECT文は失敗します。
SQL> SELECT * FROM DEPT;
ORA-01555: スナップショットが古すぎます: ロールバック・
セグメント番号 xxx、名前xxxが小さすぎます
上記エラーはSELECT時にUNDOデータが上書きされてしまい
エラーとなった場合です。このようなことがないようCOMMIT後の
UNDOデータを一定時間保持させる必要があります。
UNDO_RETENTION:900(秒)
上記の初期化パラメータはCOMMIT後のUNDOデータを保持する期間を指定します。
デフォルトは900秒です。COMMIT後すぐに上書きされるわけではなく、
900秒後に上書き可能になります。
どのくらいの設定値が理想なのかは難しいところですが、
先ほどのような読み取り一貫性で長時間かかるSELECT文が失敗しないよう、
長時間かかるSELECT文を特定し、最大何分所要するかを確認し、
その時間までは保持する方が良いと思います。
SELECT文終了時間までUNDOを保持しておけば、
SELECT文が失敗することはありませんので。安全に設計することが一番です。
ただしUNDO_RETENTIONはUNDO表領域のサイズに余裕があった場合、
UNDO_RETENTIONの時間まで保持しますが、UNDO表領域が既に一杯と
なっている場合は、アクティブなUNDOの書き込みが失敗しないよう、
UNDO_RETENTIONの時間を超えていなくても上書きされてしまいます。
その為、UNDO表領域は十分に余裕を持ったサイズにしましょう。
UNDOの保存期間の自動チューニング
UNDOの保持期間はUNDO_RETENTIONパラメータで制御できますが、
どの時間が適切かを見積もるのは難しいですね。
しかし、OracleはUNDO_RETENTIONパラメータを自動的に調整し、
ORA-1555エラーが出ないようにチューニングを実施してくれます。
OracleはUNDO表領域サイズとデータベース内の実行されるSQLの具合を
見てUNDO保存期間を自動チューニングします。
UNDO_RETENTIONを設定するとその値は最低限保持する時間となり、
その値が少ない場合は、自動的に値を増加します。
しかしUNDO表領域に属するデータファイルが固定か自動拡張かで動作が変わります。
データファイル固定サイズ時の
自動UNDO管理
UNDO_RETENTIONパラメータは無視されます。
UNDO保存期間を動的にチューニングします。通常、この最適な保存期間は、
な最長実行問合せの期間よりもかなり長くなります。
データファイル自動拡張時の
自動UNDO管理
UTOEXTENDオプションが有効なUNDO表領域の場合、データベースでは、
UNDO_RETENTIONで指定された最小保存期間を維持しようとします。
空き領域が少なくなると、期限切れでないロールバック情報を上書きするかわりに、
表領域が自動的に拡張されます。
結論を簡単に言ってしまうと、以前のバージョンではUNDO管理は
難しいものでしたが、現在は自動UNDO管理の機能があるため、
UNDOの管理においてはUNDO表領域のサイズを気にするだけで
済むようになっています。
以上がUNDOの管理となります。