このブログを検索

ラベル 確認用 の投稿を表示しています。 すべての投稿を表示
ラベル 確認用 の投稿を表示しています。 すべての投稿を表示

2011年8月22日月曜日

REDOログファイルを一覧表示する

REDOログファイルを一覧表示します。
set pages 10000
set lines 120
COL MEMBER FORMAT A30
COL STATUS FORMAT A10
SELECT LOG.THREAD#,LOG.GROUP#,
    LOG.BYTES/1024/1024 AS MBYTES,
    LOG.STATUS,LOG.ARCHIVED,LOGFILE.MEMBER 
 FROM   V$LOG LOG,V$LOGFILE LOGFILE
 WHERE LOG.GROUP# = LOGFILE.GROUP#
 ORDER BY THREAD#,GROUP#;
実行結果は次の通りです。
この例では2ノードRAC、3グループ、各1GBです。

STATUS=CURRECTが現在使用中のREDOログファイルです。
ACTIVEが使ったことがあるがアーカイブされていないもの、INACTIVEはアーカイブ済のものです。
UNUSEDはREDOログファイル追加後などまったく未使用のものです。

THREAD#     GROUP#     MBYTES STATUS     MEMBER
---------- ---------- ---------- ---------- ------------------------------
         1          1       1024 INACTIVE   +DATA/redo/redo111.dbf
         1          1       1024 INACTIVE   +LOG/redo/redo112.dbf
         1          2       1024 ACTIVE     +DATA/redo/redo121.dbf
         1          2       1024 ACTIVE     +LOG/redo/redo122.dbf
         1          3       1024 CURRENT    +DATA/redo/redo131.dbf
         1          3       1024 CURRENT    +LOG/redo/redo132.dbf
         2          4       1024 INACTIVE   +LOG/redo/redo212.dbf
         2          4       1024 INACTIVE   +DATA/redo/redo211.dbf
         2          5       1024 ACTIVE     +LOG/redo/redo222.dbf
         2          5       1024 ACTIVE     +DATA/redo/redo221.dbf
         2          6       1024 CURRENT    +LOG/redo/redo232.dbf
         2          6       1024 CURRENT    +DATA/redo/redo231.dbf

2011年6月15日水曜日

ASMディスクグループの容量や使用率を調べる

v$asm_diskgroupでディスクグループの情報を得られます。
RATIOが一定量を超えないように監視スクリプトを作成しています。
set pages 10000
set linesize 100
col name format a20
col total_mb for 999,999,999
col free_mb for 999,999,999
col ratio for 999.99
col state for a10
select group_number, name, total_mb, free_mb,
  round(((total_mb-free_mb)/total_mb)*100 ,2) as ratio,
  state
from v$asm_diskgroup;
実行結果は次の通り。
GROUP_NUMBER NAME                     TOTAL_MB      FREE_MB   RATIO STATE
------------ -------------------- ------------ ------------ ------- -----------
           1 DATA                      708,468      500,535   29.35 CONNECTED
           2 LOG                       493,804      481,292    2.53 CONNECTED

2011年6月14日火曜日

LIKE句でアンダースコアをマッチングさせる

OracleのLIKE句では、'_'(アンダースコア)は任意の1文字でマッチングします。
アンダースコアそのものをマッチングしたい場合は、ESCAPE句を使います。

例として表領域のデータファイル情報を取得します。
SQL> set pages 10000
set lines 120
col tablespace_name for a20
col file_name for a50
col bytes for 999,999,999,999
select tablespace_name,file_name,bytes,status from DBA_DATA_FILES
where tablespace_name like 'SSS01+_S+_%' escape '+'
order by tablespace_name,file_name;
実行結果は次の通りです。
TABLESPACE_NAME   FILE_NAME                                      BYTES STATUS
----------------- ----------------------------------- ---------------- ---------
SSS01_S_DATA      +DATA/database/sss01_s_data_01.dbf     2,147,483,648 AVAILABLE
SSS01_S_DATA      +DATA/database/sss01_s_data_02.dbf     2,147,483,648 AVAILABLE
SSS01_S_IDX       +DATA/database/sss01_s_idx_01.dbf      1,589,641,216 AVAILABLE
SSS01_S_IDX       +DATA/database/sss01_s_idx_02.dbf      1,588,592,640 AVAILABLE
SSS01_S_IDX       +DATA/database/sss01_s_idx_03.dbf      1,073,741,824 AVAILABLE
SSS01_S_IDX       +DATA/database/sss01_s_idx_04.dbf      1,073,741,824 AVAILABLE

6行が選択されました。

2011年4月22日金曜日

ASMのファイルシステムを直接操作する

ASMにはASMのファイルシステムを操作するシェル、asmcmdが用意されています。
使い方はORACLE_SIDをASMにしてasmcmdを起動するだけ。
cdやlsだけでなくrmやduもあって非常に便利。
ASMCMD> help
       :
        commands:
        --------
        cd
        du
        find
        help
        ls
        lsct
        lsdg
        mkalias
        mkdir
        pwd
        rm
        rmalias
ASMディスクグループへディスクを追加するではSQLで確認していますが、容量確認だけであればasmcmdの方が楽です。
$ export ORACLE_SID=+sss01
$ asmcmd
ASMCMD> lsdg
State    Type    Rebal  Unbal  Sector  Block       AU  Total_MB  Free_MB  Req_mir_free_MB  Usable_file_MB  Offline_disks  Name
MOUNTED  EXTERN  N      N         512   4096  1048576    476843   334069                0          334069              0  DATA/
MOUNTED  EXTERN  N      N         512   4096  1048576    143055   130125                0          130125              0  LOG/

