しばちょう先生の試して納得!DBAへの道 indexページ▶▶


みなさん、こんにちは。サクラ満開な中、執筆に苦しんでいる”しばちょう”こと柴田長(しばた つかさ)です。

さて、連載28回目にして初登場?という今更感は否めませんが、執筆開始時の初心でもある「DBAへの道」に従うべく、データベース管理の基本であるUNDO表領域の管理を取り上げたいと思います。

最近ではUNDO表領域のサイズとUNDOの保存期間だけを指定する自動UNDO管理が主流であり、Oracle Databaseが内部的にUNDOの保存期間を自動チューニングする機能により、ORA-1555(読取一貫性エラー)の発生が抑制されています。このような背景もあり、UNDO表領域はDBAのチューニング対象から外れているケースがあるかもしれませんが、ORA-1555が発生しなくとも実はパフォーマンスの問題が発生しているかもしれません。

私自身、パフォーマンス・テスト中に思い通りの結果が出ていない場合に、UNDO表領域が枯渇していたという経験があり、ORA-1555が出ていないからこそ発見が遅れたりしていました。と言う事を、複数回にわたり皆さんにも体験して頂きたいと思っています。今回はUNDOの保存期間の自動チューニングの動作について確認していきましょう。

以下の演習をOracle Database 11g Release 2 Enterprise Editionのデータベースで試してみてください。

1. 次のSQLを実行し、TRYスキーマ上に約100MBの更新用の表およびCOL1列に対する主キーを作成して下さい。

$ sqlplus / as sysdba
SQL> 
-- TBS28表領域と、この表領域をデフォルト表領域とするTRYユーザーの作成
create tablespace TBS28 datafile '+DATA(DATAFILE)' size 500m ;
create user TRY identified by TRY default tablespace TBS28 ;
grant CONNECT, RESOURCE, DBA to TRY ;

-- TAB28表の作成
connect TRY/TRY
create table TAB28 (COL1 number not null, COL2 date, COL3 number, COL4 char(1000)) ;

-- 約100MBのレコードを挿入
insert /*+append */ into TAB28
  select LEVEL, SYSDATE, mod(LEVEL,10), 'initial'
   from DUAL
 connect by LEVEL <= 7 * 128 * 100 ;
commit ;

-- COL1列にユニーク索引を作成し、主キーとして登録
create unique index PK_TAB28 on TAB28(COL1) ;
alter table TAB28 add primary key(COL1) using index PK_TAB28 ;

-- TAB28表と主キーのセグメント・サイズを確認
col SEGMENT_NAME for a16
select SEGMENT_NAME, SEGMENT_TYPE, BYTES/1024/1024 from USER_SEGMENTS ;

SEGMENT_NAME     SEGMENT_TYPE       BYTES/1024/1024
---------------- ------------------ ---------------
PK_TAB28         INDEX                            2
TAB28            TABLE                          104

はい、毎度お馴染みの指の準備運動ですね。今回は特別変わったことはしていませんので、説明を割愛させて頂きます。

もし、この連載を初めて読まれた方は、是非とも以前の回の演習1番目の解説にも目を通して頂ければ、何か面白い事が解説されているはず。。。

 

2. 新規に、100MBのUNDO表領域(UNDOTBS28)を作成してください。ただし、自動拡張可能で最大サイズが100MBの一つのデータファイルで構成して下さい。

$ sqlplus / as sysdba
SQL>
-- UNDO表領域の作成
create undo tablespace UNDOTBS28
  datafile '+DATA(DATAFILE)' size 100m autoextend on next 8m maxsize 100m ;

-- 作成したUNDO表領域の確認
set lines 150 pages 50000
col FILE_NAME for a50
select FILE_ID, FILE_NAME, TABLESPACE_NAME, BYTES/1024/1024 "MB",
       AUTOEXTENSIBLE, MAXBYTES/1024/1024 "MAXMB"
  from DBA_DATA_FILES
 where TABLESPACE_NAME = 'UNDOTBS28' ;

