新人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よりも遥かに大きいサイズの空き領域があるのに、
何故エラーになるのでしょうか?
その答えは・・・(次回へ続く)