findも使えます。
要らないオンラインREDOログを削除する前の確認くらいにしか使いませんが。
ASMCMD> find -t ONLINELOG log redo1*.dbf  
+log/REDO/REDO1012.DBF
+log/REDO/REDO1022.DBF
+log/REDO/REDO1032.DBF
+log/REDO/REDO1042.DBF
+log/REDO/REDO1052.DBF
+log/REDO/REDO1062.DBF

2011年4月5日火曜日

SQLをトレースしTKPROFで整形する

EXPLAINで実行計画がわかりますが、バインド変数を使ったSQLの場合はデータ(レコード)を特定できないため、正確な実行計画が得られません。
ここでは実際に実行したSQLをトレースをすることにより実行計画を取得します。

次のように、トレースをONにして実行します。
var vcarrier number
var vleader number
exec :vcarrier := 2
exec :vleader := 2
alter session set timed_statistics=true;
alter session set events '10046 trace name context forever, level 12';

SELECT
    *
FROM
    (SELECT
        rank() over (ORDER BY tt.regist_dt DESC) as rn,
        tt.team_nm AS team_nm ,
        tt.member_cnt AS member_cnt ,
        tt.team_status_id AS team_status_id ,
        tt.pr_comment AS pr_comment ,
        tt.team_id AS team_id ,
        tm.user_id AS user_id ,
        tt.regist_dt AS regist_dt ,
        wearing_avatar_kind,
        avatar_id,
        gender,
        avatar_session
    FROM
        T01_Test2 tt ,
        T01_TestMember2 tm ,
        T01_UserMyTest2 my
    WHERE
        tt.carrier_id = :vcarrier     AND
        tm.user_id = my.user_id     AND
        tt.team_id = tm.team_id     AND
        tm.leader_flg = :vleader
    ORDER BY
        tt.regist_dt DESC
    )
WHERE
    rn BETWEEN 1 AND
    30;

alter session set events '10046 trace name context off';
alter session set timed_statistics=false;
EVENT 10046のレベルは4種類あります。
level  1   alter session set sql_trace=trueと同じ
level  4   level 1にバインド変数情報
level  8   level 1に待機イベント情報
level 12   level 4 + level 8
実行後、DBサーバにトレースファイルが出力されています。
そのトレースファイルそのままだと読みづらいので、TKPROFというツールで整形します。
$ ls -tlr /opt/app/oracle/admin/sss01dev/udump/ | tail -1
$ sudo scp /opt/app/oracle/admin/sss01dev/udump/sss01dev_ora_21243.trc snwdev1:/home/ito/tmp/
$ tkprof sss01dev_ora_21243.trc test.trc
ただし、TKPROFはバインド情報を無視するので必要であればトレースファイルを直接確認します。
$ grep -A4 "^ Bind" sss01dev_ora_21243.trc 
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=03 fl2=1000000 frm=00 csi=00 siz=48 off=0
  kxsbbbfp=2b818341b4c0  bln=22  avl=02  flg=05
  value=2
 Bind#1
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=03 fl2=1000000 frm=00 csi=00 siz=0 off=24
  kxsbbbfp=2b818341b4d8  bln=22  avl=02  flg=01
  value=2
整形したファイル例は次の通りです。
TKPROF: Release 10.2.0.4.0 - Production on 火 4月 5 11:25:10 2011

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Trace file: sss01dev_ora_29755.trc
Sort options: default

********************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing 
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call
********************************************************************************

SELECT
    *
FROM
    (SELECT
        rank() over (ORDER BY tt.regist_dt DESC) as rn,
        tt.team_nm AS team_nm ,
        tt.member_cnt AS member_cnt ,
        tt.team_status_id AS team_status_id ,
        tt.pr_comment AS pr_comment ,
        tt.team_id AS team_id ,
        tm.user_id AS user_id ,
        tt.regist_dt AS regist_dt ,
        wearing_avatar_kind,
        avatar_id,
        gender,
        avatar_session
    FROM
        T01_Team2 tt ,
        T01_TeamMember2 tm ,
        T01_UserMyRoom2 my
    WHERE
        tt.carrier_id = :vcarrier     AND
        tm.user_id = my.user_id     AND
        tt.team_id = tm.team_id     AND
        tm.leader_flg = :vleader
    ORDER BY
        tt.regist_dt DESC
    )
WHERE
    rn BETWEEN 1 AND
    30

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch       31      0.14       0.14          0       6097          0          30
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       33      0.14       0.14          0       6097          0          30

Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 113  

Rows     Row Source Operation
-------  ---------------------------------------------------
     30  VIEW  (cr=6097 pr=0 pw=0 time=140143 us)
   1153   WINDOW SORT PUSHED RANK (cr=6097 pr=0 pw=0 time=141286 us)
   1153    HASH JOIN  (cr=6097 pr=0 pw=0 time=129360 us)
   1164     TABLE ACCESS FULL T01_TEAM2 (cr=227 pr=0 pw=0 time=166 us)
   1153     HASH JOIN  (cr=5870 pr=0 pw=0 time=123033 us)
   1153      TABLE ACCESS FULL T01_TEAMMEMBER2 (cr=253 pr=0 pw=0 time=4643 us)
  86413      TABLE ACCESS FULL T01_USERMYROOM2 (cr=5617 pr=0 pw=0 time=86469 us)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                      32        0.00          0.00
  SQL*Net message from client                    32        0.00          0.02



********************************************************************************

OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch       31      0.14       0.14          0       6097          0          30
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       33      0.14       0.14          0       6097          0          30

Misses in library cache during parse: 0

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                      79        0.00          0.00
  SQL*Net message from client                    79       15.53         23.49


OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        0      0.00       0.00          0          0          0           0
Execute      0      0.00       0.00          0          0          0           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        0      0.00       0.00          0          0          0           0

