This document discusses performance measurement and tracing in Oracle databases. It provides requirements for measurement tools, such as relevance, determinism, integrity and quality. It also discusses how to control tracing using ALTER SESSION/SYSTEM commands and avoiding intrusion from tracing. The document explores what the 'c' value in SQL traces represents (user vs. kernel time) and how to determine this through function interposition. Other topics covered include appropriate tracing levels and using interposition to modify trace output.
9. @carymillsap
Relevance
Measured durations must match experienced durations.
Determinism
The data interpretation process must be deterministic, unambiguous, devoid of magic.
Integrity
Numbers must reconcile within a report, across drill-downs, across reports, etc.
Quality
There must be no unit-mixing, no chartjunk, no longjumps, etc.
9
Some requirements for measurement tools
13. @carymillsap
alter session set events '10046 trace name context forever, level 12'
-- Trace this session until you disable.
alter session set events '10046 trace name context off'
13
The old way
alter session set events 'sql_trace wait=true, bind=true, plan_stat=all_executions'
-- Trace this session until you disable.
alter session set events 'sql_trace off'
The new11g way
Better alter session syntax
14. @carymillsap 14
alter system set events 'sql_trace[sql: sql_id=ds9j6z3j9n49k|95hh6uvjgspm2] wait=true, bind=true, plan_stat=adaptive';
-- Trace statements with matching SQL IDs until you disable.
alter system set events 'sql_trace[sql: sql_id=ds9j6z3j9n49k|95hh6uvjgspm2] off';
alter system set events 'sql_trace{process: 9176} wait=true, bind=true, plan_stat=adaptive';
-- Trace the identified process until you disable.
alter system set events 'sql_trace{process: 9176} off';
alter system set events 'sql_trace{process: orapid=75} wait=true, bind=true, plan_stat=adaptive';
-- Trace the identified process until you disable.
alter system set events 'sql_trace{process: orapid=75} off';
alter system set events 'sql_trace{process: pname=smon|p0000|p0003} wait=true, bind=true, plan_stat=adaptive';
-- Trace the named processes until you disable.
alter system set events 'sql_trace{process: pname=smon|p0000|p0003} off';
alter system set events 'sql_trace[sql: sql_id=4cxhkp5ckjs6s]{process:9176} wait=true, bind=true, plan_stat=adaptive';
-- Trace the specified SQL only in the specified process until you disable.
alter system set events 'sql_trace[sql: sql_id=4cxhkp5ckjs6s]{process:9176} off';
More alter system options
22. @carymillsap
Respect the IOPS capacity of your storage
Thumb rule: ≤ 5 simultaneous traces
Make a plan for an immediate emergency trace disable
Test your tracing strategy
Trace at the right level
22
What is “if you do it right”?
24. @carymillsap
If you don’t have time to think about it, then use…
sql_trace wait=true, bind=false, plan_stat=adaptive
Using the wrong level can get you into big trouble.
24
25. @carymillsap
Example: A batch program is too slow. With tracing disabled, the program processes
10,000 rows in 1.222 s. However, with wait=true,bind=true tracing enabled, the
same program takes 29.342 s to process the same 10,000 rows. This is a 24×
performance penalty, which is horrifying. With wait=true,bind=false tracing
enabled, the same program processes its 10,000 rows in 1.211 s, which is within ±1%
of the trace-disabled duration.
Investigation of the trace reveals that the program’s duration is dominated nearly 100%
by a complicated update statement. The statement is parsed only once, which is good,
but each EXEC of this statement updates only one row (this, of course, is the root of the
problem). The statement’s where clause references 100 placeholders
named :b001, :b002, ..., :b100. With bind tracing disabled, we can tell that each
EXEC call consumes 0.000 122 s, but with bind tracing enabled, each EXEC call
consumes 0.002 921 s. For each call, the tracing overhead is 95.8%!
25
27. @carymillsap
bind=true prints 5n + 1 lines per EXEC call.
Lots of placeholders (n) makes 2(5n + 1) large.
Application makes way too many EXEC calls.
27
Problem is a combination of three factors…
28. @carymillsap
Trace with wait=true,bind=false.
Now you know the application makes way too many EXEC calls.
Fix the application (process sets, not rows).
Now the application is faster.
And now you can use wait=true,bind=true.
28
Solution
36. @carymillsap
1. Use strace to find out what function Oracle
calls to calculate c.
2. Use function interposition to replace that
function; make it return what we want.
3. Trace something. See what c is.
36
What is c?
User running? Kernel running? Both?
45. @carymillsap 45
1. Interpose all fd = open(path,…) calls:
if path is *.trc, then set trcfile = fd.
2. Interpose all write(fd,s) calls:
if (fd == trcfile) then...
if s doesn’t end with “n”, then save s;
otherwise, write deferred content and s.
A solution…
46. @carymillsap 46
1. Buffer trace writes (Oracle SR 3-9616334591).
2. Write your own WAIT lines into the trace file that
summarize the cost of all the sql_trace write calls.
3. Intercept unnecessary commit calls.
4. Write In-Memory DB or Exadata Storage stats from
Oracle shared memory to the sql_trace file.
Other things you could do…