FILE_ID FILE_NAME                                   TABLESPACE_NA    MB AUTOEXTENS MAXMB
------- ------------------------------------------- ------------- ----- ---------- -----
      5 +DATA/orcl/datafile/undotbs28.259.843945455 UNDOTBS28       100 YES          100

今回の連載の主役でもあるUNDO表領域を新規に作成して頂きましたが、如何ですか?

通常の表領域を作成するSQL文とほとんど同じですよね。一点違いがあるとすれば、「UNDO」句を付け加えるだけですね。なので、改めてUNDO表領域を作成するSQL文をリファレンス・マニュアルで調査する必要はほとんど無かったりします。

とは言え、演習問題には「自動拡張可能で最大サイズが100MB」という条件が含まれている点に注意です。

まあ、自動拡張可能という部分には疑問を抱かないかもしれませんが、最大サイズが100MBという部分は既にデータファイルを100MBで作成しているので、「結局拡張できないじゃん! 演習問題のミスじゃないの?」となりますよね。しかし、演習問題は正しいです。私は自動拡張可能だけど、実際には拡張しないUNDO表領域を作りたかったのです。その理由は追ってご紹介していくことにしましょう。

 

3. 演習2で作成したUNDO表領域UNDOTBS28を使用した自動UNDO管理に設定して下さい。また、UNDO保存期間はデフォルトの900秒に設定されていることを確認して下さい。

$ sqlplus / as sysdba
SQL>
-- UNDO管理に関連する初期化パラメータの現在の設定値を確認
show parameter undo_

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

-- UNDO表領域の変更
alter system set undo_management='AUTO' scope=SPFILE ;
alter system set undo_retention=900 scope=SPFILE ;
alter system set undo_tablespace='UNDOTBS28' scope=SPFILE ;

shutdown immediate
startup

-- UNDO管理に関連する初期化パラメータの新規の設定値を確認
show parameter undo_

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS28

ほとんどの方は自動UNDO管理を使用されてデータベースを運用されていると思っているので、この演習は簡単ですね。

自動UNDO管理を使用する為には、最低でも3つの初期化パラメータを設定する必要があります。今回はSPFILE上で設定した後にインスタンスを再起動している為、設定する順番は気にする必要がありません。

自動UNDO管理を有効化する為にはUNDO_MANAGEMENT初期化パラメータを「AUTO」に指定します。次に、その自動UNDO管理で使用するUNDO表領域を指定するUNDO_TABLESPACE初期化パラメータを設定します。最後に、UNDOブロックの保存期間を指定するUNDO_RETENTION初期化パラメータを設定します。ちなみに、UNDO_MANAGEMENT初期化パラメータ以外はインスタンス再起動無しに変更することが可能であることを覚えておきましょう。UNDO表領域を別のUNDO表領域へ切替たい場合に重宝しますよ。

さて、900秒(15分)に設定したUNDO_RETENTION初期化パラメータで制御されるUNDOブロックの保存期間とは何でしょう?復習になると思いますが、UNDOとはデータベースの変更をロールバックまたは取り消すために使用する情報で、この情報があるからこそ、Oracle Databaseは読取一貫性を提供することが出来ていたりします。これを理解する為には、次の演習を体験して頂いた方が手っ取り早いと思います。

4. 次のSELECT処理とUPDATE処理を同時に実行し、SELECT文で読取一貫性エラー(ORA-1555)が発生することを確認してください。

$ sqlplus /nolog
SQL>
-- SELECT処理の準備
connect TRY/TRY
alter session set NLS_DATE_FORMAT='YYYY/MM/DD HH24:MI:SS' ;
select SYSDATE from DUAL ;

SYSDATE
-------------------
2014/04/03 21:21:57

-- トランザクション・レベルの読取り一貫性を設定
SET TRANSACTION READ ONLY NAME 'hogehoge' ;