Misses in library cache during parse: 0

    1  user  SQL statements in session.
    0  internal SQL statements in session.
    1  SQL statements in session.
********************************************************************************
Trace file: sss01dev_ora_29755.trc
Trace file compatibility: 10.01.00
Sort options: default

       1  session in tracefile.
       1  user  SQL statements in trace file.
       0  internal SQL statements in trace file.
       1  SQL statements in trace file.
       1  unique SQL statements in trace file.
     263  lines in trace file.
       0  elapsed seconds in trace file.

2011年4月4日月曜日

RACのサービス名一覧フル表示する

RACのサービス状況は、crs_statというコマンドで表示することが出来ます。
オプション-tでサマリ一覧表示ができますが、長い文字列は途中で切れてしまいます。

そこで、パイプなどを使ってサービス名をフル表示することができます。
$ crs_stat | awk '{print $1 "="  $4; }' RS="" FS="\n" | awk '{ printf "%-50s%s\n",$2,$4}' FS="="
ora.sss01.SSS01DBBATCH.cs                         ONLINE on sssdb1
ora.sss01.SSS01DBBATCH.sss011.srv                 ONLINE on sssdb1
ora.sss01.SSS01DBBATCH.sss012.srv                 ONLINE on sssdb2
ora.sss01.SSS01DBBATCH1.cs                        ONLINE on sssdb1
ora.sss01.SSS01DBBATCH1.sss011.srv                ONLINE on sssdb1
ora.sss01.SSS01DBBATCH2.cs                        ONLINE on sssdb2
ora.sss01.SSS01DBBATCH2.sss012.srv                ONLINE on sssdb2
ora.sss01.SSS01DBE.cs                             ONLINE on sssdb1
ora.sss01.SSS01DBE.sss011.srv                     ONLINE on sssdb1
ora.sss01.SSS01DBE.sss012.srv                     ONLINE on sssdb2
ora.sss01.SSS01DBI.cs                             ONLINE on sssdb1

2011年4月3日日曜日

マテリアライズドビューの自動同期対象テーブルを探す

マテリアライズドビューの自動同期対象を探します。
自動同期のジョブは、リフレッシュグループにあるテーブルに対して実行します。
ジョブとリフレッシュグループの紐付けはマテリアライズドビューの同期エラーを解決するを参照。

リフレッシュグループのテーブル一覧は次の通り。
set pages 10000
set lines 120
column RNAME FORMAT a20
column NAME FORMAT a40
select r.job,r.rname,c.name,c.broken
 from DBA_REFRESH r, DBA_REFRESH_CHILDREN c
 where r.REFGROUP=c.REFGROUP
  and r.rowner='INDEP1USER'
実行例は、次の通り。
わかりにくいですが、BROKEN=Nであれば自動同期をします。
JOB RNAME                NAME                                     BRO
---------- -------------------- ---------------------------------------- ---
       118 REFRESH_INDEP1       TBL_CONSENTLOG1                          N
       118 REFRESH_INDEP1       TBL_EXPORTCONSENTLOG                     N
       118 REFRESH_INDEP1       TBL_MYROOMCOMMENT1                       N
       118 REFRESH_INDEP1       TBL_MYROOMCOMMENTCONSENT1                N
       118 REFRESH_INDEP1       TBL_USERMYROOMCOMMENT1                   N
       118 REFRESH_INDEP1       TBL_USERMYROOMCOMMENTCONSENT1            N

2011年3月25日金曜日

自動アナライズの実行時刻を変更する

Oracleは定期的にアナライズをすることにより、実行計画の精度を上げるのが基本です。
10gではGATHER_STATS_JOBという自動アナライズ機能がデフォルトでONになっています。
とはいえ、たびたびアナライズをするとパフォーマンスダウンにつながるため、 GATHER_STATS_JOBは次のオブジェクトに対して実施します。
統計情報を取得していないオブジェクト
統計情報が失効(レコードが10%が変更された)オブジェクト
私の担当Webサイトでは、ジョブスケジューリングの設定変更をしています。
というのは、デフォルト設定のままだと平日22時および土曜日0時にしか実行されないためです。
担当サイトの高負荷時間帯は毎日22~25時なので、負荷の低い毎日14時に実行しています。

まず、GATHER_STATS_JOBがMAINTENANCE_WINDOW_GROUPというジョブグループで動いていることを確認します。
col JOB_NAME for a30
col SCHEDULE_NAME for a40
select JOB_NAME ,SCHEDULE_NAME from DBA_SCHEDULER_JOBS;

JOB_NAME                       SCHEDULE_NAME
------------------------------ ----------------------------------------
AUTO_SPACE_ADVISOR_JOB         MAINTENANCE_WINDOW_GROUP
GATHER_STATS_JOB               MAINTENANCE_WINDOW_GROUP
FGR$AUTOPURGE_JOB
PURGE_LOG                      DAILY_PURGE_SCHEDULE
MGMT_STATS_CONFIG_JOB
MGMT_CONFIG_JOB                MAINTENANCE_WINDOW_GROUP
次に、MAINTENANCE_WINDOW_GROUPのスケジュール内容を確認します。
set pages 10000
set lines 120
col WINDOW_NAME for a20
col REPEAT_INTERVAL for a80
col DURATION for a30
select WINDOW_NAME ,REPEAT_INTERVAL ,DURATION from DBA_SCHEDULER_WINDOWS;

WINDOW_NAME          REPEAT_INTERVAL
-------------------- --------------------------------------------------------------------------------
DURATION
------------------------------
WEEKNIGHT_WINDOW     freq=daily;byday=MON,TUE,WED,THU,FRI;byhour=22;byminute=0; bysecond=0
+000 08:00:00

