UNDOに関する検証 その3

投稿日: 2003年1月29日

<UNDOに関する検証その3>
ペンネーム:クレイジーボーダー

前回は、UNDO表領域の切替えを行った。UNDO表領域変更中に実行されていた
トランザクションは、引き続き変更前のUNDO表領域を使用する。また、その
UNDO表領域はONLINEモードからPENDING OFFLINEモードに変わる。そのため、
変更前の表領域は使用中のために削除できない。

SQL> DROP TABLESPACE UNDOTBS_02;
DROP TABLESPACE UNDOTBS_02
*
ERROR at line 1:
ORA-30013: undo tablespace 'UNDOTBS_02' is currently in use

全てのトランザクションがコミットされた後は、自動的にOFFLINEになり、
削除できる。ここまでが前回の内容だが、ここで疑問が1つでてきた。
初期化パラメータ(UNDO_RETENTION)との関係だ。UNDO_RETENTIONとは、UNDO
データを保存する期間を秒単位で指定するものであり、デフォルト値は15分
(900秒)であるが、削除されるタイミングが UNDO_RETENTION で設定した期
間内ならどうなるだろうか?

今回は、フラッシュバック問合せを使用して検証してみる。フラッシュバック
問合せの詳細については過去のメルマガを参照して欲しい。

まず、現在のUNDOに関連した初期化パラメータは以下のようになっている。

SQL> SHOW PARAMETER UNDO
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------
UNDO_MANAGEMENT                      STRING      AUTO
UNDO_RETENTION                       INTEGER     10800
UNDO_SUPPRESS_ERRORS                 BOOLEAN     FALSE
UNDO_TABLESPACE                      STRING      UNDOTBS_02

UNDOデータの保存期間は、デフォルトでは15分しかないので3時間(10800秒)
に変更し起動させた。

それでは、フラッシュバック問合せが使用できるよう、SYSユーザで
DBMS_FLASHBACKの実行権限をMAGに与える。
<ユーザSYSのSQL文>

SQL> GRANT EXECUTE ON DBMS_FLASHBACK TO MAG;

ユーザMAGの表(TBL_MAG1)の行数を確認する。
<ユーザMAGのSQL文>

SQL> SELECT TO_CHAR(SYSDATE, 'HH24:MI') AS TIME, COUNT(*)
     FROM TBL_MAG1;

TIME    COUNT(*)
----- ----------
13:10         11

現在アクティブなトランザクションは実行されていない。別ターミナルから
ユーザMAGで、insert文を実行する。
<ユーザMAGのSQL文>

SQL> INSERT INTO TBL_MAG1 VALUES (134, 'MAG_0128');
1 ROW CREATED.

ここで現在UNDOセグメントの使用状況を見てみる。
<ユーザSYSのSQL文>

SQL> SELECT S.USERNAME, T.XIDUSN, T.UBAFIL, T.UBABLK, T.USED_UBLK,
  2  RN.NAME AS "SEGMENT", RS.STATUS, RS.EXTENTS, RS.RSSIZE,
  3  RS.HWMSIZE, RS.XACTS, DF.STATUS AS "FILE STATUS",
  4  DF.NAME AS "FILE", TS.NAME AS "TABLESPACE"
  5  FROM V$SESSION S, V$TRANSACTION T, V$ROLLNAME RN, V$ROLLSTAT RS,
  6  V$DATAFILE DF, V$TABLESPACE TS
  7  WHERE S.SADDR = T.SES_ADDR
  8  AND T.XIDUSN = RN.USN
  9  AND RN.USN = RS.USN
 10  AND T.UBAFIL = DF.FILE#
 11  AND TS.TS# = DF.TS#;

USERNAME  XIDUSN  UBAFIL  UBABLK  USED_UBLK  SEGMENT     STATUS
--------  ------  ------  ------  ---------  ----------  ------
MAG       16      5       355     1          _SYSSMU16$  ONLINE

EXTENTS  RSSIZE  HWMSIZE  XACTS  FILE STATUS
-------  ------  -------  -----  -----------
2        129024  129024   1      ONLINE