-- 約5分間継続するTAB28表の更新処理(シェルスクリプト)を実行
SQL> !
$ ### SQL*Plusから一旦抜けた状態でシェルを実行
minvalue=1
maxvalue=89600
interval=300
i=${maxvalue}
while [ $i -gt 0 ]; do
  echo "update TAB28 set COL4='updated'
        where COL1 between (${i} - $interval + 1) and ${i} ;" ;
  echo "commit;" ;
  i=`expr $i - $interval` ;
  sleep 1 ;
done | sqlplus -s TRY/TRY


### SQL*Plusへ戻る為に「exit」
$ exit
SQL>
select SYSDATE from DUAL ;

SYSDATE
-------------------
2014/04/03 21:27:12


-- TAB28表の全件検索
select sum(COL3) from TAB28 ;

ERROR at line 1:
ORA-01555: snapshot too old: rollback segment number 14
           with name "_SYSSMU14_1314829549$" too small

ORA-1555が出ましたね!「スナップショットが古すぎます」という解読不能なエラー・メッセージですが、これが読取一貫性エラーです。簡単に言ってしまえば、「UNDO表領域が小さいので、読取一貫性を提供する為に必要なUNDO情報が上書きしちゃいました。なので、読取一貫性を提供することが出来ませんでした。」というものです。と言う事が理解できれば、UNDO表領域を大きくすれば良いと言うのが解決策になるわけですが、その前に少し上記の回答例を解説しておきましょう。

まず、「21:21:57」付近で「SET TRANSACTION READ ONLY NAME ‘hogehoge’ ;」コマンドを実行している「トランザクション・レベルの読取り一貫性を設定」が大切なポイントです。このコマンドを実行したことで、このトランザクションに限定して以降に実行する全ての問合せにおいて、トランザクション開始前にコミットされたデータのみが参照されることになります。

とは言え、まだ問合せは実行せずに、5分間継続してTAB28表を全件更新する処理を実行して、UNDO情報を生成してみます。これにより、データ・ブロックは最新のデータ変更が反映された状態に変化してしまいましたね。

次に、先ほど「21:21:57」付近に読取り一貫性を設定したトランザクションにおいて、更新処理が完了後の「21:27:12」にTAB28表に問合せを実行しています。この場合、「21:21:57」以降にデータ変更/Commitされたデータは参照されず、「21:21:57」よりも前にコミットされていたデータだけが参照されると言う事になるので、最新のデータ変更が反映された状態のデータ・ブロックでは「21:21:57」よりも前のデータだけを参照することは不可能です。その為に、以前のデータ・ブロックを作り出す必要があり、UNDO情報を使用してメモリ上でブロックのロールバックが試行されますが、そのUNDO情報が消えてしまっていてORA-1555が発生してしまった。という流れになります。

ここでUNDO情報の保持期間を何秒に設定していたのかを思い出してみてください。UNDO_RETENTION初期化パラメータでは900秒(15分)を設定していましたよね?しかし、今回のケースでは5分前のUNDO情報が消えてしまっていると言う事になりますから、どうもこの設定が反映されていないのでは?と疑いたくなってきましたねー。面白くなってきましたねー。では、演習を進めていきましょう!

ちなみに、今回はORA-1555の再現を簡単にする為に「トランザクション・レベルの読取一貫性」を設定していますが、デフォルトでは「文レベルの読取り一貫性」が設定されており、問合せ文を実行したタイミングでコミットされているデータが参照対象となります。つまり通常の運用では、参照処理を含む実行時間が長いSQL文においてORA-1555が発生する可能性が高くなります。

5. UNDO表領域の使用量を確認してください。

$ sqlplus /nolog
SQL>
connect / as sysdba