WEEKEND_WINDOW       freq=daily;byday=SAT,SUN;byhour=0;byminute=0;bysecond=0
+000 48:00:00
設定は次のようにします。
exec DBMS_SCHEDULER.SET_ATTRIBUTE('WEEKNIGHT_WINDOW','repeat_interval','freq=daily;byday=MON,TUE,WED,THU,FRI;byhour=15;byminute=0; bysecond=0');
exec DBMS_SCHEDULER.SET_ATTRIBUTE('WEEKNIGHT_WINDOW','duration','+000 05:00:00');

exec DBMS_SCHEDULER.SET_ATTRIBUTE('WEEKEND_WINDOW','repeat_interval','freq=daily;byday=SAT,SUN;byhour=15;byminute=0;bysecond=0');
exec DBMS_SCHEDULER.SET_ATTRIBUTE('WEEKEND_WINDOW','duration','+000 05:00:00');
実行されたかどうかは、スケジューラの履歴で確認できます。
なお、この例はRAC環境なのでインスタンス単位で表示されます。
set pages 10000
set lines 120
col job_name for a25
col status for a10
col START_DATE for a20
col END_DATE for a20
SELECT 
  TO_CHAR(ACTUAL_START_DATE, 'YYYY/MM/DD HH24:MI:SS') AS "START_DATE",
  TO_CHAR(LOG_DATE, 'YYYY/MM/DD HH24:MI:SS') AS "END_DATE",
  JOB_NAME,STATUS,INSTANCE_ID
 FROM DBA_SCHEDULER_JOB_RUN_DETAILS
 WHERE JOB_NAME in ('AUTO_SPACE_ADVISOR_JOB','GATHER_STATS_JOB')
 ORDER BY ACTUAL_START_DATE,JOB_NAME;

 START_DATE           END_DATE             JOB_NAME                  STATUS     INSTANCE_ID
-------------------- -------------------- ------------------------- ---------- -----------
2011/02/23 14:00:02  2011/02/23 14:05:19  AUTO_SPACE_ADVISOR_JOB    SUCCEEDED            2
2011/02/23 14:00:02  2011/02/23 14:09:55  GATHER_STATS_JOB          SUCCEEDED            2
2011/02/24 14:00:02  2011/02/24 14:05:39  AUTO_SPACE_ADVISOR_JOB    SUCCEEDED            2
2011/02/24 14:00:02  2011/02/24 14:10:30  GATHER_STATS_JOB          SUCCEEDED            2
2011/02/25 14:00:01  2011/02/25 14:11:04  GATHER_STATS_JOB          SUCCEEDED            1
2011/02/25 14:00:02  2011/02/25 14:05:38  AUTO_SPACE_ADVISOR_JOB    SUCCEEDED            2
2011/02/26 14:00:00  2011/02/26 14:09:39  GATHER_STATS_JOB          SUCCEEDED            1
2011/02/26 14:00:00  2011/02/26 14:05:40  AUTO_SPACE_ADVISOR_JOB    SUCCEEDED            1

2011年3月17日木曜日

実行計画(EXPLAIN)を取得する

クエリの実行計画を取得するには2ステップ必要です。
(1)explainしてその結果を保存する
(2)保存結果を表示する
まずexplainすると、その結果はPLAN_TABLEに保存されます。
SQL> explain plan for select user_id from T01_AQUA1_APPITEM_LIMIT1;

Explained.
結果は、標準スクリプトでテーブル内容を表示できます。
SQL> @?/rdbms/admin/utlxpls.sql

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------
Plan hash value: 4246935464

----------------------------------------------------------------------------------------------
| Id  | Operation         | Name                     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                          |  7421K|    42M|  9167   (2)| 00:01:50 |
|   1 |  TABLE ACCESS FULL| T01_AQUA1_APPITEM_LIMIT1 |  7421K|    42M|  9167   (2)| 00:01:50 |
----------------------------------------------------------------------------------------------
表関数がサポートされている9i(9iR2?)以上は、DBMS_XPLANパッケージでさらに詳細な情報を表示することもできます。
3つ目の引数を'ALL'にするとパラレルクエリやカラム情報も表示します。
SQ> SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY('plan_table',null,'all'));
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------
Plan hash value: 4246935464

----------------------------------------------------------------------------------------------
| Id  | Operation         | Name                     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                          |  7421K|    42M|  9167   (2)| 00:01:50 |
|   1 |  TABLE ACCESS FULL| T01_AQUA1_APPITEM_LIMIT1 |  7421K|    42M|  9167   (2)| 00:01:50 |
----------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / T01_AQUA1_APPITEM_LIMIT1@SEL$1

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - "USER_ID"[NUMBER,22]

2011年3月7日月曜日

オブジェクトの依存関係を確認する

ビューが参照しているテーブルをdropすると、そのビューはINVALIDになります。
Oracleはオブジェクト同士の依存関係を管理しているためです。
set pages 10000
set lines 120
col REFERENCED_NAME for a30
col TYPE for a20
col NAME for a30
select referenced_name,type,name from user_dependencies
where referenced_name in ('M01_DOWNLOADITEM','M01_MACHINE')
order by referenced_name,type,name;
実行結果は次の通り。
REFERENCED_NAMEが参照されているオブジェクト、NAMEが影響を受ける(INVALIDになりうる)オブジェクトです。
REFERENCED_NAME                TYPE                 NAME
------------------------------ -------------------- ------------------------------
M01_DOWNLOADITEM               FUNCTION             L_ITEMPUBLISHLOG
M01_DOWNLOADITEM               VIEW                 V_CATEGORYLIST
M01_MACHINE                    VIEW                 V_CATEGORYLIST

共有プールのサイズ変更履歴を確認する

