ablog

不器用で落着きのない技術者のメモ

Oracle 9i で analyze してみた

emp表を analyze する。

SQL> analyze table emp compute statistics;

Table analyzed.

emp表にはられているインデックスを調べる。

SQL> select index_name from user_indexes where table_name ='EMP';

INDEX_NAME
------------------------------
PK_EMP

インデックスも analyze する。

SQL> analyze index PK_EMP compute statistics;

Index analyzed.

Oracle Corporation strongly recommends that you use the DBMS_STATS package rather than ANALYZE to collect optimizer statistics. That package lets you collect statistics in parallel, collect global statistics for partitioned objects, and fine tune your statistics collection in other ways. Further, the cost-based optimizer, which depends upon statistics, will eventually use only statistics that have been collected by DBMS_STATS. See Oracle9i Supplied PL/SQL Packages and Types Reference for more information on this package.

However, you must use the ANALYZE statement (rather than DBMS_STATS) for statistics collection not related to the cost-based optimizer, such as:

To use the VALIDATE or LIST CHAINED ROWS clauses
To collect information on freelist blocks

General Management of Schema Objects

9i のときから DBMS_STATS package が推奨されていたのか。知らなかった。

dbx を使ってみる

Solaris10dbx を使ってみた。
Oracle 9iR2 に同梱されているサンプルプログラム(Pro*C)をデバッグオプション付でコンパイルし、dbx を使ってステップ実行などしてみた。

# su - oracle
$ cd /export/home/oracle/app/oracle/product/9.2.0/precomp/lib
$ cp env_precomp.mk env_precomp.mk.debug
$ vi env_precomp.mk.debug
#CC=/opt/SUNWspro/bin/cc
CC=/opt/SUNWspro/bin/cc -g -m64 # ← デバッグオプション追記
$ mkdir -p /export/home/oracle/work
$ cd /export/home/oracle/work
$ cp $ORACLE_HOME/precomp/demo/proc/demo_proc64.mk ./
$ cp $ORACLE_HOME/precomp/demo/proc/sample1.pc ./
  • サンプルmakefileを変更して、env_precomp.mk.debug を使うようにする。
$ vi demo_proc64.mk
#include $(ORACLE_HOME)/precomp/lib/env_precomp.mk
include $(ORACLE_HOME)/precomp/lib/env_precomp.mk.debug
  • sample1.pc を編集する*1
/* Define constants for VARCHAR lengths. */
#define     UNAME_LEN      20
#define     PWD_LEN        40
#define     DBNAME_LEN     10 # ← 追記

...

/* Copy the password. */
    strncpy((char *) password.arr, "TIGER", PWD_LEN);
    password.len =
      (unsigned short) strlen((char *) password.arr);

/* Copy the dbname. */                                # ← 追記
    strncpy((char *) dbname.arr, "orcl", DBNAME_LEN); # ← 追記
    dbname.len =                                      # ← 追記
      (unsigned short) strlen((char *) dbname.arr);   # ← 追記

...

    EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbname; # ← 「USING :dbname」を追記
$ /usr/ccs/bin/make -f demo_proc64.mk build EXE=sample1 OBJS=sample1.o
  • 実行してみる。
$ ./sample1

Connected to ORACLE as user: SCOTT

Enter employee number (0 to quit): 7369


Employee   Salary    Commission
--------   -------   ----------
SMITH       800.00      NULL

Enter employee number (0 to quit):
  • dbx を使ってみる(別のターミナルセッションを開く)。
$ ps -ef | grep "[s]ample1"
  oracle 21378  3073   0 15:48:14 pts/1       0:00 ./sample1
$ /opt/SUNWspro/bin/dbx - 21378
For information about new features see `help changes'
To remove this message, put `dbxenv suppress_startup_message 7.6' in your .dbxrc
Reading sample1
Reading ld.so.1
Reading libclntsh.so.9.0
Reading libnsl.so.1
Reading libsocket.so.1
Reading libgen.so.1
Reading libdl.so.1
Reading libaio.so.1
Reading librt.so.1
Reading libm.so.2
Reading libthread.so.1
Reading libc.so.1
Reading libwtc9.so
Reading libmd5.so.1
Reading libc_psr.so.1
Attached to process 21378
t@1 (l@1) stopped in _read at 0xffffffff7d5ce794
0xffffffff7d5ce794: _read+0x0008:       ta       %icc,0x0000000000000040
Current function is main (optimized)
  344           gets(temp_char);
(dbx) step # ← ステップ実行(関数内に入り込む)
t@1 (l@1) stopped in main (optimized) at line 346 in file "sample1.c"
  346           if (emp_number == 0)
(dbx) next # ← ステップ実行(関数実行後に次の行で実行停止する)
t@1 (l@1) stopped in main (optimized) at line 362 in file "sample1.c"
  362           sqlstm.sqlvsn = 12;
(dbx) list # ソースコードを表示する
  346           if (emp_number == 0)
  347               break;
  348
  349   /* Branch to the notfound label when the
  350    * 1403 ("No data found") condition occurs.
  351    */
  352           /* EXEC SQL WHENEVER NOT FOUND GOTO notfound; */
  353
  354
  355           /* EXEC SQL SELECT ename, sal, comm
(dbx) print emp_number # 変数の中身を表示する。
emp_number = 0


[参考]
http://docs.sun.com/app/docs/doc/805-7883/6j7dojf62?l=ja&a=view
monjyu.biz

*1:ローカルのOracleインスタンスとプロセス間通信する場合は不要。今回は Oracle Net を使ってリモートデータベースに接続するためにこの変更が必要だった

新久保 浩二さんの実践オラクルトラブルシューティングガイドを聞いて来た

http://www.istudy.ne.jp/www/cms/news/om20/week.html に行って来た。
株式会社インサイトテクノロジー の新久保 浩二さんがスピーカー。
さすが、おら!オラ!オラクルインサイトテクノロジー。濃かった。


Oracleなんて所詮、OS上で動作するいくつかのプロセスと共有(非共有)メモリと物理的ファイルで構成されるアプリケーション。アーキテクチャやメカニズムを理解して、ロジカルに考えシンプルなツールをつかってトラブルシューティングしましょうというお話し。


キーワードだけメモ

  • Prelim Connection (10g以降)
  • oradebug (11g以降)
  • DMA tools (3rd party tools)
  • pstack(Linux) と 実行計画は対応している
  • ORA-1578
  • DBMS_REPAIR(event#10231 or event#10233)
  • bbed (Block Browser and Editor)
  • Data Unload
  • LogMiner
  • Database Time
  • Active Session History
  • Average Active Sessions
  • ORA-03113
  • oerr

後日遊べそうなネタがたくさん。


今日は oerr コマンドだけ試してみる。

$ oerr ora 1555
01555, 00000, "snapshot too old: rollback segment number %s with name \"%s\" too small"
// *Cause: rollback records needed by a reader for consistent read are
//         overwritten by other writers
// *Action: If in Automatic Undo Management mode, increase undo_retention
//          setting. Otherwise, use larger rollback segments

こんなコマンドあったのか。知らなかった。