Miladin Modrakovic’s Blog: Oraclue

July 7, 2009

Troubleshooting SQL*NET

Filed under: Troubleshooting — oraclue @ 9:57 pm

Few weeks ago I found very good white paper which explains sqlnet trace files.I wrote about it in previous blog

http://oraclue.com/2009/05/27/examining-oracle-net-trace-files/

 I was troubleshooting sqlnet  issue today and used very same article  to read trace files.It was very useful.

Also I used  tool that I completely forgot .I am talking about  Oracle Trace Assistant  or Oracle binary  trcasst

For large trace files this can be very useful.It is very easy to use:

 Usage : trcasst [options] <filename>
      [options]  default values are -odt -e0 -s
      <filename>  always last argument
    -o[c|d][u|t][q]  Net Services and TTC information
      [c]  Summary of Net Services information
      [d]  Detailed Net Services information
      [u]  Summary of TTC information
      [t]  Detailed TTC information
      [q]  SQL commands (used together with u)
    -s  Statistics
    -e[0|1|2]  Error information, default is 0
      [0]  Translate NS error numbers
      [1]  Error translation
      [2]  Error numbers without translation
    -l[a|i <connection_id>]  Connection information
      [a]  List all connections in a trace file
      [i <connection_id>]  Decode a specified connection

Most useful option in my case was error information or  ( -e )

trcasst -e  sqlnet_tracefile.trc

It gives NS & NT Errors Translation or  TNS familiar error number.Then at least you can get some idea what is going on.Oracle has explanation for Error Stack Components which  helps to narrow issue.

Do not forget to  check with your network admin and see if there is any firewall or F5 involved .

References:

Oracle Net8 Administrator’s Guide – Chapter 10 Troubleshooting

Metalink:  Network Products and Error Stack Components  Doc ID:  39662.1

July 1, 2009

Process diagnostic

Filed under: Uncategorized — oraclue @ 7:46 pm

Each Oracle process has a process state object.Process is running session  and session open transaction.Typically process has only one session object.

To dump a process state  I normally use:

alter session set events ‘immediate trace name processstate level 10′ or

oradebug dump processstate 10

This dump will produce file which has many different information about process itself like process global information, dump of memory , session wait history etc.

The oradebug  unit test harness command has option ( ksdxutdiagpid ) that will produce similar dump but smaller in size and with some information that are not included in processstate dump with level 10.

So here is my short list of commands :

oradebug setmypid
alter system flush buffer_cache;
select * from dba_extents;
oradebug unit_test_nolg ksdxutdiagpid
oradebug tracefile_name

First part of dump file has general process information like pid, sid, session serial etc

*** 2009-06-29 15:45:14.517
Process diagnostic dump for oracle@apollo (TNS V1-V3), OS id=6957,
pid: 29, proc_ser: 139, sid: 238, sess_ser: 30736
——————————————————————————-

Next section  has information about memory, swap and process.