例えばWebリクエストと分析系バッチなど、特性が違いすぎる処理を実行しているとします。
自動共有メモリ管理(ASMM)を使っている場合、Oracleは共有プールとデータベースバッファの最適化に迷ってしまうことがあります。
特性の異なる最適化を繰り返してしまうのは、本当の意味で最適化とは言えません。

メモリ(SGA)のリサイズ結果を判断の1つにすることができます。
set time on 
set pages 10000
set lines 120
col component for a25
col oper_type for a12
col parameter for a25
alter session set nls_date_format='yyyy/mm/dd hh24:mi:ss';
select component,oper_type,parameter,modsize,end_time from (
  select row_number() over (order by end_time desc) as rn,
    component,oper_type,parameter,(final_size-initial_size) as modsize,end_time
  from v$SGA_RESIZE_OPS
) where rn<=20;
実行結果は次の通り。 OPER_TYPEは増減(GROW/SHRINK)です。 頻度や量(MODSIZE)を確認するといいと思います。
COMPONENT                 OPER_TYPE    PARAMETER                    MODSIZE END_TIME
------------------------- ------------ ------------------------- ---------- -------------------
shared pool               SHRINK       shared_pool_size          -100663296 2011/03/05 04:14:31
DEFAULT buffer cache      GROW         db_cache_size              100663296 2011/03/05 04:14:31
shared pool               SHRINK       shared_pool_size          -100663296 2011/03/05 03:01:26
DEFAULT buffer cache      GROW         db_cache_size              100663296 2011/03/05 03:01:26
DEFAULT buffer cache      SHRINK       db_cache_size             -100663296 2011/03/04 18:57:11
shared pool               GROW         shared_pool_size           100663296 2011/03/04 18:57:11
shared pool               SHRINK       shared_pool_size          -100663296 2011/03/04 04:32:11
DEFAULT buffer cache      GROW         db_cache_size              100663296 2011/03/04 04:32:11
DEFAULT buffer cache      SHRINK       db_cache_size             -201326592 2011/03/03 16:12:45
shared pool               GROW         shared_pool_size           201326592 2011/03/03 16:12:45

REDOログスイッチの完了時刻を確認する

更新処理によりREDOログファイルがいっぱいになると、REDOログファイルはローテートされます
これをログスイッチと呼びます。
1時間に1度を目処に考えていますが、頻繁に発生するとパフォーマンスが落ちるのでチューニングが必要です。

ログスイッチのタイミングはアラートログから調べることができます。
$ grep -B1 "LGWR switch" $ORACLE_BASE/admin/sss01/bdump/alert_sss011.log | tail -1000 | grep "Mar  6"

Sun Mar  6 00:29:08 2011
Sun Mar  6 02:07:04 2011
Sun Mar  6 02:07:43 2011
Sun Mar  6 07:31:04 2011
Sun Mar  6 07:32:33 2011
Sun Mar  6 13:57:04 2011
Sun Mar  6 13:58:38 2011
Sun Mar  6 18:57:06 2011
Sun Mar  6 18:58:25 2011
ログスイッチはロックによる待機を最小限にするため、次の順に処理します。
1)REDOログファイルのローテート
2)古いREDOログファイルをアーカイブREDOログファイルとして書き出す(アーカイブログモード)
アーカイブログモードでログスイッチが高頻度すぎると、ディスクI/Oが発生してパフォーマンスが低下します。
アーカイブREDOログファイルへの書き出しが完了しないと、そのREDOファイルは次回REDOログとして利用できません。
最悪の場合、REDOログファイルのローテートが1周してもアーカイブREDOログファイルへの書き出しが完了しません。
そうなると、利用出来るREDOログがなくなるため、ローテート待ちでデータベースがロックします。

注意として、アラートログの時刻はローテートが完了した時刻です。
アーカイブREDOログの書き出し完了時刻もチェックするといいと思います。
set pages 10000
set lines 100
alter session set nls_date_format='yyyy/mm/dd hh24:mi:ss';
select SEQUENCE#,COMPLETION_TIME from (
  select row_number() over (order by COMPLETION_TIME desc) as rn,
    SEQUENCE#, COMPLETION_TIME from v$archived_log
) where rn<=10

 SEQUENCE# COMPLETION_TIME
---------- -------------------
      2750 2011/03/07 00:21:59
      2656 2011/03/06 18:58:26
      2749 2011/03/06 18:58:25
      2748 2011/03/06 18:58:24
      2655 2011/03/06 18:58:22
      2747 2011/03/06 13:58:39
      2654 2011/03/06 13:58:39
      2746 2011/03/06 13:58:36
      2653 2011/03/06 13:58:32
      2652 2011/03/06 07:32:34

2011年3月4日金曜日

システム権限とオブジェクト権限を確認する

Oracleにはシステム権限とオブジェクト権限の2種類あります。
権限をロールとしてひとまとめにすることもでき、ロールにロールを付与することもできます。
注意として、権限だけではデフォルト表領域以外は、スキーマの表領域へのアクセス制限を確認する設定が必要です。
また、grantはロールと権限を混在して記述できません。
もっとも注意しなければならないのは、ストアド内部ではロールの権限は無視されることです。

スキーマやロールに付与したシステム権限を確認します。
set pages 10000
set lines 100
col grantee for a20
col privilege for a30
select grantee,privilege from dba_sys_privs
where grantee='SSS01DBUSER'
order by grantee,privilege;

