新人Tさんの相談

システムの「心臓」こと、Oracle Databaseに日々携わるたろーちゃん。
たろーちゃんのもとに、新人のTさんが訪れました。
Tさんは随分と困った顔をしています。何かあったのでしょうか?

新人T「お疲れ様です、たろーさん。」
たろー「Tさん、お疲れ様。例のシステムはその後、順調に動いてるかい?」
新人T「はい。その節はありがとうございました。おかげ様で復旧後も無事に動作しています。
バックアップ方式も、たろーさんに教えて頂いた方法に変更しました。」
※Tさんのシステムについては、以前の記事『動かない心臓』を参照してください。

たろー「今日はどうしたの?随分困った顔してるけど。」
新人T「実は、たろーさんに診て頂きたい Oracle Database の症状がありまして……。」
たろー「俺が診て大丈夫かな?……H課長に怒られない?」
新人T「怒られるのは覚悟の上です。どうしても、たろーさんに診て頂きたくて…。」
 

新人T

たろーちゃんを取り巻く相関図


そう言うとTさんはノートパソコンを広げ、某データベースのアラートログをたろーちゃんに見せました。
 

<アラートログ>

ORA-1653: unable to extend table APP.TAB1 by 8192 in tablespace USERS


たろー
「ん?表領域の容量不足かい?」
新人T「はい、エラーメッセージはそうなんですが…。表領域の状態を見ると、空きがあるんです。」
 

col TABLESPACE_NAME for A10
set linesize 1000
SELECT
       B.tablespace_name,
       B.TOTAL "サイズ(MB)",
       A.FREE  "空き(MB)",
       B.TOTAL - A.FREE  "使用(MB)",
       ROUND( (B.TOTAL - A.FREE)/B.TOTAL * 100, 2) "使用率"
  FROM
  (
      SELECT tablespace_name,SUM(BYTES)/1024/1024 FREE
      FROM dba_free_space
      GROUP BY tablespace_name
  ) A,
  (
      SELECT tablespace_name,SUM(BYTES)/1024/1024 TOTAL
      FROM dba_data_files
      GROUP BY tablespace_name
  ) B
  WHERE A.tablespace_name = B.tablespace_name
    AND A.tablespace_name = 'USERS'
  ORDER BY A.tablespace_name
;

TABLESPACE サイズ(MB)   空き(MB)   使用(MB)     使用率
---------- ---------- ---------- ---------- ----------
USERS            5120       1727       3393      66.27


たろー
「本当だ。5120MBのうち、まだ1727MBも空きがあるね。」
新人T「はい、そうなんです。
使用率 66.27% でまだ空きがあるのに、どうして ORA-1653 が出るのか分からなくて…。
H課長に相談したら、『絶対に Oracle Database のバグだから、サポートに重要度1で問い合わせて』と言われました。」
たろー「いやいや、ちょっと待って。この様子だと AUTOEXTEND は OFF なんだよね?」
新人T「はい、AUTOEXTEND はOFFです。」
たろー「データベースの構成はどうなってるの?」
新人T「11gR2 Enterprise Editionの4ノードRAC(Real Application Clusters)です。」
たろー「パワフルな構成だな。実行しているSQLは分かる?」
新人T「これです。」
 

SQL> INSERT /*+ APPEND PARALLEL(32) */ INTO TAB1
 SELECT ~ FROM ~ ;


行1でエラーが発生しました。:
ORA-01653: 表APP.TAB1を8192(表領域USERS)で拡張できません


たろー
「ふーん・・・。」
新人T「1ノード当たり8CPUを搭載していて、4ノードRACで パラレルインサート を行っています。」
たろー「だから PARALLEL(32) なのか。」
新人T「はい、そうです。スピード重視で、全ノードでフルパワーで パラレルインサート しているんです。」
たろー「今まで動いていた実績はあるの?」
新人T「はい、あります。一昨日までは動いていたんですが、昨晩、アプリケーション部門から
『夜間バッチがコケた』って連絡がきて、調べてみると、この状態だったんです。」
たろー「うむ。……ちょっといいかい?」


たろーちゃんは、Tさんのノートパソコンを操作し始めました。
 

set linesize 1000
col TABLESPACE_NAME for A10
col ALLOCATION_TYPE for A15

select TABLESPACE_NAME, ALLOCATION_TYPE
  from dba_tablespaces
 where TABLESPACE_NAME='USERS'
;

TABLESPACE ALLOCATION_TYPE
---------- ---------------
USERS      SYSTEM


たろー
「……なるほどな。」
新人T「え?何か分かったんですか?」

ニヤリ!

表領域には空きがあるのに・・・

たろー「Tさん。このエラーメッセージはどういう意味か分かる?」
 

ORA-01653: 表APP.TAB1を8192(表領域USERS)で拡張できません


新人T
「え……? USERS表領域に空きが無いってことですよね?」
たろー「もっと正確には?」
新人T「えーっと……。 TAB1テーブルを拡張するために エクステント を確保しようとしているんですがUSERS表領域に 8192 ブロックの空きが無いってことですよね?」
たろー「正解。では、このデータベースのブロックサイズはいくつ?」
新人T「デフォルトの 8192KB です。」
たろー「ということは、何バイトの空きが無いって言われてることになるのかな?」
新人T「えーっと、8192 × 8192 で64MB です。」
たろー「そうだね。USERS表領域に64MBの空きがないんだよ。」
新人T「え?…いや、たろーさん、待って下さい。」
 

col TABLESPACE_NAME for A10
set linesize 1000
SELECT
       B.tablespace_name,
       B.TOTAL "サイズ(MB)",
       A.FREE  "空き(MB)",
       B.TOTAL - A.FREE  "使用(MB)",
       ROUND( (B.TOTAL - A.FREE)/B.TOTAL * 100, 2) "使用率"
  FROM
  (
      SELECT tablespace_name,SUM(BYTES)/1024/1024 FREE
      FROM dba_free_space
      GROUP BY tablespace_name
  ) A,
  (
      SELECT tablespace_name,SUM(BYTES)/1024/1024 TOTAL
      FROM dba_data_files
      GROUP BY tablespace_name
  ) B
  WHERE A.tablespace_name = B.tablespace_name
    AND A.tablespace_name = 'USERS'
  ORDER BY A.tablespace_name
;

TABLESPACE サイズ(MB)   空き(MB)   使用(MB)     使用率
---------- ---------- ---------- ---------- ----------
USERS            5120       1727       3393      66.27


新人T
「USERS表領域はこのとおり、まだ1727MBも空きがありますよ?
どうしてそれで、64MBの空きが無いって怒られるんですか?」

Tさんの疑問はもっともです。
64MBよりも遥かに大きいサイズの空き領域があるのに、
何故エラーになるのでしょうか?
その答えは・・・(次回へ続く)

投稿者プロフィール

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