-- UNDO 表領域の使用率 = (ACTIVE + UNEXPIRED のエクステントサイズ) / UNDO 表領域全体のサイズ
select to_char(sysdate,'YYYY/MM/DD HH24:MI:SS') "TIME",
       round("USED_SIZE(MB)", 3) "USED(MB)",
       round("TBS_SIZE(MB)", 3)  "TBS(MB)",
       round("USED_SIZE(MB)"/"TBS_SIZE(MB)" * 100, 3) "USAGE(%)"
  from (select sum(BYTES)/1024/1024 "USED_SIZE(MB)"
          from DBA_UNDO_EXTENTS
         where STATUS in ('ACTIVE', 'UNEXPIRED')
           and TABLESPACE_NAME = 'UNDOTBS28') ,
       (select sum(BYTES)/1024/1024 "TBS_SIZE(MB)"
          from DBA_DATA_FILES
         where TABLESPACE_NAME = 'UNDOTBS28') ;

TIME                  USED(MB)    TBS(MB)   USAGE(%)
------------------- ---------- ---------- ----------
2014/04/03 21:28:52         58        100         58


-- STATUS毎のエクステントサイズの確認
select STATUS, sum(BYTES)/1024/1024
  from DBA_UNDO_EXTENTS
 where TABLESPACE_NAME = 'UNDOTBS28'
 group by STATUS ;

STATUS    SUM(BYTES)/1024/1024
--------- --------------------
UNEXPIRED                   41
EXPIRED                     58


-- UNDOTBS28表領域内のセグメントの合計サイズ
select TABLESPACE_NAME, sum(BYTES)/1024/1024
  from DBA_SEGMENTS
 where TABLESPACE_NAME = 'UNDOTBS28'
 group by TABLESPACE_NAME ;

TABLESPACE_NAME  SUM(BYTES)/1024/1024
---------------- --------------------
UNDOTBS28                          99

まずは、DBA_UNDO_EXTENTSビューを参照して、UNDO表領域内でACTIVE(使用中)もしくはUNEXPIRED(解放不可)なステータスのエクステントの合計サイズを確認してみると、UNDO表領域のサイズが100MBに対して58MB程度しか、使用されていないことが確認できます。しかし、この情報だけで「まだ空きがあったのでは?」と思ってしまってはダメです。もちろん、この問合せを実行したタイミングでは空きがあります。それは正しいですが、演習4の5分間の更新処理を実行している最中にも空きがあったとは言い切れないからです。では、どのように確認するべきかと言うと、私は3つの方法があると思っています。

一つ目はDBA_UNDO_EXTENTSビューへの問い合わせで、ステータス毎にエクステントのサイズを合計して確認する方法、二つ目はUNDO表領域内のセグメントの合計サイズを確認する方法です。例えば、DBA_SEGMENTSビューであれば、かつて99MBまで使用された形跡を確認することができるので、領域が枯渇していたことがあるという事実を把握できますね。

三つ目は定期的にDBA_UNDO_EXTENTSビューを参照しておくことです。以下は、演習4における5分間の更新処理中に、UNDO表領域の使用率を確認するクエリーを30秒間隔で実行しておいた結果です。

-- UNDO 表領域の使用率を確認するクエリーを約30秒間隔で実行した結果を成形

TIME                  USED(MB)    TBS(MB)   USAGE(%)
------------------- ---------- ---------- ----------
2014/04/03 21:21:50       .625        100       .625
2014/04/03 21:22:20     15.125        100     15.125
2014/04/03 21:22:51         27        100         27
2014/04/03 21:23:21         38        100         38
2014/04/03 21:23:51         53        100         53
2014/04/03 21:24:22         67        100         67
2014/04/03 21:24:52         81        100         81
2014/04/03 21:25:23      82.75        100      82.75
2014/04/03 21:25:54     96.938        100     96.938
2014/04/03 21:26:24     92.563        100     92.563
2014/04/03 21:26:54         99        100         99
2014/04/03 21:27:24         90        100         90
...
2014/04/03 21:30:50         58        100         58

この結果を見れば一目瞭然ですね。更新処理を開始直後は0.625MBしか使用されていませんでしたが、徐々に使用量が増加して「21:25:54」~「21:27:24」の間では100MBの手前で使用量が増減していることが確認できます。結論としては、更新処理中にUNDO表領域が枯渇した為、UNDO_RETENTION初期化パラメータの900秒を無視して古いUNDO情報が上書きせざるを得なかったと言う事を推測することが出来ましたね。