GRANTEE              PRIVILEGE
-------------------- ------------------------------
SSS01DBUSER          ALTER ANY TABLE
SSS01DBUSER          CREATE ANY INDEX
SSS01DBUSER          CREATE ANY MATERIALIZED VIEW
SSS01DBUSER          CREATE ANY PROCEDURE
SSS01DBUSER          CREATE ANY SEQUENCE
SSS01DBUSER          CREATE ANY TABLE
SSS01DBUSER          CREATE ANY TRIGGER
SSS01DBUSER          CREATE ANY VIEW
SSS01DBUSER          CREATE PROCEDURE
SSS01DBUSER          CREATE SEQUENCE
SSS01DBUSER          CREATE SESSION
SSS01DBUSER          CREATE TABLE
SSS01DBUSER          CREATE TRIGGER
SSS01DBUSER          DELETE ANY TABLE
SSS01DBUSER          DROP ANY INDEX
SSS01DBUSER          DROP ANY MATERIALIZED VIEW
SSS01DBUSER          DROP ANY PROCEDURE
SSS01DBUSER          DROP ANY SEQUENCE
SSS01DBUSER          DROP ANY TABLE
SSS01DBUSER          DROP ANY TRIGGER
SSS01DBUSER          DROP ANY VIEW
SSS01DBUSER          EXECUTE ANY PROCEDURE
SSS01DBUSER          GLOBAL QUERY REWRITE
SSS01DBUSER          INSERT ANY TABLE
SSS01DBUSER          RESUMABLE
SSS01DBUSER          SELECT ANY SEQUENCE
SSS01DBUSER          SELECT ANY TABLE
SSS01DBUSER          UPDATE ANY TABLE
スキーマやロールに付与したロールを確認します。
set pages 10000
set lines 100
col grantee for a20
col granted_role for a20
select grantee,granted_role from dba_role_privs
where grantee='SSS01DBUSER'
order by grantee,granted_role;

GRANTEE              GRANTED_ROLE
-------------------- --------------------
SSS01DBUSER          SSS01APP
SSS01DBUSER          CONNECT
スキーマやロールに付与したオブジェクト権限を確認します。
set pages 10000
set lines 100
col grantee for a20
col owner for a10
col table_name for a30
col privilege for a20
select grantee,owner,table_name,privilege from dba_tab_privs
where grantee like 'SSS01DBUSER'
order by grantee,table_name,privilege;

GRANTEE      OWNER      TABLE_NAME      PRIVILEGE
------------ ---------- --------------- -----------
SSS01DBUSER  SYS        DBMS_LOCK       EXECUTE
ログインしているスキーマのシステム権限を確認します。
set pages 10000
set lines 100
col privilege for a30
select privilege from user_sys_privs order by privilege;

2011年3月2日水曜日

長時間実行しているセッションを調べる

何かしらの待機により残ったままのセッションおよびそのSQLを調べます。
新規、かつ、実行途中のSQLexecutions=0のままなので、除算エラーにならないようにしています。
set time on
set pages 10000
set lines 100
set long 20000
col program for a50
col username for a20
col status for a10
col sql_fulltext for a100
alter session set nls_date_format='yyyy/mm/dd hh24:mi:ss';
select s.sid,s.serial#,s.username,s.logon_time,s.status,
  q.sharable_mem,q.elapsed_time/nvl(nullif(executions,0),1)/1000/1000 as executions,
  s.program,
  replace(replace(replace(q.sql_fulltext,chr(9),''),chr(10),' '),'  ',' ') as sql
from v$session s,v$sqlstats q
where s.sql_id=q.sql_id and username<>'SYS'
order by s.logon_time desc
;
実行結果は次の通り。
SID    SERIAL# USERNAME             LOGON_TIME          STATUS     SHARABLE_MEM EXECUTIONS
------ ---------- -------------------- ------------------- ---------- ------------ ----------
PROGRAM
--------------------------------------------------
SQL
--------------------------------------------------------------------------------
   476       9190 SSS01DBIUSER         2011/03/02 17:33:06 INACTIVE          16408 .001146854
httpd@sssweb24.sss.co.jp (TNS V1-V3)
select user_id,item_id,item_count,to_char( update_dt, 'yyyy/mm/dd hh24:mi:ss')
 as update_dt from TBL_StartAvatar1 where item_id=:i
tem_id1 and user_id=:user_id2 and item_count>:item_c
ount3 order by update_dt desc

2011年3月1日火曜日

データベースリンクを確認する

set pages 10000
set lines 110
col owner for a10
col db_link for a30
col username for a20
col host for a10
select * from dba_db_links;
実行結果は次の通り。
OWNER      DB_LINK              USERNAME     HOST       CREATED
---------- -------------------- ------------ ---------- --------
PUBLIC     SSS01_MASTER_SYNC    MASTERUSER   SSS01      10-07-14

2011年2月25日金曜日

似て非なるSQLを探す

Oracleは意識的にプレースホルダを使わないと、共有プールのSQL領域を食いつぶしてSQLのキャッシュ率が悪くなります。
SGAを増やす手段もありますが、数ギガ規模にまで増やすとキャッシュの吐き出し(エージアウト)をしている間、SQLキャッシュ全体をロック(ラッチ)されて処理を何も受け付けなくなります。
そこで、リテラル値が含まれているSQLを定期的に探すといいでしょう。
この例では、SQL文を前方一致100文字だけで比較していますが、アプリケーションによっては50~150文字など調整するといいかと思います。
CNTが多いものを最優先に対応するといいでしょう。
select "Stmt",cnt,"Mem/count","Exec" from (
  SELECT row_number() over (order by count(*) desc) as rn,
      substr(sql_text,1,100) "Stmt", count(*) cnt,
      sum(sharable_mem)/count(*)    "Mem/count",
      sum(executions)      "Exec"
  FROM v$sqlstats
  GROUP BY substr(sql_text,1,100)
  HAVING count(*) > 10
) where rn<=100;
実行例は次の通り。
Stmt                                                                                    CNT  Mem/count       Exec
-------------------------------------------------------------------------------- ---------- ---------- ----------
    SELECT     msfr.free_rankavg_id,     msfr.free_rankavg_nm,     msfr.event_id       4308 36555.0975       4312