loadavg : 0.21 0.17 0.13
memory info: free memory = 0.00M
swap info:   free = 0.00M alloc = 0.00M total = 0.00M
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
0 S oracle    5334     1  0  75   0 – 695798 -     Jun11 ?        00:00:42 ora_lgwr_test
0 S oracle    6957  6956  1  78   0 – 692473 pipe_w 15:41 ?       00:00:02 oracletest11g (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
0 S oracle   25659     1  0  75   0 – 695799 -     Jun01 ?        01:07:44 ora_lgwr_demo

Third part is a short stack dump with all Oracle functions

Short stack dump: <-ksedsts()+315<-ksdxfstk()+32<-ksdxdocmdmultex()+3456<-ksdxdocmdmult()+29<-ksudmp_proc_short_stack()+697<-ksdhng_diag_proc_int(
)+2760<-ksdhng_diag_proc()+27<-ksdhng_diag_proc_ut()+139<-ksdxutdiagpid()+114<-ksdxuth()+1249<-ksdxen_int()+5656<-ksdxen()+14<-opiodr()+1220<-ttcp
ip()+1208<-opitsk()+1449<-opiino()+1026<-opiodr()+1220<-opidrv()+580<-sou2o()+90<-opimai_real()+145<-ssthrdmain()+177<-main()+215<-__libc_start_ma
in()+244<-_start()+41

Next part has information about wait stack and wait state:

Current Wait Stack:
0: waiting for ‘process diagnostic dump’
=0, =0, =0
wait_id=22666 seq_num=22667 snap_id=1
wait times: snap=0.153272 sec, exc=0.153272 sec, total=0.153272 sec
wait times: max=30.000000 sec
wait counts: calls=0 os=0
in_wait=1 iflags=0×1a0
Wait State:
auto_close=0 flags=0×22 boundary=(nil)/-1

and last part is dedicated to session wait history and sampled session history:

Session Wait History:
0: waited for ‘SQL*Net message from client’
driver id=62657100, #bytes=1, =0
wait_id=22665 seq_num=22666 snap_id=1
wait times: snap=0.002478 sec, exc=0.002478 sec, total=0.002478 sec
wait times: max=infinite
wait counts: calls=0 os=0
occurred after 0.002582 sec of elapsed time
1: waited for ‘db file sequential read’
file#=3, block#=1b179, blocks=1
wait_id=22664 seq_num=22665 snap_id=1
wait times: snap=0.000013 sec, exc=0.000013 sec, total=0.000013 sec
wait times: max=infinite
wait counts: calls=0 os=0
occurred after 0.000127 sec of elapsed time

———-
The history is displayed in reverse chronological order.

sample interval: 1 sec, max history 120 sec
—————————————————
[1 sample,                                                          15:45:14]
waited for ‘db file sequential read’, seq_num: 22340
p1: ‘file#’=0×2
p2: ‘block#’=0×9a53
p3: ‘blocks’=0×9a53
time_waited: >= 0 sec (still in wait)
[1 sample,                                                          15:45:13]
idle wait at each sample
[1 sample,                                                          15:45:12]
waited for ‘db file sequential read’, seq_num: 18907
p1: ‘file#’=0×2
p2: ‘block#’=0×13e03
p3: ‘blocks’=0×13e03
time_waited: 0.003633 sec (sample interval: 0 sec)
[1 sample,                                                          15:45:11]
waited for ‘db file sequential read’, seq_num: 16332
p1: ‘file#’=0×1
p2: ‘block#’=0×2b01
p3: ‘blocks’=0×2b01
time_waited: 0.005140 sec (sample interval: 0 sec)
[10 samples,                                             15:45:01 - 15:45:10]

Cool thing is that one command dump all of this.

June 25, 2009

Memory Diagnostics – Part 2

Filed under: Internals — oraclue @ 5:00 pm

Well I had this post ready to publish today and did last check on google to find some additional resources and it turned out that
Tanel got this one just day before.It seems that memory is popular topic these days.
I am not going to repeat it since he covered this topic pretty good.

Here is link to Tanel’s post :

http://blog.tanelpoder.com/2009/06/24/oracle-memory-troubleshooting-part-3-automatic-top-subheap-dumping-with-heapdump/

I found some of these information researching  memory leak bugs.

In particulary Metalink  Doc ID:  784804.1

June 19, 2009

Memory Diagnostics – PGA Part 1

Filed under: Internals — oraclue @ 8:35 pm

Second and very short post related to Oracle memory structures.This time I will focus on PGA .

Oracle offers many diffrents tools ( views, tables, dumps etc.. ) to gather information about these structures.This time I will introduce hidden oradebug options.

Reading these files is not difficult. There are also  heap analyzers out there on internet.

Since these dump files looks very familiar I will just focus on commands and syntax.

This is 3 line script to perform these dumps:

oradebug setmypid
oradebug unit_test_nolg &p
oradebug tracefile_name

First command will dump  PGAs information for all processes:

SQL> @od
Statement processed.
Enter value for p: dump_pga_details
Statement processed.

===============================================
PGA memory detail for pid 2, OS pid 13741
===============================================
2072 bytes,   3 chunks: “miscellaneous             “  PL/SQL
multiple heaps  ds=(nil)  dsprt=(nil)
42928 bytes,  90 chunks: “miscellaneous             “
multiple heaps  ds=(nil)  dsprt=(nil)
155824 bytes,  20 chunks: “permanent memory          “
pga heap        ds=0×9e5fa20  dsprt=(nil)
53120 bytes,   2 chunks: “free memory               “
session heap    ds=0×2aaaabd66998  dsprt=0×9e65120
44608 bytes,   1 chunk : “permanent memory          “
session heap    ds=0×2aaaabd66998  dsprt=0×9e65120
32792 bytes,   1 chunk : “permanent memory          “

———————————————————-
===============================================
PGA memory detail for pid 3, OS pid 13743
===============================================
141976 bytes,  18 chunks: “permanent memory          “
pga heap        ds=0×9e5fa20  dsprt=(nil)
53120 bytes,   2 chunks: “free memory               “
session heap    ds=0×2aaaabd66998  dsprt=0×9e65120
44608 bytes,   1 chunk : “permanent memory          “
session heap    ds=0×2aaaabd66998  dsprt=0×9e65120
32792 bytes,   1 chunk : “permanent memory          “
top call heap   ds=0×9e64f00  dsprt=(nil)
31608 bytes,   1 chunk : “free memory               “
top call heap   ds=0×9e64f00  dsprt=(nil)
31328 bytes,   1 chunk : “Fixed Uga                 “
pga heap        ds=0×9e5fa20  dsprt=(nil)
27248 bytes,   6 chunks: “free memory

——————————————————————

(more…)

June 10, 2009

Memory Annotations and Oradebug

Filed under: Internals — oraclue @ 7:55 pm

Annotations can help to detect leaks and other problems with allocations of memory.

I will again use “old friend “  ORADEBUG

There are two  hidden options related to memory annotations:

MEMANOTEND <shared|private>                          – Record end-state mem annotations

MEMANOTDUMP <shared|private> <level>       -  Dump memory annotations

and four undocumented parameters :

_mem_annotation_pr_lev            private memory annotation collection level                           0
_mem_annotation_scale             memory annotation pre-allocation scaling                                 1
_mem_annotation_sh_lev            shared memory annotation collection level                            0
_mem_annotation_store             memory annotation in-memory store                                FALSE

So before you can use these options  I have to set these parameters.They cannot be changed dynamically

and  instance must be bounced.Something like this:

SQL> alter system set “_mem_annotation_store”=true scope=spfile;

System altered.  etc for the rest..

and now after restarting instance:

First set the process

SQL> oradebug setmypid
Statement processed.

Start recording :

SQL> oradebug memanotend private
Statement processed.

and at the end dump context into trace file:

SQL> oradebug memanotdump private 1
Statement processed.

SQL> oradebug tracefile_name
/oracle/diag/rdbms/test/test2/trace/test2_ora_26953.trc

host vi ora-main/app/oracle/diag/rdbms/test/test2/trace/test2_ora_26953.trc

In some cases when you set these parameters you will get ORA-600 like

ORA-00600: internal error code, arguments: [kspgip1], [101], [121], [1], [_mem_annotation_sh_lev],

or  ORA-00600: internal error code, arguments: [ksmanotsh:size]  but  here is option that will let you start your database:

more inittest.ora

*._mem_annotation_store=TRUE
*._mem_annotation_sh_lev=0
*._mem_annotation_scale=10
*._mem_annotation_pr_lev=1

-sh-3.1$ sqlplus / as sysdba

SQL*Plus: Release 11.1.0.7.0 – Production on Thu Jun 18 12:33:48 2009

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

Connected to an idle instance.

SQL> startup pfile=’/oracle/admin/test/pfile/inittest.ora’;
ORACLE instance started.

Total System Global Area 2622255104 bytes
Fixed Size                  2162960 bytes
Variable Size             738201328 bytes
Database Buffers         1862270976 bytes
Redo Buffers               19619840 bytes
Database mounted.
Database opened.

SQL> select * from v$version;
BANNER
——————————————————————————–
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 – 64bit Production
PL/SQL Release 11.1.0.7.0 – Production
CORE    11.1.0.7.0      Production
TNS for Linux: Version 11.1.0.7.0 – Production
NLSRTL Version 11.1.0.7.0 – Production

SQL> set linesize 125 pagesize 50 newpage 0
SQL> col param_dflt form a3 head ‘Dflt?’
SQL> col param_name form a33 head ‘Parameter’
SQL> col param_value form a20 head ‘Value’
SQL> col DESCP format a64
SQL> select decode (ksppstdf, ‘FALSE’, ‘NO’, ‘ ‘) param_dflt,
2  ksppinm param_name,ksppdesc descp, ksppstvl param_value
3  from x$ksppi, x$ksppcv
4  where x$ksppi.indx = x$ksppcv.indx
5  and ksppinm like ‘%&1%’
6  order by ksppinm;
Enter value for 1: annota
old   5: and ksppinm like ‘%&1%’
new   5: and ksppinm like ‘%annota%’

Dfl Parameter                         DESCP                                                            Value
— ——————————— —————————————————————- ——————–
NO  _mem_annotation_pr_lev            private memory annotation collection level                       1
NO  _mem_annotation_scale             memory annotation pre-allocation scaling                         10
NO  _mem_annotation_sh_lev            shared memory annotation collection level                        0
NO  _mem_annotation_store             memory annotation in-memory store                                TRUE
_optimizer_reuse_cost_annotations reuse cost annotations during cost-based query transformation    TRUE

SQL> oradebug setmypid
Statement processed.

SQL> oradebug memanotend private
Statement processed.

SQL> oradebug memanotdump private 1
Statement processed.

SQL> oradebug tracefile_name

/oracle/admin/test/diag/rdbms/test/test/trace/test_ora_30961.trc

SQL> host vi test_ora_30961.trc

SQL> host vi /oracle/admin/test/diag/rdbms/test/test/trace/test_ora_30961.trc

*** 2009-06-18 12:34:49.059
Oradebug command ’setmypid’ console output: <none>

*** 2009-06-18 12:34:57.811
Processing Oradebug command ‘memanotend private’

*** 2009-06-18 12:34:57.811
Oradebug command ‘memanotend private’ console output: <none>

*** 2009-06-18 12:35:05.971
Processing Oradebug command ‘memanotdump private 1′

*** 2009-06-18 12:35:05.971
MEMORY ANNOTATION DUMP
———————-
Region: private
Level: 1
Level collected: 1
LEVEL ADDRESS          SIZE         NAME:TYPE
—– —————- ———— —————————————-
END OF MEMORY ANNOTATION DUMP

June 2, 2009

Oracle diagnostic events Part 5

Filed under: Internals — oraclue @ 5:18 pm

I know I already did four blogs on events but there is more to cover.

This short post will focus on some of the  trace option and it’s components.

trace[target ]<components>

In previous post I have used example something like:

alter session set events ‘trace[sql_mon] memory=high,get_time=highres’;

where sql_mon is target of interest

Just for reference here is list of targets that I have already posted:

bind_capture  -  capturing binds

dirpath_load  – direct load

explain       -  explain plan

sql_apa       – access path analysis

sql_analyze   -  sql analyze

sql_perf      -  performance analyzer

sql_tune      -  tuning advisor

sql_mon       -  sql monitor

sql_optimizer -  optimizer

sql_planmanagement – plan management

sql_costing        – cost based analysis

sql_transform     – sql transformation

sql_execution     – sql execution

Now let’s see what other options I can use in conjuction with target.

In my previous example I have used options memory and get_time :

alter session set events ‘trace[sql_mon] memory=high,get_time=highres’;

so this command will trace in memory sql monitor on high resolution.

Here is list of all combination:

[disk=DISABLE | LOW | LOWEST | MEDIUM | HIGH | HIGHEST]

[memory=DISABLE | LOW | LOWEST | MEDIUM | HIGH | HIGHEST]

[get_time=DISABLE | DEFAULT | SEQ | HIGHRES | SEQ_HIGHRES ]

[get_stack=DISABLE | DEFAULT | ENABLED ]

These options are self explanatory.

Just a few examples:

alter session set events ‘trace[sql_mon] memory=high,get_time=highres’;

alter session set events ‘trace[sql_mon] disk=highest,get_time=highres,get_stack=default’;

May 27, 2009

Examining Oracle Net Trace Files

Filed under: Troubleshooting — oraclue @ 5:20 pm

I lost a count how many times I had to trace sqlnet clients and collect trace files .Many times I tried to read them and understand what is realy going on,  but these files are hard to read and understand without detail explanation of Oracle Net protocol.Ultimatelly Oracle support will analyze them and send explanation.

Oracle white paper Examining Oracle Net Trace Files  that I have found on metalink explains connection process to the database and “decrypt “  trace codes.Here is link:

https://metalink2.oracle.com/metalink/plsql/docs/282035.pdf

or Metalink:  Doc 156485.1

May 18, 2009

Procedure to kill blocking session in RAC 11g

Filed under: Troubleshooting — oraclue @ 7:10 pm

Many times I tried to kill session in RAC  and then get message back saying that session cannot be killed because my session is connected to different instance.Then I would login to instance where blocking sessions runs  and kill it.

Starting with 11g , Oracle included instance name in alter system kill command (3thd parameter or  @instance_id ) .So to kill blocking session on any node from any node I would run:

SQL> set serveroutput on
SQL> exec kill_blocker;

ALTER SYSTEM KILL SESSION ‘115,9779,@1′ 

PL/SQL procedure successfully completed.

 

Code is below.It is standard code for detecting blocking session in RAC which can be found on google.I just modified it to include instance id and placed into procedure

CREATE OR REPLACE PROCEDURE kill_blocker
AS
   sqlstmt   VARCHAR2 (1000);
BEGIN
   FOR x IN (SELECT gvh.SID sessid, gvs.serial# serial,
                    gvh.inst_id instance_id
               FROM gv$lock gvh, gv$lock gvw, gv$session gvs
              WHERE (gvh.id1, gvh.id2) IN (SELECT id1, id2
                                             FROM gv$lock
                                            WHERE request = 0
                                           INTERSECT
                                           SELECT id1, id2
                                             FROM gv$lock
                                            WHERE lmode = 0)
                AND gvh.id1 = gvw.id1
                AND gvh.id2 = gvw.id2
                AND gvh.request = 0
                AND gvw.lmode = 0
                AND gvh.SID = gvs.SID
                AND gvh.inst_id = gvs.inst_id)
   LOOP
      sqlstmt :=
            ‘ALTER SYSTEM KILL SESSION ”’
         || x.sessid
         || ‘,’
         || x.serial
         || ‘,@’
         || x.instance_id
         || ””;
      DBMS_OUTPUT.put_line (sqlstmt);

      EXECUTE IMMEDIATE sqlstmt;
   END kill_blovk;
END TEST;
/

Just a note. If you are not comfortable killing session owned by SYS than exclude them from query…

April 23, 2009

Detecting Deadlock Source Part 2

Filed under: Troubleshooting — oraclue @ 7:26 pm

This is very simple  deadlock case.Instad of event 10046 ( that I have used in previous blog ) to identify initial TX locks this time
I  have used flashback version query and flashback transaction query .

So here is demo:

First craete table and populate some rows:

create table t(a int primary key);

insert into t select rownum from dba_tables where rownum <5;
commit;

SQL> @ct

Table created.
4 rows created.
Commit complete.

SQL> select * from t;

A
———-
1
2
3
4

Now cause deadlock by running these updates in 2 different session is following order:

Session 1:

update t set a=5 where a=1;
update t set a=6 where a=2;

Session 2:

update t set a=7 where a=3;
update t set a=8 where a=4;

Session 1:

update t set a=9 where a=3;

Session 2:

update t set a=10 where a=1;

Last update will cause deadlock and my session 1 will die:

update t set a=9 where a=3
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource

Now when I select from t and see what it looks like:

SQL> select * from t;

A
———-
5
6
7
8

Diagnostic part:

I will first run flashback version query to get transaction ID ( XID ) for my transactions:

SQL> ALTER SESSION SET nls_timestamp_format = ‘DD-MON-YYYY HH24:MI:SS.FF3′;

SQL> l
1  SELECT     VERSIONS_XID
2      ,      VERSIONS_STARTTIME
3      ,      VERSIONS_ENDTIME
4      ,      VERSIONS_STARTSCN
5      ,      VERSIONS_ENDSCN
6      ,      VERSIONS_OPERATION
7      ,      a
8      FROM   miladin.t VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE
9     ORDER  BY
10*            VERSIONS_STARTTIME
SQL> /

VERSIONS_XID     VERSIONS_STARTTIME             VERSIONS_ENDTIME               VERSIONS_STARTSCN VERSIONS_ENDSCN V          A
—————- —————————— —————————— —————– ————— – ———-
0A0015008B3D0000 23-APR-2009 14:08:54.000                                               30260800                 U          5
0A0015008B3D0000 23-APR-2009 14:08:54.000                                               30260800                 U          6
05000A00162C0000 23-APR-2009 14:09:00.000                                               30260807                 U          7
05000A00162C0000 23-APR-2009 14:09:00.000                                               30260807                 U          8
23-APR-2009 14:09:00.000                                30260807            3
23-APR-2009 14:09:00.000                                30260807            4
23-APR-2009 14:08:54.000                                30260800            1
23-APR-2009 14:08:54.000                                30260800            2

8 rows selected. (more…)

April 20, 2009

Detecting Deadlock Source Part 1

Filed under: Internals — oraclue @ 7:51 pm

In the case of deadlock oracle will raise ORA-60 error.Trace file is writen by the Global Enqueue Service Daemon (LMD) background process.

Trace file will record sql involved but NOT the SQL  that initialy took the locks.It will record last entries.

So how to resolve issue and get all data involved with deadlocks?

Before I get to that point let me create simple deadlock case:

create table test(a int primary key);

insert into test select rownum from dba_tables where rownum <9;
commit;
Session 1:

update test set a=9 where a=1;
update test set a=10 where a=2;

session 2:

update test set a=11 where a=3;
update test set a=12 where a=4;

session 1:

update test set a=25 where a=8;
update test set a=13 where a=3;
session 2:

update test set a=22 where a=6;
update test set a=14 where a=1;

To troubleshoot deadlock I have create after logon trigger on database.
Although I can place all these commands together ( new option with events ) just for easy read I have used execute immediate for every command.
I have used new events syntax in 11g so  event 10046 is sql_trace, ORA-60 is deadlock.I have posted it on previous blogs.

For HANGANALYZE level 4 is used.This level dumps blockers.

Bellow is hanganalyze level description:

10     Dump all processes (IGN state)
5      Level 4 + Dump all processes involved in wait chains (NLEAF state)
4      Level 3 + Dump leaf nodes (blockers) in wait chains (LEAF,LEAF_NW,IGN_DMP state)
3      Level 2 + Dump only processes thought to be in a hang (IN_HANG state)
1-2    Only HANGANALYZE output, no process dump at all

and  trigger:

CREATE OR REPLACE TRIGGER SYS.TRACE_MILADIN_DEADLOCKS
after logon on database
begin
if user like ‘MILADIN’ then
execute immediate ‘alter session set timed_statistics=true’;
execute immediate ‘alter session set max_dump_file_size=unlimited’;
execute immediate ‘alter session set tracefile_identifier=”miladin_deadlock”’;
execute immediate ‘alter session set events ‘’sql_trace  wait=true, bind=true,plan_stat=all_executions,level=12”’;
execute immediate ‘alter session set events ”deadlock trace name hanganalyze_global level 4,forever”’;
execute immediate ‘alter session set events ”deadlock trace name systemstate level 266,lifetime 1”’;
execute immediate ‘alter session set events ”deadlock trace name processstate level 10,forever”’;
end if;
end;
/

(more…)

Older Posts »

Blog at WordPress.com.