では、過去何秒までのUNDO情報であれば保持されていたのでしょうか?また、UNDO表領域を100MBからどの程度まで大きくすれば、今回の問題は回避できるのでしょうか?という2つの疑問を次の演習6で解決して差し上げましょう。

6. V$UNDOSTATビューを問い合わせて、演習4を実行したタイミングにおける自動チューニングされたUNDO保存期間の値を確認してください。

$ sqlplus /nolog
SQL>
connect / as sysdba
set linesize 150 pages 50000
alter session set NLS_DATE_FORMAT='HH24:MI:SS' ;
select BEGIN_TIME, END_TIME, TUNED_UNDORETENTION,
       UNDOBLKS, TXNCOUNT, MAXQUERYLEN, MAXQUERYID, MAXCONCURRENCY
  from V$UNDOSTAT
 order by 2 ;

BEGIN_TI END_TIME TUNED_UNDORETENTION UNDOBLKS TXNCOUNT MAXQUERYLEN MAXQUERYID    MAXCONCURRENCY
-------- -------- ------------------- -------- -------- ----------- ------------- --------------
21:02:43 21:12:43                1183        2       23         343 0rc4km05kgzb9              1
21:12:43 21:22:43                1786     1261      501         944 0rc4km05kgzb9              3
21:22:43 21:32:43                 342    16030      639         342 0rc4km05kgzb9              2
21:32:43 21:42:43                 679        2       61         944 0rc4km05kgzb9              1

さて、今回の連載の目玉である、V$UNDOSTATビューの登場です。

このビューには、10分間隔で過去4日間分のUNDO関連の統計情報が格納されており、上記の赤文字のレコードが演習4において5分間の更新処理を実行していたタイミングのものとなります。更新処理を実行していた形跡として、10分間で生成されたUNDOブロックの数が16,030個と他の期間よりも圧倒的に多く、トランザクション数(TXNCOUNT)も多い傾向となっています。そして注目はTUNED_UNDORETENTION列であり、342秒と一番小さな値になっていることが確認できます。実は、このTUNED_UNDORETENTIONが「自動チューニングされたUNDO保存期間」の値であり、UNDO_RETENTION初期化パラメータで指定した900秒では無く、342秒しかUNDO情報を保存することが出来なかったことを(恐らく)示しています。

ここで、一旦ですが、自動チューニングされたUNDO保存期間について解説しておきましょう。Oracle Databaseでは、UNDOの保存期間が自動チューニングされます。とは言え、UNDO表領域が自動拡張可能か否かによって、少し動作が変わってきます。

+ UNDO表領域が自動拡張可能(AUTOEXTEND ON)な場合

1. データベース内で最も長く実行されたクエリーよりも長くなるように保存期間を動的にチューニングします。

2. UNDO_RETENTION初期化パラメータで指定された最小保存期間を維持しようとします。

3. そのため、UNDO表領域の空き領域が少なくなるとUNDOを上書きしないように自動的に拡張します。

4. ただし、MAXSIZE句に指定されているサイズまで拡張した場合は、期限切れではないUNDOを上書きします。

+ UNDO表領域が固定(AUTOEXTEND OFF)の場合

1. 現行のUNDO生成量がUNDO表領域のサイズに収まるようにUNDO保存期間を動的にチューニングします。

2. UNDO_RETENTION初期化パラメータは無視されます。

3. UNDO表領域の領域が不足した場合、期限切れではないUNDOを上書きします。

上記の情報は、実はOracle Database管理者ガイドの「16 UNDOの管理」に記載されていたりしますので、マニュアルの重要性を改めて思い知らされる内容ですよね。でもって、私が演習2において「自動拡張可能」なUNDO表領域を作成した意図としては上記の青文字部分を採用したかったからです。とは言え、際限なく自動拡張されてしまうのも避けるためにMAXSIZEで指定する値をデータファイルのサイズと同じにして、実質的に自動拡張OFFの状態を作り出すという一つのアイディアです。

