UNDOを大切にしないとバチが当たる!読み取り一貫性やリカバリを実現するのはUNDOだ

覚えるべきキーワード
・UNDO
・UNDO保存期間
・UNDO保存期間の保証
・RETENTION GUARANTEE句
・RETENTION NOGUARANTEE句
・自動UNDO管理
・UNDO表領域
・UNDOアドバイザ
・UNDO表領域の最小サイズ

アンドゥー表領域足りてないんじゃない?

アンドゥーデータがちゃんと保存されてないとフラッシュバックできないよ。

システム開発の現場ではこのような会話をしばし耳にします。
システムエンジニアになった僕にとって、最初の壁は「IT特有の専門用語を理解する事」でしたが、その中でもこのアンドゥーという言葉はかなり新鮮でした。(アンドゥーっていうのは安藤さんのあだ名でしか聞いたことがない)音的にもかなり面白いなーっと思っていました。

しかし、システムエンジニアになった今は、このアンドゥーがかなり大事なモノだと知っています。面白いと言うか、Oracleではとてつもなく、重要なモノです。Oracleデータベースには必要不可欠です。

アンドゥーはUNDOと書きます。UNDOは造語ではなく、れっきとした英単語です。
「元通りにする」という他動詞です。読み方はそのまま、アンドゥーです。
OracleデータベースでもUNDOは「元通りにする」ために使います。では、何を元通りにするのか。
もちろん、データです。

一番よく使うUNDO用語はUNDOデータです。
UNDOデータとはトランザクションによるデータ変更前に、データベースが取得する変更前データです。データが変更される前にOracleデータベースは変更前データをしれっと取得しておき、そのデータをしれっと表領域で保存しています。

では、これはなんのためでしょう。

※ちなみにUNDOに似たOracle用語として、REDOがあります。
→( REDOとは古いデータを最新にし、UNDOとは最新データを古くする )
UNDOとREDOが混同している方はぜひ一度こちらからお読みください。

UNDOが支える機能

読み取り一貫性、ロールバック、フラッシュバック、リカバリ。これらの用語はOracleをユーザーなら聞いたことがあるでしょう。Oracleの特徴と言っても良いほど優れた機能です。実はこれら機能はぜんぶ、UNDOデータが支えています。UNDOデータがないとロールバックもリカバリも確実に実現しません。
簡単にそれぞれどこでUNDOデータが利用されるか見ていきます。

読み取り一貫性

読み取り一貫性は分かりづらいワードですが、イメージしやすいようにシーンを想像しながら説明します。
例えば、AさんがXデータベースのYテーブルのデータを表示するためにselect * from Y;を11月12日9:00に実行しました。ただし、Yテーブルには1000万件のデータが入っているためデータ表示には5分以上かかります。
同じタイミングでBさんが11月12日9:01にXデータベースのYテーブルのデータのうち、1件を変更しました。id(PK)が30のデータのname列をsatohからasadaに変更するためupdate Y set name = ‘asada’ where id = 30;を実行しました。update分は1秒かからずに実行でき、すぐさまcommitを実行しました。
Aさんのselect文は9:20にようやく表示できました。
この場合、Aさんが取得したデータのうち、id=30のデータはsatohでしょうか、asadaでしょうか。
select文を実行時点ではasadaでした。でも、取得した時点でデータ自体はsatohになっています。この場合、表示されるデータはどちらになるのか。

答えはasadaです。Oracleでは、select実行中にデータが変更されても、実行時点のデータを取得します。しかし、一方で別ユーザーのトランザクションも実行できないといけないので、実際、メモリーのデータはsatohに変わっています。メモリーデータはsatohに変わるけれど、asadaが表示されます。
内部ではこのような仕組みになっています。
select実行中に他でトランザクションが起きると、変更前データはUNDOに保存されます。しかし、表示までには、そのUNDOデータで変更前に戻すので、結果、asadaが表示されます。Oracleではselect文実行中に変更があっても、実行時点のデータを表示します。
これを読み取り一貫性と言います。

ロールバック操作

ロールバックとは、変更したトランザクションを取消す機能です。コミットされていないトランザクションは、rollbackの実行で取り消されると言われていますが、正確には取り消されるのではなく、「変更後データに対して、UNDOデータ(変更前データ)でさらに変更することで変更前状態に戻す。」がロールバックの真相です。

フラッシュバック

フラッシュバック機能はリカバリや過去時点のデータを表示する機能です。フラッシュバックにはいくつかの種類がありますが、フラッシュバックドロップとフラッシュバックデータベースを除いたフラッシュバックはUNDOデータを使います。

リカバリ

インスタンスリカバリやメディアリカバリといった重めのリカバリにもUNDOデータを使います。これらリカバリはトランザクション実行後のコミットされていないデータまでリカバリするため、コミットされていないトランザクションは取り消さないといけません。UNDOデータで変更を加えれば、未コミットのトランザクションが取り消された状態でリカバリされます。