FILE                                           TABLESPACE
---------------------------------------------  ----------
/export/home/mag920/oradata/mag920/undo02.dbf  UNDOTBS_02

UNDOセグメントを使用しているようなので、ユーザMAGでコミットを行なう。
<ユーザMAGのSQL文>

SQL> COMMIT;
COMMIT COMPLETE.

SQL> SELECT COUNT(*) FROM TBL_MAG1;

  COUNT(*)
----------
        12

再度、ユーザSYSで、先ほどUNDO情報を取得したSQL文を実行すると、コミット
後なので、何も選択されない。
<ユーザSYSのSQL文>

SQL> SELECT S.USERNAME, T.XIDUSN, T.UBAFIL, T.UBABLK, T.USED_UBLK,
  2  RN.NAME, RS.STATUS, RS.EXTENTS, RS.RSSIZE, RS.HWMSIZE, RS.XACTS,
  3  DF.STATUS AS "FILE STATUS", DF.NAME AS "FILE",
  4  TS.NAME AS "TABLESPACE"
  5  FROM V$SESSION S, V$TRANSACTION T, V$ROLLNAME RN, V$ROLLSTAT RS,
  6  V$DATAFILE DF, V$TABLESPACE TS
  7  WHERE S.SADDR = T.SES_ADDR
  8  AND T.XIDUSN = RN.USN
  9  AND RN.USN = RS.USN
 10  AND T.UBAFIL = DF.FILE#
 11  AND TS.TS# = DF.TS#;

NO ROWS SELECTED

ユーザMAGでフラッシュバック問合せを利用し、過去のデータを取得できるこ
とを確認する。
<ユーザMAGのSQL文>
時間指定を簡単に行なう為、NLS_TIMESTAMP_FORMATを変更する。

SQL> ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY/MM/DD HH24:MI:SS';

コミット前のデータを取得してみる。

SQL> EXECUTE DBMS_FLASHBACK.ENABLE_AT_TIME('2003/01/28 13:10:00');
PL/SQL PROCEDURE SUCCESSFULLY COMPLETED.

SQL> SELECT COUNT(*) FROM TBL_MAG1;

  COUNT(*)
----------
        11

SQL> EXECUTE DBMS_FLASHBACK.DISABLE;
PL/SQL PROCEDURE SUCCESSFULLY COMPLETED.

UNDOデータの保存期間内であることを確認し、UNDO表領域を変更し削除する。

SQL> ALTER SYSTEM SET UNDO_TABLESPACE='UNDOTBS_01';
SYSTEM ALTERED.

SQL> DROP TABLESPACE UNDOTBS_02;
TABLESPACE DROPPED.

UNDO_RETENTIONで設定した期間内でも削除することができた。

UNDO表領域は削除されてしまい、データが無い状態になった。確認としてユー
ザMAGでフラッシュバック問合せを実行する。データがデータベース・バッファ
から追い出された後から実行すると以下の結果となる。

<ユーザMAGのSQL文>

SQL> EXECUTE DBMS_FLASHBACK.ENABLE_AT_TIME('2003/01/28 13:10:00');
PL/SQL PROCEDURE SUCCESSFULLY COMPLETED.

SQL> SELECT COUNT(*) FROM TBL_MAG1;
SELECT COUNT(*) FROM TBL_MAG1

ERROR AT LINE 1:
ORA-01555: SNAPSHOT TOO OLD: ROLLBACK SEGMENT NUMBER  WITH NAME ""
TOO SMALL

UNDOデータが無いために、ORA-01555のエラーが出力されたのである。

まとめると、UNDO表領域の削除は、UNDO_RETENTIONで設定した期間内でも削除
できてしまい、フラッシュバック問合せができなくなる。
要するに削除する際は注意が必要である。

次回は、V$UNDOSTATを使用してこのUNDO_RETENTIONについて検証していきたい。

以上、雪がなかなか降らない茅ヶ崎にて