隣の部署で障害発生

システムの「心臓」こと、Oracle Databaseに日々携わるたろーちゃん。
ある日、隣の部署のDさんがたろーちゃんの元に訪れました。
何かあったのでしょうか?

Dさん「たろーちゃん、ちょっと時間あるかな?」
たろー「あ、先輩。お疲れ様です。どうされました?」
Dさん「ずっと前に診てもらったこのシステムなんだけど、覚えてるかな?」
※Dさんのシステムについては、以前の記事『UNDO障害』を参照してください。

たろー「ああ、あれですか。ディスク容量を削減するために、相当ギリギリまで攻めた設計したシステムですよね?勿論覚えてますよ。」
Dさん「そうだ。あのシステムで、今度は一時表領域のデータファイルを格納しているディスクで障害が発生したんだ。」

たろー「確かこのシステムは、ノーアーカイブログモードで運用していて、深夜にストレージの スナップショット 機能を使ってコールドバックアップを取得しているんでしたよね?」
Dさん「その通りだ。一時表領域は障害が発生しても、次回インスタンス起動時に自動でデータファイルが作成される筈だから、この図のとおり、バックアップ対象にしていない。」
たろー「はい。」
Dさん「しかし、だ・・・。ディスク交換後にインスタンスを起動して、今日のバッチ処理を実行したところ、こんなエラーが発生したんだ。」


そう言うとDさんはノートパソコンを開き、たろーちゃんに画面を見せました。

Dさん
ORA-01652:一時セグメントを拡張できません(128 分、表領域 TEMP)


たろー
「一時表領域の容量不足ですか?」
Dさん「エラーメッセージはそうなんだが、障害発生前はこんなエラーは出ていなかったんだ。」
たろー「アプリ側の処理が変わったとか、多重で処理が動くようになったとか、そういったワークロードの変化はないですか?」
Dさん「俺もそう思ってアプリケーション部隊に確認したんだが、全く変わってないそうだ。むしろ今日の処理はいつもより軽いらしく、一時表領域が不足することは考えられないと言っていた。」
たろー「うーむ・・・。とりあえず一時表領域のサイズを確認してみましょう。」


たろーちゃんはノートパソコンに向かい、コマンドを入力しました。

SQL> select TABLESPACE_NAME, BYTES / 1024 / 1024 / 1024 from dba_temp_files ;

TABLESPACE_NAME                BYTES/1024/1024/1024
------------------------------ --------------------
TEMP                                              1


たろー
「ふむ。1GBか。」
Dさん「え?」
たろー「どうされました?」
Dさん「いや、このシステムの一時表領域のサイズは270GBの筈だ。1GBじゃ小さすぎる。」
たろー「でも、この実行結果を見る限り、確かに1GBですよ?」
Dさん「エラーが発生した直接原因はこれだな。単純に一時表領域が小さいんだ。
一時表領域のデータファイルって、再作成される場合は前より小さくなるものなのか?」
たろー「いや、そんなことはないと思うんですが・・・。ちょっと制御ファイルの中身を見てみましょう。」

SQL> ALTER DATABASE BACKUP CONTROLFILE TO TRACE ;

たろー「これで出力されたトレースファイルの中身を見てみれば・・・。」

■トレースファイル抜粋

  :::
 :::
ALTER TABLESPACE TEMP ADD TEMPFILE ' /opt/app/oracle/oradata/orcl/temp01.dbf'
     SIZE 276480M REUSE AUTOEXTEND OFF;   
 :::
 :::

たろー「本当だ。確かに制御ファイル上は 270GB(=276480MB)になってますね・・・。」
Dさん「どうしてこれで1GBになってしまうんだろう?」

 

一時表領域は、制御ファイルに記録されているサイズで再作成が
行われると思っていたけど、もしかして違うのか・・・?

 

 

 

 

 

Dさん「まぁ根本原因の追究はあと回しだ。とりあえず一時表領域のデータファイルサイズを大きくして業務を動かすよ。ありがとう、たろーちゃん。」


Dさんは一時表領域のデータファイルを270GBにリサイズし、業務で使えるようにしました。