UNDO保存期間中は上書きされない

ロールバック操作、読み取り一貫性、フラッシュバック、リカバリというOracleの重要な機能はUNDOデータがありきです。いかにUNDOデータが重要なデータか認識できたのではないでしょうか。
このように大事なUNDOデータなので、原則、コミットが実行されるまでは上書きされません。コミット後は原則、再利用できるようになるのですが、UNDO保存期間中は万が一に備えて、UNDO表領域含めて再利用ができなくなっています。
コミットした後も念のため少しだけデータ保持をしておこう。という感じです。UNDO保存期間とはUNDOデータを保存する期間を言います。
UNDO保存期間は、自動UNDO管理有効のデータベースだと自動管理してくれますが、UNDO保存期間中でもUNDO表領域が不足してしまうと、やむを得ず上書きしてしまう場合があります。しかし、確実に保証できないのであれば、「いざフラッシュバックをする際にUNDOデータがない!」という悲劇も起こりえてしまいます。
そのため、もしUNDO保存期間中は絶対UNDOデータを保持したい場合はUNDO保存期間の保証オプションを有効にします。設定はUNDO表領域の作成時か、変更時にRETENTION GUARANTEE句を指定するだけです。これでUNDO保存期間中のUNDOデータ保持を保証してくれます。ちなみにUNDO保存期間中の保証を無効にしたい場合はRETENTION NOGUARANTEE句を指定します。
UNDO保存期間の保証を有効にしておけば、UNDO保存は安心できます。

UNDO自動管理で効率的なUNDO利用をする

さきほど出てきたUNDO自動管理についても少し触れてみます。UNDO管理には自動管理と手動管理がありますが、基本的には自動管理を選択していると思います。(UNDOを手動管理しているシステムはかなり少数なのではないかな。)

UNDO自動管理モードにすると、UNDOデータはUNDOセグメントに格納され、UNDOセグメントはUNDO表領域に格納されます。自動UNDO管理では、UNDO表領域が不足する場合、表領域を拡張しなければいけませんが、自動で拡張する方法と自動拡張しない方法があります。
UNDO表領域を自動拡張するにはAUTOEXTENDED ON、自動拡張不可(固定サイズ指定)の場合はAUTOEXTENDED ONにします。ALTER DATABASE文で変更ができます。
なんとなく、自動拡張の方が良い気がしますが、実はそういうわけではありません。特にフラッシュバック実現のためには自動拡張を不可にしておく必要があります。

フラッシュバック実現には自動拡張不可(固定サイズ)にする

フラッシュバック機能をザックリ言うと、「ある過去地点のデータを見たい!」と言うときに当時のデータを見せてくれる機能です。このある過去時点のデータはUNDOデータなのですが、かなり古い過去データを見るためにはその分、UNDOデータを残しておかないといけません。つまり、多くのUNDO表領域を確保しておく必要があります。
ここで自動UNDO管理の管理方法に戻りましょう。自動UNDO管理で表領域を管理するには自動拡張可と自動拡張不可(固定サイズを指定)がありました。一見、自動拡張可の方が効率的な表領域管理ができるように感じますが、自動拡張可の管理では一番時間がかかるSQLよりも少しだけが長く保存できるようUNDO保存期間が設定されています。つまりムダがない設定です。その代わり、余裕もありません。一方で自動拡張不可(固定サイズ指定)の場合は、好きなサイズを指定できるので、余裕を持った表領域サイズが設定できます。フラッシュバックを実現するには自動拡張不可(固定サイズ指定)にしておく必要があります。
とは言っても、では一体どれぐらいの固定サイズが最適なのか、という問題が出てきます。普通分からないですよね。大きすぎてもデータベースを圧迫するので良くありません。そのため、表領域のサイズを決めるときはEM ExpressのUNDOアドバイザという機能を参考にすると良いです。

UNDOアドバイザ

UNDOアドバイザは、データベースの稼働状況から適切なUNDO表領域のサイズを分析してくれます。フラッシュバック操作に対応できるUNDO表領域の最小サイズが確認できます。この情報を参考にすれば、フラッシュバックが成功し、かつ大きくなりすぎないUNDO表領域が設定できます。

UNDO表領域不足は即日対応の案件です

UNDO表領域が不足すると、データベース実行中にしばしばエラーが発生します。よく発生する問題がDML文の実行失敗と読み取り一貫性の維持不可です。
UNDO表領域に余裕がないので、SELECTやUPDATEなどのDMLは実行できなくなりますし、読み取り一貫性が維持できなくなるので「スナップショットが古すぎます。」のエラーが発生します。これはかなり大問題です。特に「DML実行ができない=システムが使えない」ので、即日対応が必要です。
UNDO表領域の問題はシステム全体の問題なので、UNDO表領域拡張などで早急に対策しましょう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です