さて、UNDO表領域のサイズをどの程度まで拡張すれば良いのかという話に移りましょう。一番のお勧めの方法としては、Oracle Enterprise ManagerのUNDOアドバイザを使用することですので、環境がある方は是非とも試して頂きたいと思います。

もしも、ザックリな見積もりでも良い、私に責任を追及しないという方のみ、次の方法を使ってみてください。とは言え、単純な小学校の算数(比の計算)です。TUNED_UNDORETENTIONがUNDO_RETENTIONよりも小さい場合にだけ使用して下さい。

shibacho-28-1.png

 

7. UNDO表領域UNDOTBS28を270MBへ拡張して下さい。

$ sqlplus / as sysdba
SQL> 
-- 拡張前の状態を再確認
set lines 150 pages 50000
col FILE_NAME for a50
select FILE_ID, FILE_NAME, TABLESPACE_NAME, BYTES/1024/1024 "MB",
AUTOEXTENSIBLE, MAXBYTES/1024/1024 "MAXMB"
  from DBA_DATA_FILES
 where TABLESPACE_NAME = 'UNDOTBS28' ;
FILE_ID FILE_NAME                                   TABLESPACE_NA    MB AUTOEXTENS MAXMB
------- ------------------------------------------- ------------- ----- ---------- -----
      5 +DATA/orcl/datafile/undotbs28.259.843945455 UNDOTBS28       100 YES          100


-- 270MBへ拡張
alter database datafile 5 resize 270m ;
alter database datafile 5 autoextend maxsize 270m ;


-- 拡張後の状態を確認
set lines 150 pages 50000
col FILE_NAME for a50
select FILE_ID, FILE_NAME, TABLESPACE_NAME, BYTES/1024/1024 "MB",
AUTOEXTENSIBLE, MAXBYTES/1024/1024 "MAXMB"
  from DBA_DATA_FILES
 where TABLESPACE_NAME = 'UNDOTBS28' ;
FILE_ID FILE_NAME                                   TABLESPACE_NA    MB AUTOEXTENS MAXMB
------- ------------------------------------------- ------------- ----- ---------- -----
      5 +DATA/orcl/datafile/undotbs28.259.843945455 UNDOTBS28       270 YES          270

演習6で見積もったUNDO表領域のサイズへ拡張して頂きました。

今回の表領域はBig File表領域では無いので、一つの表領域に複数のデータファイルが存在する可能性があります。その為、データファイル単位でサイズをリサイズする必要があります。となると、データファイル名を入力しなければならないと思いがちですが、データファイル番号を指定する方法もあるので、上記の回答例では、「5」番のデータファイルを指定して拡張しています。

また、RESIZE句ではデータファイルの最大サイズ(上記では100MB)を越えて拡張(上記では270M)することができてしまう点と、最大サイズが変更されないという二つの点は把握しておいた方が良いでしょう。最大サイズを増加させるには、改めて「autoextend」句で「maxsize」を指定し直す必要があります。

8. 演習4を再実行した際に、UNDO 表領域の使用量が上限に達しないことを30秒間隔で確認してください。また、チューニング済みUNDO保存期間の値が、UNDO_RETENTION初期化パラメータの設定値(900秒)を下回っていないことも確認してください。

$
vi undo_usage.sql
-----
select to_char(sysdate,'YYYY/MM/DD HH24:MI:SS') "TIME",
       round("USED_SIZE(MB)", 3) "USED(MB)",
       round("TBS_SIZE(MB)", 3)  "TBS(MB)",
       round("USED_SIZE(MB)"/"TBS_SIZE(MB)" * 100, 3) "USAGE(%)"
  from (select sum(BYTES)/1024/1024 "USED_SIZE(MB)"
          from DBA_UNDO_EXTENTS
         where STATUS in ('ACTIVE', 'UNEXPIRED')
           and TABLESPACE_NAME = 'UNDOTBS28') ,
       (select sum(BYTES)/1024/1024 "TBS_SIZE(MB)"
          from DBA_DATA_FILES
         where TABLESPACE_NAME = 'UNDOTBS28') ;