Dさん

原因判明

たろー「どこかに何か書いてないかなぁ?」


納得のいかないたろーちゃんは、マニュアルを徹底的に読むことにしました。
すると・・・。

たろー「・・・あった!これか!」


何かを見つけたたろーちゃんは、Dさんのもとへ向かいました。

たろー「先輩、見つけましたよ。」
Dさん「何を?」
たろー「これをみて下さい。」


たろーちゃんは、マニュアルのこの箇所をDさんに見せました。

たろー「『17.3.2 データベース全体の完全リカバリの実行』によると、
『データベース全体のリストアおよびリカバリの後で、データベースがオープンされると、制御ファイルに記録された欠落している一時表領域は、以前の作成サイズ、AUTOEXTENDおよびMAXSIZE属性で再作成されます。欠落している一時表領域のみが再作成されます。』
と書かれています。」

Dさん「んん??分かりにくいな。つまりどういうことなんだ?」
たろー「『以前の作成サイズ、AUTOEXTENDおよびMAXSIZE属性で再作成される』ということは、つまり、CREATE DATABASE した時の状態で再作成されるって意味です。」
Dさん「なんだって?!」

Dさん

たろー「先輩、一時表領域は作成後にリサイズしたんじゃないですか?」
Dさん「ああ、そうだ。 DBCA でデータベースを作成した後に、リサイズした。」
たろーDBCA でデータベースを作成したとき、一時表領域のサイズはいくつで作成しましたか?」
Dさん「ちょっと待てよ。 DBCA でデータベースを作成したときに、スクリプトも一緒に出力するようにしたんだ。それを見れば・・・。」


Dさんはサーバにログインし、スクリプトを開きました。

■/u01/app/oracle/admin/orcl/scripts/CreateDB.sql ファイル抜粋

SET VERIFY OFF
connect "SYS"/"&&sysPassword" as SYSDBA
set echo on
spool /u01/app/oracle/admin/orcl/scripts/CreateDB.log append
startup nomount pfile="/u01/app/oracle/admin/orcl/scripts/init.ora";
CREATE DATABASE "orcl"
MAXINSTANCES 32
MAXLOGHISTORY 1
MAXLOGFILES 192
MAXLOGMEMBERS 3
MAXDATAFILES 1024
DATAFILE SIZE 1024M
EXTENT MANAGEMENT LOCAL
SYSAUX DATAFILE SIZE 1024M,
BIGFILE DEFAULT TEMPORARY TABLESPACE TEMP TEMPFILE SIZE 1024M EXTENT MANAGEMENT LOCAL UNIFORM SIZE 4M
SMALLFILE UNDO TABLESPACE "UNDOTBS1" DATAFILE  SIZE 1024M
  :::
  :::
  :::
  :::

 

Dさん「ビンゴだよ、たろーちゃん。
CREATE DATABASE したときは、1GB(=1024MB)で作成してある。」
たろー「だから1GBで再作成されたんですね。」
Dさん「えー?!どうして制御ファイルに記録されてあるサイズで再作成してくれないんだよ?こんなの分からないって。」
たろー「うーむ、私もそう思います。。。これが仕様なんでしょうね。」

 

仕様だけに『しょうがない』ってか?
笑えない冗談だな。はっはっは。

 

 

 

 

 

せ、先輩・・・。つまらなくて、マジで笑えないです・・・。

 

 

 

 


今回の「心臓外科医の術式」いかがだったでしょうか?
一時表領域のデータファイルは RMAN でもバックアップが取得されません。
一時表領域に障害が発生して、データファイルが自動で再作成されたあとは、あるべき姿(正しいサイズ)になっていることを、必ず確認するようにしましょう。
次回も頑張りますので、応援よろしくお願い致します。

投稿者プロフィール

たろーちゃん
たろーちゃん
株式会社システムサポート インフラソリューション事業部に在籍するPlatinumホルダー。
Oracle Databaseのパフォーマンスチューニングを得意とする。
データベースは Oracle 以外興味がないという変わり者。
一番嫌いなエラーメッセージは CRS-02625。
連載「心臓外科医の術式」を執筆。