,     msfr.team_flg,

select substrb(dump(val,16,0,32),1,120) ep, cnt from (select /*+ no_parallel(t)         308 12900.4416       3365
no_parallel_index(t)

select TABLE_NAME,TABLESPACE_NAME,CLUSTER_NAME,PCT_FREE,PCT_USED,INI_TRANS,MAX_T        170 44840.8471        380
RANS,INITIAL_EXTENT/

select column_name,data_type,data_length,nullable,data_default,data_precision,da        127 48466.2047        310
ta_scale from user_t

 select /*+ no_parallel(t) no_parallel_index(t) dbms_stats cursor_sharing_exact         104 11319.4615       1182
use_weak_name_resl d

SELECT /*+ cursor_sharing_exact */ count(*) FROM  "SYS"."KUPC$DATAPUMP_QUETAB" T        100      12426          0
AB, SYS.DUAL WHERE t

select /*+ no_parallel(t) no_parallel_index(t) dbms_stats cursor_sharing_exact u         93 51273.5484       1069
se_weak_name_resl dy

SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB         91 17089.3187       1338
) opt_param('paralle

    SELECT     tau.user_id,     tau.aplus_level_no,     taf.appr_stat_cd    FROM         63 19573.8413        252
     aplus001iuser.t

select * from ( select rank() over ( order by last_access_dt desc , rownum) AS r         49 32231.8367        161
n, user_id,uid_2,car

insert into TBL_ObjectiveEventLog (regist_dt,event_id,objective_id,carrier_id,us         34 10804.2353        397
er_id,event_clear_co

SELECT COUNT(DISTINCT BAG_USER_ID), COUNT(DISTINCT CAP_USER_ID) FROM (SELECT CAS         32    22367.5       4622
E MBAG.BAG_KIND WHEN

SELECT COUNT(DISTINCT APL_USER_ID), COUNT(DISTINCT SMS_USER_ID) FROM (SELECT CAS         32   23160.75       4458
E MAPP.SMST_FLG WHEN

select item_id,category_id,item_nm,carrier_1_publish_flg,carrier_2_publish_flg,c         25   13244.16         88
arrier_3_publish_flg

SELECT * FROM (SELECT DISTINCT user_id, 1 as carrier_id, row_number() over( orde         22 17519.6364         65
r by last_adm_dt  )

SELECT alias000$."STYLESHEET" AS STYLESHEET FROM "SYS"."METASTYLESHEET" alias000         20      14730        992
$ WHERE 1 = 1 AND ((

select user_regist_kind1, TO_CHAR(last_adm_dt_kind1,'YYYY/MM/DD HH24:MI:SS') as          20    24929.2         93
last_adm_dt_kind1 fr

SELECT     user_id,     sum(prev_user_point_amt),      sum(user_point_result_amt         18 15337.3333         19
),     trunc(update_

    SELECT     mfri.free_rankavg_incentive_id,     mfri.free_rankavg_id,     mfr         18      15336         18
i.team_flg,     mfri

     sss01dbiuser.         17 22733.6471        291
tbl_usermyroom1

select * from (       select temp_.*, rownum as rownumber_ from (            SEL         16    35747.5        389
ECT         mwp.aplu

select * from (       select temp_.*, rownum as rownumber_ from (            sel         15    34043.2      13478
ect     user_id,

SELECT count(DISTINCT user_id) as datacount FROM MST_User1 WHERE user_id in (SEL         15    14788.8         42
ECT user_id FROM MST

SELECT AP001_ID,USER_ID,AP001_LEVEL_NO,MISSION_COMPLETE_PCT,TOTAL_GAME_CNT,TOTAL         13 27131.0769         87
_COIN_AMT,TOTAL_DECO

select user_id,nick_name,mail,mail_sec,mail_domain,user_name,user_zip,user_pref,         12 29984.6667       5073
user_address,to_char

SELECT AP001_ITEM_ID,AP001_ID,AP001_ITEM_CATEGORY_CD,CARRIER_1_PUBLISH_FLG,CARRI         12       9270         31
ER_1_PUBLISH_DT,CARR

2011年2月24日木曜日

LOBセグメントからテーブル名を探す

LOBはテーブルセグメントとは別管理なので、セグメントのサイズを確認するとSYS_LOB
から始まるセグメント名で表示されます。
shrinkするのにテーブル名を知りたい場合、dba_lobsで探すことができます。
set time on
set pages 10000
set lines 120
col owner for a20
col tablespace_name for a20
col table_name for a30
col column_name for a20
col segment_name for a30
select owner,segment_name,tablespace_name,table_name,column_name from dba_lobs
where segment_name in ('SYS_LOB0000032214C00005$$','SYS_LOB0000032217C00014$$');
実行例は次の通り。
OWNER           SEGMENT_NAME                   TABLESPACE_NAME TABLE_NAME           COLUMN_NAME
--------------- ------------------------------ --------------- -------------------- --------------------
SSS01DBIUSER    SYS_LOB0000032214C00005$$      SSS01_I_DATA    TBL_AAARESTEXT1      AAA_ANS_TEXT
SSS01DBIUSER    SYS_LOB0000032217C00014$$      SSS01_I_DATA    TBL_GENERALENTRY1    GENERALENTRY_FREE

セグメントのサイズを確認する

テーブルやインデックスなどのセグメントは、使ううちに断片化して肥大化します。
定期的にサイズをチェックし、shrinkなどの対策をするといいでしょう。
set time on
 set pages 10000
 set lines 120
 col segment_name for a30
 col tablespace_name for a20
 col bytes for 9,999,999,999
 select tablespace_name,segment_name,bytes from (
   select rank() over (order by bytes desc) rnk,
     tablespace_name,segment_name,bytes from dba_segments
 ) where rnk<=20;
実行例は次の通り。
TABLESPACE_NAME      SEGMENT_NAME                            BYTES
-------------------- ------------------------------ --------------
SSS01_INDPA1_DATA    TBL_CHARGECONSENTLOG1           1,412,431,872
SSS01_MASTERD_DATA   TBL_OBJECTIVESTREAMING01LOG1    1,046,478,848
SSS01_MASTERD_DATA   IXT2_OBJECTIVESTREAMING01LOG1     745,537,536
SSS01_MASTERD_DATA   TBL_MEDIAAPPITEMLOG1              732,954,624
SSS01_MASTERD_DATA   TBL_OBJECTIVESTREAMING01LOG3      495,976,448
SSS01_MASTERD_DATA   TBL_OBJSTREAMING01LOG1_1201       490,733,568
SSS01_MASTERD_DATA   TBL_OBJSTREAMING01LOG1_0101       475,004,928
SSS01_MASTERD_DATA   TBL_OBJSTREAMING01LOG1_0201       452,984,832
SSS01_MASTERD_DATA   TBL_CCACCESS1                     418,381,824
SSS01_MASTERD_DATA   TBL_OBJSTREAMING01LOG1_1101       387,973,120
SSS01_MASTERD_DATA   IXT2_OBJECTIVESTREAMING01LOG3     353,370,112
FUKA_I_DATA          TBL_OBJECTIVESTREAMING011         344,981,504
SSS01_MASTERD_DATA   TBL_MEDIABAGLOG1                  342,884,352
FUKA_I_DATA          TBL_DAILYTEXTMACHINEUPLOAD1       319,815,680
FUKA_I_DATA          TBL_USERSESSION1                  318,767,104
FUKA_I_DATA          TBL_DAILYTEXTTOTALUPLOAD1         279,969,792
SSS01_I_DATA         TBL_USERSESSION1                  264,241,152
FUKA_I_DATA          TBL_CCQUIZ_USER_RESULT1           244,318,208
FUKA_I_IDX           IXT1_DAILYTEXTTOTALUPLOAD1        236,978,176
SSS01_MASTERD_DATA   TBL_OBJSTREAMING01LOG3_0201       227,540,992

2011年2月18日金曜日

スキーマの表領域へのアクセス制限を確認する

スキーマ作成および権限付与(grant)をしても、特定の表領域を参照できないときは確認してみるといいでしょう。
表領域への割り当て制限設定がされていないと、権限があっても参照できません。
SQL> SELECT * FROM user_ts_quotas;
MAX_BYTES  ・・・  利用できる上限。負の値は無制限

TABLESPACE_NAME                     BYTES  MAX_BYTES     BLOCKS MAX_BLOCKS DRO
------------------------------ ---------- ---------- ---------- ---------- ---
SSS01_INDEP3_DATA                       0         -1          0         -1 NO
MVLOG_I_DATA                    161480704         -1      19712         -1 NO
SSS01_MASTER_IDX                        0         -1          0         -1 NO
SSS01_HISTORY_IDX                       0         -1          0         -1 NO
SSS01_MASTER_DATA                       0         -1          0         -1 NO
SSS01_HISTORY_DATA                      0         -1          0         -1 NO
SSS01_I_DATA                   4600102912         -1     561536         -1 NO
CCCC01TOWN_DATA                         0         -1          0         -1 NO
MVLOG_I2_DATA                           0         -1          0         -1 YES
SSS01_I_IDX                    3890216960         -1     474880         -1 NO
SSS01_INDEP1_DATA                       0         -1          0         -1 NO
CCCC01TOWN_IDX                          0         -1          0         -1 NO
SSS01_INDEP1_IDX                        0         -1          0         -1 NO
SSS01_INDEP2_IDX                        0         -1          0         -1 NO
SSS01_INDEP2_DATA                       0         -1          0         -1 NO
SSS01_INDEP3_IDX                        0         -1          0         -1 NO

2011年2月17日木曜日

共有プールの利用状況を確認する

負荷特性の異なる処理を混在させている場合、共有プールの変化をウォッチしておくとボトルネックを見つけられることがあります。
sql area   ・・・   SQL文そのもののキャッシュ
CCursor/PCursor   ・・・   カーソルキャッシュ
library cache   ・・・   コンパイル済SQLのキャッシュ
free memory   ・・・   空きメモリ

set pages 10000
set lines 100
set time on
col name for a30
col bytes for 999,999,999,999
select name,bytes from (
 select row_number() over (order by bytes desc) as rn,name,bytes from v$sgastat
 where pool = 'shared pool'
) where rn <= 20;

NAME                                      BYTES
------------------------------ ----------------
sql area                          2,484,421,928
free memory                       1,734,338,672
CCursor                             678,436,864
PCursor                             472,727,184
library cache                       352,787,688
sql area:PLSQL                      346,800,984
kglsim object batch                 182,272,608
gcs resources                       128,586,016
kglsim heap                         104,469,120
Cursor Stats                         98,273,576
gcs shadows                          76,999,136
db_block_hash_buckets                47,185,920
ASH buffers                          30,408,704
ges enqueues                         19,842,976
ges big msg buffers                  15,936,168
trace buffer                         14,057,472
KGLS heap                            13,290,704
event statistics per sess            12,296,000
FileOpenBlock                        11,575,096
ges resource                         11,342,888
似たSQLが多いWebサイト処理と、SQL数が多くなりがちな大量更新バッチを混在させていると次のグラフのようになることがあります。 バッチを実行していない時はfreeがかなり多いためボトルネックを見つけづらいと思います。