-----

$ ### undo_usage.sqlを30秒間隔で実行(Linux環境)
while true; do
  cat undo_usage.sql
  sleep 30
done | sqlplus –s / as sysdba

-- 上記の実行結果を成形
TIME                  USED(MB)    TBS(MB)   USAGE(%)
------------------- ---------- ---------- ----------
2014/04/03 23:52:36      28.12        270     10.417
2014/04/03 23:53:07      40.25        270     14.907
2014/04/03 23:53:37      56.25        270     20.833
2014/04/03 23:54:08      68.25        270     25.278
2014/04/03 23:54:38      83.25        270     30.833
2014/04/03 23:55:09      99.25        270     36.759
2014/04/03 23:55:39     114.25        270     42.315
2014/04/03 23:56:10     129.25        270     47.870
2014/04/03 23:56:40     143.25        270     53.056
2014/04/03 23:57:11     159.25        270     58.981
2014/04/03 23:57:41     163.25        270     60.463


-- チューニング済みUNDO保存期間の確認
$ sqlplus / as sysdba
SQL>
set linesize 150 pages 50000
alter session set NLS_DATE_FORMAT='HH24:MI:SS' ;
select BEGIN_TIME, END_TIME, TUNED_UNDORETENTION,
       UNDOBLKS, TXNCOUNT, MAXQUERYLEN, MAXCONCURRENCY
  from V$UNDOSTAT
 order by 2 ;

BEGIN_TI END_TIME TUNED_UNDORETENTION UNDOBLKS TXNCOUNT MAXQUERYLEN MAXQUERYID    MAXCONCURRENCY
-------- -------- ------------------- -------- -------- ----------- ------------- --------------
23:52:43 00:02:43                1785    14661      327         945 0rc4km05kgzb9              3

さあ、最後の演習です。上記回答例では再実行部分は記述しておりませんが、皆さんの環境でも問題無く(ORA-1555の読取一貫性エラーが発生することなく)、SELECT文の結果が戻ってきたと信じています。

UNDO表領域の使用量(ACTIVE or UNEXPIREDなエクステントの合計サイズ)を30秒間隔で取得した結果からは、見事に270MBの上限に達することなく5分間の更新処理が完了したことを確認することが可能です。少し使用率が高いように思われますが、前回生成されたUNDO情報が20MB前後残っている状態から計測し始めた為であるとお断りしておきます。また、V$UNDOSTATビューを確認する限り、1785秒間分のUNDO情報を保持する用にUNDO保持期間が自動チューニングされていることからも、UNDO表領域のサイズが十分であることが確認できますね。

繰り返しになりますが、適切なUNDO表領域のサイズ見積もりは、Oracle Enterprise ManagerのUNDOアドバイザを使用することをお勧めします。合わせて、表領域の空き領域サイズの監視+通知も実装できますので非常に有効に活用して頂けます。

さて、いかがでしたでしょうか?

データベース管理の基本でもあるUNDO表領域の管理ですが、意外にも少し難しい部分を感じて頂けたかなと思っています。特に、UNDO表領域の自動拡張or固定によって内部的に自動チューニングされるUNDO保持期間の動きが変わる部分については、忘れてしまっていた方も多いと思うので、復習になったのであれば幸いです。今回は、読取一貫性エラー(ORA-1555)の発生を抑止する為のUNDO表領域のサイズ見積もりについて体験して頂きましたが、次回は更新処理のパフォーマンス・ダウンを避ける為のUNDO表領域のサイズ設定について、待機イベントを絡めて解説させて頂く予定でおりますので、楽しみにしていて下さい。

今回も最後まで体験して頂きましてありがとうございました。次回以降もどうぞよろしくお願い致します。サクラを見に北上してきます!


ページトップへ戻る▲

 

しばちょう先生の試して納得!DBAへの道 indexページ▶▶