Beruflich Dokumente
Kultur Dokumente
SMON Snnn
Dnnn Pnnn
PMON
SGA Redo Log
CKPT
Shared Pool Database Buffer Cache Buffer
DBWR
ARCH
LGWR
DBWR
LGWR ARCH oracle
User Queries
– User info v$session
– System info v$parameter
– Performance statistics v$sysstat, v$latch, v$system_event
– Buffer cache headers, x$bh
Why Direct Access with C?
Reading Hidden Information
– Sort info on version 7
– OPS locking info version 8
– Contents of data blocks (only the headers or visible in X$)
Low overhead
Database Slow or Hung
Often happens at the largest sites when
cutting edge support is expected.
0x80000000
SGA SGA
Buffer Cache
Graphic SGA
SGA
0x80000000
Fixed Area
Buffer Cache
Shared Pool
Log Buffer
Fixed Area
SGA X$KSUSECST- user waits
0x80000000
0x85251EF4
X$KSUSECST
170 Records
2328 bytes
1276
2328 bytes
X$KSUSECST Fields
Seq # Event # p1 p2 p3
Externalization of C structs: X$
tables
struct foo
{
int id;
int A;
int B;
int C;
};
struct foo foo[N];
Struct C code
#include <stdio.h>
#include <fcntl.h>
#define N 20
/* structure definition: */
struct foo
{
int id;
int a;
int b;
int c;
};
/* end structure definition */
Struct Record
main(){
struct foo foo[20];
int fptr;
/* zero out memory of struct */
memset(foo,0,sizeof(foo));
foo[0].id=1; /* row 0 */
foo[0].a=12;
foo[0].b=13;
foo[0].c=13;
Struct Write to File
foo[1].id=2; /* row 1 */
foo[1].a=22;
foo[1].b=23;
foo[1].c=24;
/* write to file, simulate SGA */
if ((fptr = open("foo.out",O_WRONLY | O_CREAT,0777)) < 0 )
return -1;
write(fptr,foo,sizeof(foo));
return 0;
}
Simulate SGA with a File
write(fp,foo,sizeof(foo));
Simulate SGA with a File
Row 0 Row 1
ID A B C ID A …
0 1 3 4 6 8 bits
0 4
6 8
2 1
8 1
4 2
0 bytes
0 4 8 C
2 1
6 1
0 hex bytes
0 4 1 1 2
0 2
4 oct
0
Memory address 4 0 4
Increasing bytes
Struct File Contents
$ ./foo
$ ls -l foo.out
-rw-r--r-- joe dba 320 Feb 10 19:41 foo.out
int = 32 bits
Int = 4 bytes
20 entries * 4 int * 4 bytes/int = 320 bytes
od – octal dump
$ od -l foo.out
0000000 1 12 13 13
0000020 2 22 23 24
0000040 0 0 0 0
*
0000500
Struct File Contents
Address is in Hex
Column 2 is the ID
Column 3 is field A
Column 4 is field B
Column 5 is field C
X$ tables ?
Ok, x$foo =~ foo[20]
How do I get a list of x$ tables?
Where is each X$ located?
V$Fixed_Tables
V$Fixed_Table – list of X$
tables
0x8????????
X$????
V$Fixed_Table
spool addr.sql
select
'select 'addr, ||''''||name||''''||' from ' || name ||'
where rownum < 2;'
from
v$fixed_table
where
name like 'X%'
/
spool off
@addr.sql
Example: finding the address
select
a.addr ,
'X$KSUSE'
from
X$KSUSE
where
rownum < 2 ;
X$ layout
6802B244 X$KSLEMAP
6802B7EC X$KSLEI
6820B758 X$KSURU
6820B758 X$KSUSE - v$session
6820B758 X$KSUSECST – v$session_wait
6820B758 X$KSUSESTA – v$session_stat
6820B758 X$KSUSIO
6826FBD0 X$KSMDD
6831EA0C X$KSRCHDL
What's in these X$ views
V$ views are documented
V$ views are based often on X$ tables
The map from v$ to X$ is described in :
V$Fixed_View_Definition
V$Fixed_View_Definition
SQL> desc V$Fixed_View_Definition
Name Type
----------------------------------- --------------
VIEW_NAME VARCHAR2(30)
VIEW_DEFINITION
VARCHAR2(4000)
Definition of V$Session_Wait
SQL> select
VIEW_DEFINITION
from
V$FIXED_VIEW_DEFINITION
where
view_name='GV$SESSION_WAIT';
VIEW_DEFINITION
-----------------------------------------------------------------------
select s.inst_id,s.indx,s.ksussseq,e.kslednam, e.ksledp1,s.ksussp1,s.ksussp1r,e.
ksledp2, s.ksussp2,s.ksussp2r,e.ksledp3,s.ksussp3,s.ksussp3r, decode(s.ksusstim,
0,0,-1,-1,-2,-2, decode(round(s.ksusstim/10000),0,-1,round(s.ksusstim/10000)))
, s.ksusewtm, decode(s.ksusstim, 0, 'WAITING', -2, 'WAITED UNKNOWN TIME', -1, '
WAITED SHORT TIME', 'WAITED KNOWN TIME') from x$ksusecst s, x$ksled e where bit
and(s.ksspaflg,1)!=0 and bitand(s.ksuseflg,1)!=0 and s.ksussseq!=0 and s.ksussop
c=e.indx
The Fields in X$ tables
OK, I've picked an X$
I've got the starting address
Now, how do I get the fields?
X$KQFTA
Kernel Query Fixed_view Table
INDX use to find column information
KQFTANAM X$ table names
X$KQFCO
Kernel Query Fixed_view Column
KQFCOTAB Join with X$KQFTA.INDX
KQFCONAM Column name
KQFCOOFF Offset from beginning of the row
KQFCOSIZ Columns size in bytes
X$KSUSECST Fields
Seq # Event # p1 p2 p3
2 2 4 4 4 BYTES
SGA Contents in Resume
In resume:
Oracle takes the C structure defining the
SGA and maps it onto a shared memory
segment
Memory address Increasing
0x80000
00
Fixed Buffer Redo Library
SGA Cache Buffer Cache
Oracle provides access to some of the SGA
contents via X$ tables
**** Procedure *****
2. Choose a V$ view
3. Find base X$ Tables for v$ view
4. Map X$ fields to V$ fields
5. Get address of X$ table in SGA
6. Get the size of each record in X$ table
7. Get the number of records in X$ table
8. Get offsets for each desired field in X$ table
9. Get the base address of SGA
1) V$SESSION_WAIT Example
List of all users waiting
Detailed information on the waits
Data is ephemeral
Useful in Bottleneck diagnostics
High sampling rate candidate
Event 10046 captures this info
SQL> select
VIEW_DEFINITION
from
V$FIXED_VIEW_DEFINITION
where
view_name='V$SESSION_WAIT‘;
V$SESSION_WAIT View Definition
VIEW_DEFINITION
---------------------------------------------------------------------
select
s.inst_id,
s.indx,
s.ksussseq,
e.kslednam,
e.ksledp1,
s.ksussp1,
s.ksussp1r,
e.ksledp2,
s.ksussp2,
s.ksussp2r,
e.ksledp3,
s.ksussp3,
s.ksussp3r,
round(s.ksusstim / 10000),
s.ksusewtm,
decode(s.ksusstim, 0, 'WAITING', -2, 'WAITED UNKNOWN TIME',
-1, 'WAITED SHORT TIME', 'WAITED KNOWN TIME')
from
x$ksusecst s,
x$ksled e
where
bitand(s.ksspaflg,1)!=0 and
bitand(s.ksuseflg,1)!=0 and
s.ksussseq!=0 and
s.ksussopc=e.indx
View Definition Short
VIEW_DEFINITION
---------------------------------------------------------------------
select
s.indx,
s.ksussseq,
e.kslednam,
s.ksussp1,
s.ksussp2,
s.ksussp3
from
x$ksusecst s,
x$ksled e
where
s.ksussopc=e.indx
2) V$SESSION_WAIT Based on
X$KSUSECT
VIEW_DEFINITION
---------------------------------------------------
-
select
indx,
ksussseq,
ksussopc,
ksussp1,
ksussp2,
ksussp3
from
x$ksusecst
Equivalent SQL Statements
select select
indx, sid
ksussseq, seq#
ksussopc, event
ksussp1, p1
ksussp2, p2
ksussp3 p3
from from
x$ksusecst v$session_wait )
Note: x$ksusecst. Ksussopc is the event #
x$ksled.kslednam is a list of the event names where
x$ksled.indx = x$ksusecst. ksussopc
3) V$ to X$ Field Mapping
4) Get base SGA address for X$ table
ROW_SIZE
----------------
2328
6) Find the Number of Records in the
structure
SQL> select count(*) from x$ksusecst ;
COUNT(*)
--------------
170
Get Offsets for Each Desired Field in X$ table
SQL> select c.kqfconam field_name,
c.kqfcooff offset,
c.kqfcosiz sz
from
x$kqfco c,
x$kqfta t
where
t.indx = c.kqfcotab and
t.kqftanam='X$KSUSECST'
order by
offset
;
X$KQFTA - X$ Tables Names
List of X$ tables
X$KQFTA.INDX = X$KQFCO.KQFCOTAB
X$KQFCO – X$ Table Columns
List of all the columns in X$ Tables
• Unexposed Fields
• Sometimes exposed elsewhere, in our case
• V$SESSION
• V$SESSTAT
Fields at Same Address
Why do some fields start at the same address?
KSUSSP1
KSUSSP1R
Are at the same address
Equivalent of
V$SESSION_WAIT.P1
V$SESSION_WAIT.P1RAW
These are the same data, just exposed as
Hex
Decimal
7) Offsets of Fields
8) Get Base SGA Address
ADDR
--------------
80000000
Results X$KSUSECST
Machine Memory
0x80000000
SGA SGA
Fixed Area
SGA X$KSUSECST- user waits
0x80000000
0x85251EF4
X$KSUSECST
170 Records
2328 bytes
1276
2328 bytes
X$KSUSECST Fields
Seq # Event # p1 p2 p3
Attaching to the SGA
Finding Trace File
Shmid 34401
Shmaddr 0x80000000
Shmflg SHM_RDONLY
Spool events.h
select 'char event[][100]={' from dual;
select '"'||name||'",' from v$event_name;
select ' "" };' from dual;
spool off
Define Base Addresses and Sizes
/* SGA BASE ADDRESS */
#define SGA_BASE 0x80000000
#ifdef __linux
uflg=*(short
*)((int)sga_address)>>8;
#else
uflg=*(short *)((int)sga_address);
#endif
Byte Swap
Big Endian:
00 00 00 00 00 00 00 01
Little Endian
00 00 00 01 00 00 00 00
Solution, push the value over 8 places, to
the right,
ie >>8
64 bit vs 32 bit
SQL> desc x$ksmmem
Name Type
------------------------------------- ---------
ADDR RAW(4)
INDX NUMBER
INST_ID NUMBER
KSMMMVAL RAW(4)
-> 32 bit
Raw(8) -> 64 bit
Segmented Memory
x$ksuse – can be dis-contiguous
Work around:
select 'int users[]={' from dual;
select '0x'||addr||',' from x$ksuse;
select '0x0};' from dual;
Misaligned Access
Some platforms seg fault when
addressing misaligned bytes, need to
read in even bytes or units of 4 bytes
depending on platform
1 2 3 4 5 6 7 8
x$ksusecst Record: What's Missing?
??? ???
1276
2328 bytes
Select Addr from X$? where
Rownum< 2;
6802B244 X$KSLEMAP
6802B7EC X$KSLEI
6820B758 X$KSURU
6820B758 X$KSUSE – v$session
6820B758 X$KSUSECST – v$session_wait
6820B758 X$KSUSESTA – v$sesstat
6820B758 X$KSUSIO
6826FBD0 X$KSMDD
6831EA0C X$KSRCHDL
x$ksuse Record Contains
x$ksusecst
2328 bytes
x$ksusesta x$ksusecst
x$ksuse
Getting v$sesstat addresses
select '#define '||
upper(translate(s.name,' :-()/*''','________'))||' '||
to_char(c.kqfcooff + STATISTIC# * 4 )
from
x$kqfco c,
x$kqfta t,
v$statname s
where
t.indx = c.kqfcotab
and ( t.kqftanam='X$KSUSESTA' ) and
c.kqfconam='KSUSESTV'
and kqfcooff > 0
order by
c.kqfcooff
/
User Drilldown Query: 4 joins
select
w.sid sid,
w.seq# seq,
w.event event,
w.p1raw p1,
w.p2raw p2,
w.p3raw p3,
w.SECONDS_IN_WAIT ctime,
s.sql_hash_value sqlhash,
s.prev_hash_value psqlhash,
st.value cpu
from
v$session s,
v$sesstat st,
v$statname sn,
v$session_wait w
where
w.sid = s.sid and
st.sid = s.sid and
st.statistic# = sn.statistic# and
sn.name = 'CPU used when call started' and
w.event != 'SQL*Net message from client'
order by w.sid;
Other Fun Stuff
The next example is output from an SGA
program that follows the LRU of the
Buffer Cache