SlideShare une entreprise Scribd logo
1  sur  63
Télécharger pour lire hors ligne
@CaryMillsap
Innovative Specifications
for Better Performance
Logging and Monitoring
Cary Millsap
Cintra Software and Services · Method R Corporation
@CaryMillsap
#Kscope18
Walt Disney World Dolphin Resort, Orlando, Florida
9:00a–10:00a Tuesday 12 June 2018
1
2@CaryMillsap
2020
2015
2010
2005
2000
1995
1990
1985
100 45
6
3
hotsos
Method R
TM
Optimal Flexible Architecture
Oracle APS
System Pe ormance Group
Method R Profiler
Method R Tools
Method R Trace
The definitive guide to accurate, high-precision
measurement of user performance experiences,
for Oracle application developers and database
administrators.
Cary V. Millsap
TM
MeTHOD R
TM
The Guide to
MASTERING
ORACLE
TRACE DATA
Second Edition
REVISED
UPDA
TED
NEW PA
G
ES
1 3 2
Method R Workbench
TRASIR
SimDiff
Cary Millsap
@CaryMillsap
The Case for
Homemade Logging
3
1988 BMW 325
4@CaryMillsap
@CaryMillsap
OBDII
5
6@CaryMillsap
A short story.
Hey, the TPS report is slow. It always
used to run in about 10 minutes, but
then it went to 20, and now it’s taking
over an hour.
Any idea why?
🤣 🤣 🤣 What kind of idea would I have?
It’s *your* code, bruh.
7@CaryMillsap
So, you stick some print statements into your code.
You recompile it.
You test it.
You commit it and push it.
You deploy it.
8@CaryMillsap
Still slow.
Here, I’ve pushed a new
executable. Try it now. When it’s
finished, email me the file called
$HOME/tps.log
Ok, check your mail.
Yeah, I know. But the log file will tell
me where it’s spending its time.
Just curious. Why didn’t it do the
thing with the log file to begin with?
●●●
9@CaryMillsap
@CaryMillsap
Homemade logging
What would those printf() statements look like?
function f(stuff) {
printf(LOG, "%s %s %sn", timestamp, "f{", stuff);
for record in (records) {
process(record);
}
printf(LOG, "%s %s %d recordsn", timestamp, "}", count(records));
}
Then you’ll need to parse the log to compute durations.
(Or change the code to print them.)
10
@CaryMillsap
Homemade logging
What would those printf() statements look like?
function f(stuff) {
printf(LOG, "%s %s %sn", timestamp, "f{", stuff);
for record in (records) {
process(record);
}
printf(LOG, "%s %s %d recordsn", timestamp, "}", count(records));
}
Maybe you’ll need more printf calls to cope with skew in iteration durations.
11
@CaryMillsap
1. package com.test;
2.  
3. import org.apache.logging.log4j.Logger;
4. import org.apache.logging.log4j.LogManager;
5.  
6. import java.util.Random;
7.  
8. public class TestService {
9. private Logger logger = LogManager.getLogger(TestService.class.getName());
10.  
11. private String[] messages = new String[] {
12. "Hello, World",
13. "Goodbye Cruel World",
14. "You had me at hello"
15. };
16. private Random rand = new Random(1);
17.  
18. public void setMessages(String[] messages) {
19. logger.traceEntry(new JsonMessage(messages));
20. this.messages = messages;
21. logger.traceExit();
22. }
23.  
24. public String[] getMessages() {
25. logger.traceEntry();
26. return logger.traceExit(messages, new JsonMessage(messages));
27. }
28.  
29. public String retrieveMessage() {
30. logger.entry();
31.  
32. String testMsg = getMessage(getKey());
33.  
34. return logger.exit(testMsg);
35. }
36.  
37. public void exampleException() {
38. logger.entry();
39. try {
40. String msg = messages[messages.length];
41. logger.error("An exception should have been thrown");
42. } catch (Exception ex) {
43. logger.catching(ex);
44. }
45. logger.exit();
46. }
47.  
48. public String getMessage(int key) {
49. logger.entry(key);
50.  
51. String value = messages[key];
52.  
53. return logger.exit(value);
54. }
55.  
56. private int getKey() {
57. logger.entry();
58. int key = rand.nextInt(messages.length);
59. return logger.exit(key);
60. }
61. }
Homemade logging
What would those printf() statements look like?
function f(stuff) {
printf(LOG, "%s %s %sn", timestamp, "f{", stuff);
for record in (records) {
process(record);
}
printf(LOG, "%s %s %d recordsn", timestamp, "}", count(records));
}
Maybe you’ll use Log4j.
12
@CaryMillsap
Homemade logging
What would those printf() statements look like?
function f(stuff) {
printf(LOG, "%s %s %sn", timestamp, "f{", stuff);
for record in (records) {
process(record);
}
printf(LOG, "%s %s %d recordsn", timestamp, "}", count(records));
}
Maybe you’ll create a --debug option to control it.
13
@CaryMillsap
This function: 23.8% debug
function check_for_updates($product, $platform, $version, $debug=0) {
// Find update candidate filenames in distro directory.
$zero_distroversion = "0.0.0.0"; // -INF value for initialization.
$distro_dir = distribution_filename();
if ($dir = opendir($distro_dir)) {
$greatest_distroversion = $zero_distroversion;
if ($debug) echo "<p>Searching files in '$distro_dir':</p>";
if ($debug) echo "<ul>";
while (false !== ($entry = readdir($dir))) { // http://php.net/manual/en/function.readdir.php
if ($entry === "." or $entry === "..") {
continue;
}
if ($debug) echo "<li>";
if ($debug) echo $entry;
if (preg_match("/^$product-([0-9.]+)-$platform./", $entry, $match)) { // Assumption: filename structure.
$distroversion = $match[1];
if ($debug) echo " is a distro match";
if (version_compare($distroversion, $version, ">")) {
if ($debug) echo ", and an update candidate because $distroversion > $version";
if (version_compare($distroversion, $greatest_distroversion, ">")) {
if ($debug) echo ", and the best so far because $distroversion > $greatest_distroversion";
$greatest_distroversion = $distroversion;
$update_filename = $entry;
} else {
if ($debug) echo ", but not the best because $distroversion ≯ $greatest_distroversion";
}
14
@CaryMillsap
Why would I do that?
15
Coz my world is the
opposite of this world.
I have to operate the
software I write.
☞
@CaryMillsap
We find stepping through a program [with a
debugger] less productive than thinking harder
and adding output statements and self-
checking code at critical places. …More
important, debugging statements stay with the
program; debugging sessions are transient.
—Brian Kernighan and Rob Pike
The Practice of Programming
16
@CaryMillsap
Oracle Extended
SQL Trace
17
@CaryMillsap
What you get with sql_trace
Database calls (dbcalls)
System calls (syscalls)
Values bound to placeholders (“bind variables”)
Query plan (row source) operations
18
@CaryMillsap
sql_trace shows control flow
$ vim PSP_ora_4620_00007.trc
19
@CaryMillsap 20
Tools make it easier to read
@CaryMillsap
Innovative
Specifications
21
Edit Email Assign Resolve
Active
Priority
3 – Required
Edit Email Assign Resolve
Opened by Cary Millsap
05/24/2018 (Today) 11:34 AM
Cary Millsap Project: TPS Area: logging Milestone: 1.1.0
Kanban Column
1.1.0.1
@CaryMillsap 22
10001
An operator (e.g., a DBA) must be able to control tracing of selected business
tasks with Oracle’s dbms_monitor PL/SQL package. For example, we should be
able to trace:

- the next OE job

- the next OE BOOK job

- the next job executed by nwells
Operator-controlled tracing of task executions
@CaryMillsap
Trace all OE executionsPL/SQL
dbms_monitor.serv_mod_act_trace_enable(
service_name => 'SYS$USERS',
module_name => 'OE',
action_name => dbms_monitor.all_actions,
waits => true,
binds => false,
plan_stat => 'FIRST_EXECUTION'
);
But this works only if your code sets its module name.
23
@CaryMillsap
Trace all OE BOOK executionsPL/SQL
dbms_monitor.serv_mod_act_trace_enable(
service_name => 'SYS$USERS',
module_name => 'OE',
action_name => 'BOOK',
waits => true,
binds => false,
plan_stat => 'FIRST_EXECUTION'
);
This works only if your code sets its module and action names.
24
@CaryMillsap
Trace all nwells executionsPL/SQL
dbms_monitor.client_id_trace_enable(
client_id => 'nwells',
waits => true,
binds => false,
plan_stat => 'FIRST_EXECUTION'
);
This works only if your code sets its client ID.
25
@CaryMillsap
User session handle attributes
Settable and gettable with OCI, JDBC, etc.
Visible in v$session
service_name

module

action

client_identifier
Values can change during a session
Identify sessions or parts of sessions
26
OE/BOOK
OE/PICK
OE/SHIP
Oracle
session
connect
disconnect
set_module('OE', 'BOOK')
set_module(null, null)
set_module(null, null)
set_module(null, null)
set_module('OE', 'PICK')
set_module('OE', 'SHIP')
time
@CaryMillsap
Marking your codePL/SQL
dbms_session.set_identifier(sys_context('userenv', 'enterprise_identity'));
dbms_application_info.set_module('OE', 'BOOK');
-- Your OE BOOK code
dbms_session.set_identifier(null);
dbms_application_info.set_module(null, null);
27
@CaryMillsap
Marking your codeJDBC 12c
Properties p = new Properties();
p.put("OCSID.MODULE", "OE");
p.put("OCSID.ACTION", "BOOK");
p.put("OCSID.CLIENTID", getUserName());
connection.setClientInfo(p);
/* Your OE BOOK code */
p.put("OCSID.MODULE", "");
p.put("OCSID.ACTION", "");
p.put("OCSID.CLIENTID", "");
connection.setClientInfo(p);
28
@CaryMillsap
Better factoringJDBC 12c
connection.begin_task("OE BOOK");
/* Your OE BOOK code */
connection.end_task();
29
@CaryMillsap
The new codepseudocode
sub begin_task(t) {
(mod, act) = split(/ /, t, 2);
setClientInfo(properties(mod, act, getUserName()));
}
sub end_task() {
setClientInfo(properties("", "", ""));
}
30
Edit Email Assign Resolve
Active
Priority
3 – Required
Edit Email Assign Resolve
Opened by Cary Millsap
05/24/2018 (Today) 11:34 AM
Cary Millsap Project: TPS Area: logging Milestone: 1.1.0
Kanban Column
1.1.0.1
@CaryMillsap 31
10002
Our connection pooling application makes it difficult to isolate individual user
experiences in the trace data. The Method R Workbench trick of identifying
oceans, islands, and rivers with mrskew --thinktime=z is a start, but we want to
perfectly isolate experiences.

We can do this by printing a unique experience ID (a UUID) to the trace file at the
beginning of a task’s execution, and then printing an empty experience ID at the
end. This will give tools like mrskew a group-by handle that maps perfectly to the
user experience.
Write experience ID to the trace file
@CaryMillsap
List of experience durations
$ mrskew *.trc --group='sprintf("%-8s %-36s %s", $client_id, $experience_id, $file)' …
CLIENT-ID EXPERIENCE-ID FILE DURATION % CALLS MEAN MIN MAX
----------------------------------------------------------------- ------------ ------ --------- -------- -------- --------
nwells c6a1c359-5766-4263-9e3e-8e600bb7dba9 gxl_ora_131168.trc 9.447247 0.5% 8 1.180906 0.000000 8.075276
cshaftig 822a94c6-d27a-4804-84fe-5a7fed03ed9f gxl_ora_110636.trc 7.560207 0.4% 9 0.840023 0.000000 7.543424
nwells 733f8c60-2bd3-4fdd-a638-d304f75b1aef gxl_ora_91144.trc 7.525153 0.4% 15 0.501677 0.000000 7.489669
rmorbisun afcab6e4-02e8-47ed-a3f8-ca394ddd17cb gxl_ora_56988.trc 6.342819 0.3% 16 0.396426 0.000000 5.449377
krajita 64e57451-bf65-4022-a927-0cf2567c2fe1 gxl_ora_61704.trc 5.521687 0.3% 7 0.788812 0.000000 5.505351
89,074 others 1,975.121691 98.2% 1,233,058 0.001602 0.000000 4.900948
----------------------------------------------------------------- ------------ ------ --------- -------- -------- --------
TOTAL (89,079) 2,011.518804 100.0% 1,233,113 0.001631 0.000000 8.075276
32
@CaryMillsap
List of experience durations
$ mrskew *.trc --group='sprintf("%-8s %-36s %s", $client_id, $experience_id, $file)' …
CLIENT-ID EXPERIENCE-ID FILE DURATION % CALLS MEAN MIN MAX
----------------------------------------------------------------- ------------ ------ --------- -------- -------- --------
nwells c6a1c359-5766-4263-9e3e-8e600bb7dba9 gxl_ora_131168.trc 9.447247 0.5% 8 1.180906 0.000000 8.075276
cshaftig 822a94c6-d27a-4804-84fe-5a7fed03ed9f gxl_ora_110636.trc 7.560207 0.4% 9 0.840023 0.000000 7.543424
nwells 733f8c60-2bd3-4fdd-a638-d304f75b1aef gxl_ora_91144.trc 7.525153 0.4% 15 0.501677 0.000000 7.489669
rmorbisun afcab6e4-02e8-47ed-a3f8-ca394ddd17cb gxl_ora_56988.trc 6.342819 0.3% 16 0.396426 0.000000 5.449377
krajita 64e57451-bf65-4022-a927-0cf2567c2fe1 gxl_ora_61704.trc 5.521687 0.3% 7 0.788812 0.000000 5.505351
89,074 others 1,975.121691 98.2% 1,233,058 0.001602 0.000000 4.900948
----------------------------------------------------------------- ------------ ------ --------- -------- -------- --------
TOTAL (89,079) 2,011.518804 100.0% 1,233,113 0.001631 0.000000 8.075276
33
@CaryMillsap
Drill into an experience
$ mrskew gxl_ora_131168.trc --where='$experience_id eq "c6a1c359-5766-4263-9e3e-8e600bb7dba9"'
CALL-NAME DURATION % CALLS MEAN MIN MAX
----------------------------- -------- ------ ----- -------- -------- --------
enq: TX - row lock contention 8.075276 85.5% 1 8.075276 8.075276 8.075276
log file sync 1.355818 14.4% 1 1.355818 1.355818 1.355818
EXEC 0.015600 0.2% 1 0.015600 0.015600 0.015600
SQL*Net message from client 0.000548 0.0% 1 0.000548 0.000548 0.000548
SQL*Net message to client 0.000005 0.0% 2 0.000002 0.000002 0.000003
2 others 0.000000 0.0% 2 0.000000 0.000000 0.000000
----------------------------- -------- ------ ----- -------- -------- --------
TOTAL (7) 9.447247 100.0% 8 1.180906 0.000000 8.075276
34
@CaryMillsap
Oceans, Islands, and Rivers
35
@CaryMillsap 36
WAIT … nam='SQL*Net message from client' ela= 1202689 …
stuff for Experience A
WAIT … nam='SQL*Net message from client' ela= 4260917 …
stuff for Experience B
WAIT … nam='SQL*Net message from client' ela= 5213365 …
stuff for Experience C
WAIT … nam='SQL*Net message from client' ela= 2044420 …
37@CaryMillsap
Such trace files have
islands of activity
in an ocean of idleness.
38@CaryMillsap
But…
39@CaryMillsap
An island can have rivers.
40@CaryMillsap
So can a trace file.
41@CaryMillsap
WAIT … nam='SQL*Net message from client' ela= 1202689 …
*** CLIENT ID:(nwells)
*** EXPERIENCE ID:(c6a1c359-5766-4263-9e3e-8e600bb7dba9)
stuff for Experience A
WAIT … nam='SQL*Net message from client' ela= 342
more stuff for Experience A
WAIT … nam='SQL*Net message from client' ela= 1492
yet more stuff for Experience A
…
WAIT … nam='SQL*Net message from client' ela= 4260917 …
*** CLIENT ID:(cshaftig)
*** EXPERIENCE ID:(822a94c6-d27a-4804-84fe-5a7fed03ed9f)
stuff for Experience B
WAIT … nam='SQL*Net message from client' ela= 2928
more stuff for Experience B
…
WAIT … nam='SQL*Net message from client' ela= 5213365 …
*** CLIENT ID:(nwells)
*** EXPERIENCE ID:(733f8c60-2bd3-4fdd-a638-d304f75b1aef)
stuff for Experience C
WAIT … nam='SQL*Net message from client' ela= 855
more stuff for Experience C
…
WAIT … nam='SQL*Net message from client' ela= 2044420 …
42@CaryMillsap
WAIT … nam='SQL*Net message from client' ela= 1202689 …
*** CLIENT ID:(nwells)
*** EXPERIENCE ID:(c6a1c359-5766-4263-9e3e-8e600bb7dba9)
stuff for Experience A
WAIT … nam='SQL*Net message from client' ela= 342
more stuff for Experience A
WAIT … nam='SQL*Net message from client' ela= 1492
yet more stuff for Experience A
…
WAIT … nam='SQL*Net message from client' ela= 4260917 …
*** CLIENT ID:(cshaftig)
*** EXPERIENCE ID:(822a94c6-d27a-4804-84fe-5a7fed03ed9f)
stuff for Experience B
WAIT … nam='SQL*Net message from client' ela= 2928
more stuff for Experience B
…
WAIT … nam='SQL*Net message from client' ela= 5213365 …
*** CLIENT ID:(nwells)
*** EXPERIENCE ID:(733f8c60-2bd3-4fdd-a638-d304f75b1aef)
stuff for Experience C
WAIT … nam='SQL*Net message from client' ela= 855
more stuff for Experience C
…
WAIT … nam='SQL*Net message from client' ela= 2044420 …
@CaryMillsap
The new codepseudocode
sub begin_task(t) {
(mod, act) = split(/ /, t, 2);
setClientInfo(properties(mod, act, getUserName());
xid = uuid();
push(xid_stack, (xid, t));
dbms_log.ksdwrt(1, sprintf("EXPERIENCE ID:(%s)", xid));
}
sub end_task() {
setClientInfo(properties("", "", ""));
pop(xid_stack);
dbms_log.ksdwrt(1, "EXPERIENCE ID:()");
}
43
Edit Email Assign Resolve
Active
Priority
3 – Required
Edit Email Assign Resolve
Opened by Cary Millsap
05/24/2018 (Today) 11:34 AM
Cary Millsap Project: TPS Area: logging Milestone: 1.1.0
Kanban Column
1.1.0.1
@CaryMillsap 44
10003
We’ve had intermittent performance problems with OE BOOK. We don’t want to
trace OE BOOK every time it runs, but it would be nice if we could trace it for
some percentage of executions. We want to control that percentage from a table
that we can modify through a simple APEX application.
Trace only some executions of a given program
@CaryMillsap
Trace every execution

pseudocode
dbms_session.session_trace_enable(true, false, 'FIRST_EXECUTION');
-- Your OE BOOK code
dbms_session.session_trace_disable();
45
@CaryMillsap
Trace only some executions

pseudocode
if (should_trace('OE BOOK') {
dbms_session.session_trace_enable(true, false, 'FIRST_EXECUTION');
}
-- Your OE BOOK code
dbms_session.session_trace_disable();
46
@CaryMillsap
Trace only some executions

pseudocode
if (should_trace('OE BOOK')) {
dbms_session.session_trace_enable(true, false, 'FIRST_EXECUTION');
}
-- Your OE BOOK code
dbms_session.session_trace_disable();
sub should_trace(t) {

select proportion from trace_control where task = :t;
return (dbms_random.value(0,1) < proportion);

}
47
task_name proportion
OE BOOK 0.05
OE PICK 0.02
… …
trace_control
@CaryMillsap
Trace only some executions

pseudocode
sub should_trace(t) {

select proportion from trace_control where task = :t;
return (dbms_random.value(0,1) < proportion);

}
task_name proportion
OE BOOK 0.05
OE PICK 0.02
… …
trace_control
48
p = 0.95 should_trace('OE BOOK') == false
p = 0.05 should_trace('OE BOOK') == true
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
@CaryMillsap
The new code

pseudocode
sub begin_task(t) {
(mod, act) = split(/ /, t, 2);
setClientInfo(properties(mod, act, getUserName());
xid = uuid();
push(xid_stack, (xid, t));
dbms_log.ksdwrt(1, sprintf("EXPERIENCE ID:(%s)", xid));
if (should_trace(t)) {
session_trace_enable(true, true, 'first_execution');
}
}
sub end_task() {
setClientInfo(properties("", "", ""));
pop(xid_stack);
dbms_log.ksdwrt(1, "EXPERIENCE ID:()");
session_trace_disable();
}
49
Edit Email Assign Resolve
Active
Priority
3 – Required
Edit Email Assign Resolve
Opened by Cary Millsap
05/24/2018 (Today) 11:34 AM
Cary Millsap Project: TPS Area: logging Milestone: 1.1.0
Kanban Column
1.1.0.1
@CaryMillsap 50
10003
We don't always want to use bind=true and plan_stat='first_execution'. We
want to control those from trace_control as well.
Manage tracing levels from trace_control
@CaryMillsap
Measurement intrusion
Enough detail, but not too much.
Oracle uses events and levels. $ORACLE_HOME/rdbms/mesg/oraus.msg
• 10046 “enable SQL statement timing” levels 1, 4, 8, 16, 32, 64, … (sql_trace)
• 10053 “CBO Enable optimizer trace”
• 10200 “consistent read buffer status”
51
@CaryMillsap
How we avoid 10046 MIE
1. sql_trace wait=true, bind=false, plan_stat=first_execution
2. If application has lightweight row-by-row executions, we fix it.
3. sql_trace wait=true, bind=true, plan_stat=all_executions
52
@CaryMillsap
The new codepseudocode
sub begin_task(t) {
(mod, act) = split(/ /, t, 2);
setClientInfo(properties(mod, act, getUserName());
xid = uuid();
push(xid_stack, (xid, t));
dbms_log.ksdwrt(1, sprintf("EXPERIENCE ID:(%s)", xid));
if ((bind, stat) = should_trace(t)) {
session_trace_enable(true, bind, stat);
}
}
sub end_task() {
setClientInfo(properties("", "", ""));
pop(xid_stack);
dbms_log.ksdwrt(1, "EXPERIENCE ID:()");
session_trace_disable();
}
53
task_name proportion bind stat
OE BOOK 0.05 FALSE FIRST_EXECUTION
OE PICK 0.02 TRUE ALL_EXECUTIONS
… … … …
trace_control
Edit Email Assign Resolve
Active
Priority
3 – Required
Edit Email Assign Resolve
Opened by Cary Millsap
05/24/2018 (Today) 11:34 AM
Cary Millsap Project: TPS Area: logging Milestone: 1.1.0
Kanban Column
1.1.0.1
@CaryMillsap 54
10004
When a user has a performance problem with the application, she should be able
to click Help › Debug › Trace, which will inspire a properly time-scoped trace of
the next business task she executes.
User controls tracing with Help › Debug › Trace
@CaryMillsap
Help › Debug › Trace
How it usually works:
1. User clicks Help › Debug › Trace.
2. This triggers immediate session trace enable.
3. User eventually executes her task.
4. Clicks Help › Debug › Stop Trace.
Not what you want.
55
@CaryMillsap
It’s not the trace file you want
You need:
trace enable == task begin
trace disable == task end
Otherwise, you get either too much data,

or not enough.
56
trace disable
task end
task begin
trace enable
trace file
you got
trace file
you want
time
@CaryMillsap
Help › Debug › Trace
A user turns on tracing.
vs.
A user expresses the intention to trace the next task execution.
Help › Debug › Trace should set a boolean.
begin_task queries the boolean.
57
@CaryMillsap
The new codepseudocode
sub begin_task(t) {
(mod, act) = split(/ /, t, 2);
setClientInfo(properties(mod, act, getUserName());
xid = uuid();
push(xid_stack, (xid, t));
dbms_log.ksdwrt(1, sprintf("EXPERIENCE ID:(%s)", xid));
if (isTraceIntended() or (bind, stat) = should_trace(t)) {
session_trace_enable(true, bind, stat);
}
}
sub end_task() {
setClientInfo(properties("", "", ""));
pop(xid_stack);
dbms_log.ksdwrt(1, "EXPERIENCE ID:()");
session_trace_disable();
}
58
@CaryMillsap
Wrap-up
59
@CaryMillsap
More specs (discussion)
• Trace the first OE BOOK execution every hour.
• Trace p% of Larry’s executions, but q% of Nancy’s.
• Trace p% of executions whose durations have one of the top ten variance-to-
mean ratios (VMR) in your application.
• Trace only if the job is less than p% complete after running for m minutes.
Could you do these even if you don’t have source code access? How?
60
@CaryMillsap
Hundreds of specs you could meet
Trace when you need.
Persist every response time.
Predict response time problems.
Track pathway through the application.
Write harvesters, uploaders, profilers for the data.
Log to shared memory segments for ultra-high throughput.
You can build anything you want; application self-measurement is no big deal.
61
@CaryMillsap
For more information…
62
The definitive guide to accurate, high-precision
measurement of user performance experiences,
for Oracle application developers and database
administrators.
Cary V. Millsap
TM
MeTHOD R
TM
The Guide to
MASTERING
ORACLE
TRACE DATA
Second Edition
REVISED
UPDA
TED
NEW PA
G
ES
1 3 2
Available at
@CaryMillsap 63
Method R
TM
www.cintra.com method-r.com

Contenu connexe

Tendances

Introduction to PHP 5.3
Introduction to PHP 5.3Introduction to PHP 5.3
Introduction to PHP 5.3
guestcc91d4
 
Jdk(java) 7 - 6 기타기능
Jdk(java) 7 - 6 기타기능Jdk(java) 7 - 6 기타기능
Jdk(java) 7 - 6 기타기능
knight1128
 
Performance measurement and tuning
Performance measurement and tuningPerformance measurement and tuning
Performance measurement and tuning
AOE
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
knight1128
 

Tendances (19)

The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42
 
The Ring programming language version 1.7 book - Part 12 of 196
The Ring programming language version 1.7 book - Part 12 of 196The Ring programming language version 1.7 book - Part 12 of 196
The Ring programming language version 1.7 book - Part 12 of 196
 
Buenos Aires Drools Expert Presentation
Buenos Aires Drools Expert PresentationBuenos Aires Drools Expert Presentation
Buenos Aires Drools Expert Presentation
 
Introduction to PHP 5.3
Introduction to PHP 5.3Introduction to PHP 5.3
Introduction to PHP 5.3
 
Jdk(java) 7 - 6 기타기능
Jdk(java) 7 - 6 기타기능Jdk(java) 7 - 6 기타기능
Jdk(java) 7 - 6 기타기능
 
Source Code for Dpilot
Source Code for Dpilot Source Code for Dpilot
Source Code for Dpilot
 
Dpilot Source Code With ScreenShots
Dpilot Source Code With ScreenShots Dpilot Source Code With ScreenShots
Dpilot Source Code With ScreenShots
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 
Performance measurement and tuning
Performance measurement and tuningPerformance measurement and tuning
Performance measurement and tuning
 
Java设置环境变量
Java设置环境变量Java设置环境变量
Java设置环境变量
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
AJUG April 2011 Cascading example
AJUG April 2011 Cascading exampleAJUG April 2011 Cascading example
AJUG April 2011 Cascading example
 
Jersey Guice AOP
Jersey Guice AOPJersey Guice AOP
Jersey Guice AOP
 
The Ring programming language version 1.6 book - Part 11 of 189
The Ring programming language version 1.6 book - Part 11 of 189The Ring programming language version 1.6 book - Part 11 of 189
The Ring programming language version 1.6 book - Part 11 of 189
 
Api Design
Api DesignApi Design
Api Design
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)
 
Creating Lazy stream in CSharp
Creating Lazy stream in CSharpCreating Lazy stream in CSharp
Creating Lazy stream in CSharp
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with Thymeleaf
 

Similaire à Innovative Specifications for Better Performance Logging and Monitoring

Fpga 06-data-types-system-tasks-compiler-directives
Fpga 06-data-types-system-tasks-compiler-directivesFpga 06-data-types-system-tasks-compiler-directives
Fpga 06-data-types-system-tasks-compiler-directives
Malik Tauqir Hasan
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
Wesley Beary
 

Similaire à Innovative Specifications for Better Performance Logging and Monitoring (20)

Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo Web
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Fpga 06-data-types-system-tasks-compiler-directives
Fpga 06-data-types-system-tasks-compiler-directivesFpga 06-data-types-system-tasks-compiler-directives
Fpga 06-data-types-system-tasks-compiler-directives
 
Fatc
FatcFatc
Fatc
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloud
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Is writing performant code too expensive?
Is writing performant code too expensive? Is writing performant code too expensive?
Is writing performant code too expensive?
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
DataMapper
DataMapperDataMapper
DataMapper
 

Plus de Cary Millsap

Plus de Cary Millsap (11)

“Performance” - Dallas Oracle Users Group 2019-01-29 presentation
“Performance” - Dallas Oracle Users Group 2019-01-29 presentation“Performance” - Dallas Oracle Users Group 2019-01-29 presentation
“Performance” - Dallas Oracle Users Group 2019-01-29 presentation
 
Performance
PerformancePerformance
Performance
 
The Most Important Things You Should Know about Oracle®
The Most Important Things You Should Know about Oracle®The Most Important Things You Should Know about Oracle®
The Most Important Things You Should Know about Oracle®
 
How to find and fix your Oracle-based application performance problem
How to find and fix your Oracle-based application performance problemHow to find and fix your Oracle-based application performance problem
How to find and fix your Oracle-based application performance problem
 
How to find and fix your Oracle-based application performance problem
How to find and fix your Oracle-based application performance problemHow to find and fix your Oracle-based application performance problem
How to find and fix your Oracle-based application performance problem
 
Oracle trace data collection errors: the story about oceans, islands, and rivers
Oracle trace data collection errors: the story about oceans, islands, and riversOracle trace data collection errors: the story about oceans, islands, and rivers
Oracle trace data collection errors: the story about oceans, islands, and rivers
 
How to find and fix your Oracle application performance problem
How to find and fix your Oracle application performance problemHow to find and fix your Oracle application performance problem
How to find and fix your Oracle application performance problem
 
Most important "trick" of performance instrumentation
Most important "trick" of performance instrumentationMost important "trick" of performance instrumentation
Most important "trick" of performance instrumentation
 
My Case for Agile
My Case for AgileMy Case for Agile
My Case for Agile
 
Diagnosability versus The Cloud, Redwood Shores 2011-08-30
Diagnosability versus The Cloud, Redwood Shores 2011-08-30Diagnosability versus The Cloud, Redwood Shores 2011-08-30
Diagnosability versus The Cloud, Redwood Shores 2011-08-30
 
Diagnosability versus The Cloud, Toronto 2011-04-21
Diagnosability versus The Cloud, Toronto 2011-04-21Diagnosability versus The Cloud, Toronto 2011-04-21
Diagnosability versus The Cloud, Toronto 2011-04-21
 

Dernier

Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
amitlee9823
 
Delhi 99530 vip 56974 Genuine Escort Service Call Girls in Kishangarh
Delhi 99530 vip 56974 Genuine Escort Service Call Girls in  KishangarhDelhi 99530 vip 56974 Genuine Escort Service Call Girls in  Kishangarh
Delhi 99530 vip 56974 Genuine Escort Service Call Girls in Kishangarh
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip CallDelhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
shivangimorya083
 
CHEAP Call Girls in Saket (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Saket (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Saket (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Saket (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
Al Barsha Escorts $#$ O565212860 $#$ Escort Service In Al Barsha
Al Barsha Escorts $#$ O565212860 $#$ Escort Service In Al BarshaAl Barsha Escorts $#$ O565212860 $#$ Escort Service In Al Barsha
Al Barsha Escorts $#$ O565212860 $#$ Escort Service In Al Barsha
AroojKhan71
 

Dernier (20)

VidaXL dropshipping via API with DroFx.pptx
VidaXL dropshipping via API with DroFx.pptxVidaXL dropshipping via API with DroFx.pptx
VidaXL dropshipping via API with DroFx.pptx
 
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
 
Delhi 99530 vip 56974 Genuine Escort Service Call Girls in Kishangarh
Delhi 99530 vip 56974 Genuine Escort Service Call Girls in  KishangarhDelhi 99530 vip 56974 Genuine Escort Service Call Girls in  Kishangarh
Delhi 99530 vip 56974 Genuine Escort Service Call Girls in Kishangarh
 
Data-Analysis for Chicago Crime Data 2023
Data-Analysis for Chicago Crime Data  2023Data-Analysis for Chicago Crime Data  2023
Data-Analysis for Chicago Crime Data 2023
 
Mature dropshipping via API with DroFx.pptx
Mature dropshipping via API with DroFx.pptxMature dropshipping via API with DroFx.pptx
Mature dropshipping via API with DroFx.pptx
 
Best VIP Call Girls Noida Sector 22 Call Me: 8448380779
Best VIP Call Girls Noida Sector 22 Call Me: 8448380779Best VIP Call Girls Noida Sector 22 Call Me: 8448380779
Best VIP Call Girls Noida Sector 22 Call Me: 8448380779
 
Call Girls in Sarai Kale Khan Delhi 💯 Call Us 🔝9205541914 🔝( Delhi) Escorts S...
Call Girls in Sarai Kale Khan Delhi 💯 Call Us 🔝9205541914 🔝( Delhi) Escorts S...Call Girls in Sarai Kale Khan Delhi 💯 Call Us 🔝9205541914 🔝( Delhi) Escorts S...
Call Girls in Sarai Kale Khan Delhi 💯 Call Us 🔝9205541914 🔝( Delhi) Escorts S...
 
(NEHA) Call Girls Katra Call Now 8617697112 Katra Escorts 24x7
(NEHA) Call Girls Katra Call Now 8617697112 Katra Escorts 24x7(NEHA) Call Girls Katra Call Now 8617697112 Katra Escorts 24x7
(NEHA) Call Girls Katra Call Now 8617697112 Katra Escorts 24x7
 
Week-01-2.ppt BBB human Computer interaction
Week-01-2.ppt BBB human Computer interactionWeek-01-2.ppt BBB human Computer interaction
Week-01-2.ppt BBB human Computer interaction
 
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip CallDelhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
 
Accredited-Transport-Cooperatives-Jan-2021-Web.pdf
Accredited-Transport-Cooperatives-Jan-2021-Web.pdfAccredited-Transport-Cooperatives-Jan-2021-Web.pdf
Accredited-Transport-Cooperatives-Jan-2021-Web.pdf
 
Cheap Rate Call girls Sarita Vihar Delhi 9205541914 shot 1500 night
Cheap Rate Call girls Sarita Vihar Delhi 9205541914 shot 1500 nightCheap Rate Call girls Sarita Vihar Delhi 9205541914 shot 1500 night
Cheap Rate Call girls Sarita Vihar Delhi 9205541914 shot 1500 night
 
CHEAP Call Girls in Saket (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Saket (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Saket (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Saket (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Invezz.com - Grow your wealth with trading signals
Invezz.com - Grow your wealth with trading signalsInvezz.com - Grow your wealth with trading signals
Invezz.com - Grow your wealth with trading signals
 
Market Analysis in the 5 Largest Economic Countries in Southeast Asia.pdf
Market Analysis in the 5 Largest Economic Countries in Southeast Asia.pdfMarket Analysis in the 5 Largest Economic Countries in Southeast Asia.pdf
Market Analysis in the 5 Largest Economic Countries in Southeast Asia.pdf
 
Digital Advertising Lecture for Advanced Digital & Social Media Strategy at U...
Digital Advertising Lecture for Advanced Digital & Social Media Strategy at U...Digital Advertising Lecture for Advanced Digital & Social Media Strategy at U...
Digital Advertising Lecture for Advanced Digital & Social Media Strategy at U...
 
Al Barsha Escorts $#$ O565212860 $#$ Escort Service In Al Barsha
Al Barsha Escorts $#$ O565212860 $#$ Escort Service In Al BarshaAl Barsha Escorts $#$ O565212860 $#$ Escort Service In Al Barsha
Al Barsha Escorts $#$ O565212860 $#$ Escort Service In Al Barsha
 
Ravak dropshipping via API with DroFx.pptx
Ravak dropshipping via API with DroFx.pptxRavak dropshipping via API with DroFx.pptx
Ravak dropshipping via API with DroFx.pptx
 
CebaBaby dropshipping via API with DroFX.pptx
CebaBaby dropshipping via API with DroFX.pptxCebaBaby dropshipping via API with DroFX.pptx
CebaBaby dropshipping via API with DroFX.pptx
 
Best VIP Call Girls Noida Sector 39 Call Me: 8448380779
Best VIP Call Girls Noida Sector 39 Call Me: 8448380779Best VIP Call Girls Noida Sector 39 Call Me: 8448380779
Best VIP Call Girls Noida Sector 39 Call Me: 8448380779
 

Innovative Specifications for Better Performance Logging and Monitoring

  • 1. @CaryMillsap Innovative Specifications for Better Performance Logging and Monitoring Cary Millsap Cintra Software and Services · Method R Corporation @CaryMillsap #Kscope18 Walt Disney World Dolphin Resort, Orlando, Florida 9:00a–10:00a Tuesday 12 June 2018 1
  • 2. 2@CaryMillsap 2020 2015 2010 2005 2000 1995 1990 1985 100 45 6 3 hotsos Method R TM Optimal Flexible Architecture Oracle APS System Pe ormance Group Method R Profiler Method R Tools Method R Trace The definitive guide to accurate, high-precision measurement of user performance experiences, for Oracle application developers and database administrators. Cary V. Millsap TM MeTHOD R TM The Guide to MASTERING ORACLE TRACE DATA Second Edition REVISED UPDA TED NEW PA G ES 1 3 2 Method R Workbench TRASIR SimDiff Cary Millsap
  • 7. Hey, the TPS report is slow. It always used to run in about 10 minutes, but then it went to 20, and now it’s taking over an hour. Any idea why? 🤣 🤣 🤣 What kind of idea would I have? It’s *your* code, bruh. 7@CaryMillsap
  • 8. So, you stick some print statements into your code. You recompile it. You test it. You commit it and push it. You deploy it. 8@CaryMillsap
  • 9. Still slow. Here, I’ve pushed a new executable. Try it now. When it’s finished, email me the file called $HOME/tps.log Ok, check your mail. Yeah, I know. But the log file will tell me where it’s spending its time. Just curious. Why didn’t it do the thing with the log file to begin with? ●●● 9@CaryMillsap
  • 10. @CaryMillsap Homemade logging What would those printf() statements look like? function f(stuff) { printf(LOG, "%s %s %sn", timestamp, "f{", stuff); for record in (records) { process(record); } printf(LOG, "%s %s %d recordsn", timestamp, "}", count(records)); } Then you’ll need to parse the log to compute durations. (Or change the code to print them.) 10
  • 11. @CaryMillsap Homemade logging What would those printf() statements look like? function f(stuff) { printf(LOG, "%s %s %sn", timestamp, "f{", stuff); for record in (records) { process(record); } printf(LOG, "%s %s %d recordsn", timestamp, "}", count(records)); } Maybe you’ll need more printf calls to cope with skew in iteration durations. 11
  • 12. @CaryMillsap 1. package com.test; 2.   3. import org.apache.logging.log4j.Logger; 4. import org.apache.logging.log4j.LogManager; 5.   6. import java.util.Random; 7.   8. public class TestService { 9. private Logger logger = LogManager.getLogger(TestService.class.getName()); 10.   11. private String[] messages = new String[] { 12. "Hello, World", 13. "Goodbye Cruel World", 14. "You had me at hello" 15. }; 16. private Random rand = new Random(1); 17.   18. public void setMessages(String[] messages) { 19. logger.traceEntry(new JsonMessage(messages)); 20. this.messages = messages; 21. logger.traceExit(); 22. } 23.   24. public String[] getMessages() { 25. logger.traceEntry(); 26. return logger.traceExit(messages, new JsonMessage(messages)); 27. } 28.   29. public String retrieveMessage() { 30. logger.entry(); 31.   32. String testMsg = getMessage(getKey()); 33.   34. return logger.exit(testMsg); 35. } 36.   37. public void exampleException() { 38. logger.entry(); 39. try { 40. String msg = messages[messages.length]; 41. logger.error("An exception should have been thrown"); 42. } catch (Exception ex) { 43. logger.catching(ex); 44. } 45. logger.exit(); 46. } 47.   48. public String getMessage(int key) { 49. logger.entry(key); 50.   51. String value = messages[key]; 52.   53. return logger.exit(value); 54. } 55.   56. private int getKey() { 57. logger.entry(); 58. int key = rand.nextInt(messages.length); 59. return logger.exit(key); 60. } 61. } Homemade logging What would those printf() statements look like? function f(stuff) { printf(LOG, "%s %s %sn", timestamp, "f{", stuff); for record in (records) { process(record); } printf(LOG, "%s %s %d recordsn", timestamp, "}", count(records)); } Maybe you’ll use Log4j. 12
  • 13. @CaryMillsap Homemade logging What would those printf() statements look like? function f(stuff) { printf(LOG, "%s %s %sn", timestamp, "f{", stuff); for record in (records) { process(record); } printf(LOG, "%s %s %d recordsn", timestamp, "}", count(records)); } Maybe you’ll create a --debug option to control it. 13
  • 14. @CaryMillsap This function: 23.8% debug function check_for_updates($product, $platform, $version, $debug=0) { // Find update candidate filenames in distro directory. $zero_distroversion = "0.0.0.0"; // -INF value for initialization. $distro_dir = distribution_filename(); if ($dir = opendir($distro_dir)) { $greatest_distroversion = $zero_distroversion; if ($debug) echo "<p>Searching files in '$distro_dir':</p>"; if ($debug) echo "<ul>"; while (false !== ($entry = readdir($dir))) { // http://php.net/manual/en/function.readdir.php if ($entry === "." or $entry === "..") { continue; } if ($debug) echo "<li>"; if ($debug) echo $entry; if (preg_match("/^$product-([0-9.]+)-$platform./", $entry, $match)) { // Assumption: filename structure. $distroversion = $match[1]; if ($debug) echo " is a distro match"; if (version_compare($distroversion, $version, ">")) { if ($debug) echo ", and an update candidate because $distroversion > $version"; if (version_compare($distroversion, $greatest_distroversion, ">")) { if ($debug) echo ", and the best so far because $distroversion > $greatest_distroversion"; $greatest_distroversion = $distroversion; $update_filename = $entry; } else { if ($debug) echo ", but not the best because $distroversion ≯ $greatest_distroversion"; } 14
  • 15. @CaryMillsap Why would I do that? 15 Coz my world is the opposite of this world. I have to operate the software I write. ☞
  • 16. @CaryMillsap We find stepping through a program [with a debugger] less productive than thinking harder and adding output statements and self- checking code at critical places. …More important, debugging statements stay with the program; debugging sessions are transient. —Brian Kernighan and Rob Pike The Practice of Programming 16
  • 18. @CaryMillsap What you get with sql_trace Database calls (dbcalls) System calls (syscalls) Values bound to placeholders (“bind variables”) Query plan (row source) operations 18
  • 19. @CaryMillsap sql_trace shows control flow $ vim PSP_ora_4620_00007.trc 19
  • 20. @CaryMillsap 20 Tools make it easier to read
  • 22. Edit Email Assign Resolve Active Priority 3 – Required Edit Email Assign Resolve Opened by Cary Millsap 05/24/2018 (Today) 11:34 AM Cary Millsap Project: TPS Area: logging Milestone: 1.1.0 Kanban Column 1.1.0.1 @CaryMillsap 22 10001 An operator (e.g., a DBA) must be able to control tracing of selected business tasks with Oracle’s dbms_monitor PL/SQL package. For example, we should be able to trace: - the next OE job - the next OE BOOK job - the next job executed by nwells Operator-controlled tracing of task executions
  • 23. @CaryMillsap Trace all OE executionsPL/SQL dbms_monitor.serv_mod_act_trace_enable( service_name => 'SYS$USERS', module_name => 'OE', action_name => dbms_monitor.all_actions, waits => true, binds => false, plan_stat => 'FIRST_EXECUTION' ); But this works only if your code sets its module name. 23
  • 24. @CaryMillsap Trace all OE BOOK executionsPL/SQL dbms_monitor.serv_mod_act_trace_enable( service_name => 'SYS$USERS', module_name => 'OE', action_name => 'BOOK', waits => true, binds => false, plan_stat => 'FIRST_EXECUTION' ); This works only if your code sets its module and action names. 24
  • 25. @CaryMillsap Trace all nwells executionsPL/SQL dbms_monitor.client_id_trace_enable( client_id => 'nwells', waits => true, binds => false, plan_stat => 'FIRST_EXECUTION' ); This works only if your code sets its client ID. 25
  • 26. @CaryMillsap User session handle attributes Settable and gettable with OCI, JDBC, etc. Visible in v$session service_name
 module
 action
 client_identifier Values can change during a session Identify sessions or parts of sessions 26 OE/BOOK OE/PICK OE/SHIP Oracle session connect disconnect set_module('OE', 'BOOK') set_module(null, null) set_module(null, null) set_module(null, null) set_module('OE', 'PICK') set_module('OE', 'SHIP') time
  • 27. @CaryMillsap Marking your codePL/SQL dbms_session.set_identifier(sys_context('userenv', 'enterprise_identity')); dbms_application_info.set_module('OE', 'BOOK'); -- Your OE BOOK code dbms_session.set_identifier(null); dbms_application_info.set_module(null, null); 27
  • 28. @CaryMillsap Marking your codeJDBC 12c Properties p = new Properties(); p.put("OCSID.MODULE", "OE"); p.put("OCSID.ACTION", "BOOK"); p.put("OCSID.CLIENTID", getUserName()); connection.setClientInfo(p); /* Your OE BOOK code */ p.put("OCSID.MODULE", ""); p.put("OCSID.ACTION", ""); p.put("OCSID.CLIENTID", ""); connection.setClientInfo(p); 28
  • 29. @CaryMillsap Better factoringJDBC 12c connection.begin_task("OE BOOK"); /* Your OE BOOK code */ connection.end_task(); 29
  • 30. @CaryMillsap The new codepseudocode sub begin_task(t) { (mod, act) = split(/ /, t, 2); setClientInfo(properties(mod, act, getUserName())); } sub end_task() { setClientInfo(properties("", "", "")); } 30
  • 31. Edit Email Assign Resolve Active Priority 3 – Required Edit Email Assign Resolve Opened by Cary Millsap 05/24/2018 (Today) 11:34 AM Cary Millsap Project: TPS Area: logging Milestone: 1.1.0 Kanban Column 1.1.0.1 @CaryMillsap 31 10002 Our connection pooling application makes it difficult to isolate individual user experiences in the trace data. The Method R Workbench trick of identifying oceans, islands, and rivers with mrskew --thinktime=z is a start, but we want to perfectly isolate experiences. We can do this by printing a unique experience ID (a UUID) to the trace file at the beginning of a task’s execution, and then printing an empty experience ID at the end. This will give tools like mrskew a group-by handle that maps perfectly to the user experience. Write experience ID to the trace file
  • 32. @CaryMillsap List of experience durations $ mrskew *.trc --group='sprintf("%-8s %-36s %s", $client_id, $experience_id, $file)' … CLIENT-ID EXPERIENCE-ID FILE DURATION % CALLS MEAN MIN MAX ----------------------------------------------------------------- ------------ ------ --------- -------- -------- -------- nwells c6a1c359-5766-4263-9e3e-8e600bb7dba9 gxl_ora_131168.trc 9.447247 0.5% 8 1.180906 0.000000 8.075276 cshaftig 822a94c6-d27a-4804-84fe-5a7fed03ed9f gxl_ora_110636.trc 7.560207 0.4% 9 0.840023 0.000000 7.543424 nwells 733f8c60-2bd3-4fdd-a638-d304f75b1aef gxl_ora_91144.trc 7.525153 0.4% 15 0.501677 0.000000 7.489669 rmorbisun afcab6e4-02e8-47ed-a3f8-ca394ddd17cb gxl_ora_56988.trc 6.342819 0.3% 16 0.396426 0.000000 5.449377 krajita 64e57451-bf65-4022-a927-0cf2567c2fe1 gxl_ora_61704.trc 5.521687 0.3% 7 0.788812 0.000000 5.505351 89,074 others 1,975.121691 98.2% 1,233,058 0.001602 0.000000 4.900948 ----------------------------------------------------------------- ------------ ------ --------- -------- -------- -------- TOTAL (89,079) 2,011.518804 100.0% 1,233,113 0.001631 0.000000 8.075276 32
  • 33. @CaryMillsap List of experience durations $ mrskew *.trc --group='sprintf("%-8s %-36s %s", $client_id, $experience_id, $file)' … CLIENT-ID EXPERIENCE-ID FILE DURATION % CALLS MEAN MIN MAX ----------------------------------------------------------------- ------------ ------ --------- -------- -------- -------- nwells c6a1c359-5766-4263-9e3e-8e600bb7dba9 gxl_ora_131168.trc 9.447247 0.5% 8 1.180906 0.000000 8.075276 cshaftig 822a94c6-d27a-4804-84fe-5a7fed03ed9f gxl_ora_110636.trc 7.560207 0.4% 9 0.840023 0.000000 7.543424 nwells 733f8c60-2bd3-4fdd-a638-d304f75b1aef gxl_ora_91144.trc 7.525153 0.4% 15 0.501677 0.000000 7.489669 rmorbisun afcab6e4-02e8-47ed-a3f8-ca394ddd17cb gxl_ora_56988.trc 6.342819 0.3% 16 0.396426 0.000000 5.449377 krajita 64e57451-bf65-4022-a927-0cf2567c2fe1 gxl_ora_61704.trc 5.521687 0.3% 7 0.788812 0.000000 5.505351 89,074 others 1,975.121691 98.2% 1,233,058 0.001602 0.000000 4.900948 ----------------------------------------------------------------- ------------ ------ --------- -------- -------- -------- TOTAL (89,079) 2,011.518804 100.0% 1,233,113 0.001631 0.000000 8.075276 33
  • 34. @CaryMillsap Drill into an experience $ mrskew gxl_ora_131168.trc --where='$experience_id eq "c6a1c359-5766-4263-9e3e-8e600bb7dba9"' CALL-NAME DURATION % CALLS MEAN MIN MAX ----------------------------- -------- ------ ----- -------- -------- -------- enq: TX - row lock contention 8.075276 85.5% 1 8.075276 8.075276 8.075276 log file sync 1.355818 14.4% 1 1.355818 1.355818 1.355818 EXEC 0.015600 0.2% 1 0.015600 0.015600 0.015600 SQL*Net message from client 0.000548 0.0% 1 0.000548 0.000548 0.000548 SQL*Net message to client 0.000005 0.0% 2 0.000002 0.000002 0.000003 2 others 0.000000 0.0% 2 0.000000 0.000000 0.000000 ----------------------------- -------- ------ ----- -------- -------- -------- TOTAL (7) 9.447247 100.0% 8 1.180906 0.000000 8.075276 34
  • 36. @CaryMillsap 36 WAIT … nam='SQL*Net message from client' ela= 1202689 … stuff for Experience A WAIT … nam='SQL*Net message from client' ela= 4260917 … stuff for Experience B WAIT … nam='SQL*Net message from client' ela= 5213365 … stuff for Experience C WAIT … nam='SQL*Net message from client' ela= 2044420 …
  • 37. 37@CaryMillsap Such trace files have islands of activity in an ocean of idleness.
  • 40. 40@CaryMillsap So can a trace file.
  • 41. 41@CaryMillsap WAIT … nam='SQL*Net message from client' ela= 1202689 … *** CLIENT ID:(nwells) *** EXPERIENCE ID:(c6a1c359-5766-4263-9e3e-8e600bb7dba9) stuff for Experience A WAIT … nam='SQL*Net message from client' ela= 342 more stuff for Experience A WAIT … nam='SQL*Net message from client' ela= 1492 yet more stuff for Experience A … WAIT … nam='SQL*Net message from client' ela= 4260917 … *** CLIENT ID:(cshaftig) *** EXPERIENCE ID:(822a94c6-d27a-4804-84fe-5a7fed03ed9f) stuff for Experience B WAIT … nam='SQL*Net message from client' ela= 2928 more stuff for Experience B … WAIT … nam='SQL*Net message from client' ela= 5213365 … *** CLIENT ID:(nwells) *** EXPERIENCE ID:(733f8c60-2bd3-4fdd-a638-d304f75b1aef) stuff for Experience C WAIT … nam='SQL*Net message from client' ela= 855 more stuff for Experience C … WAIT … nam='SQL*Net message from client' ela= 2044420 …
  • 42. 42@CaryMillsap WAIT … nam='SQL*Net message from client' ela= 1202689 … *** CLIENT ID:(nwells) *** EXPERIENCE ID:(c6a1c359-5766-4263-9e3e-8e600bb7dba9) stuff for Experience A WAIT … nam='SQL*Net message from client' ela= 342 more stuff for Experience A WAIT … nam='SQL*Net message from client' ela= 1492 yet more stuff for Experience A … WAIT … nam='SQL*Net message from client' ela= 4260917 … *** CLIENT ID:(cshaftig) *** EXPERIENCE ID:(822a94c6-d27a-4804-84fe-5a7fed03ed9f) stuff for Experience B WAIT … nam='SQL*Net message from client' ela= 2928 more stuff for Experience B … WAIT … nam='SQL*Net message from client' ela= 5213365 … *** CLIENT ID:(nwells) *** EXPERIENCE ID:(733f8c60-2bd3-4fdd-a638-d304f75b1aef) stuff for Experience C WAIT … nam='SQL*Net message from client' ela= 855 more stuff for Experience C … WAIT … nam='SQL*Net message from client' ela= 2044420 …
  • 43. @CaryMillsap The new codepseudocode sub begin_task(t) { (mod, act) = split(/ /, t, 2); setClientInfo(properties(mod, act, getUserName()); xid = uuid(); push(xid_stack, (xid, t)); dbms_log.ksdwrt(1, sprintf("EXPERIENCE ID:(%s)", xid)); } sub end_task() { setClientInfo(properties("", "", "")); pop(xid_stack); dbms_log.ksdwrt(1, "EXPERIENCE ID:()"); } 43
  • 44. Edit Email Assign Resolve Active Priority 3 – Required Edit Email Assign Resolve Opened by Cary Millsap 05/24/2018 (Today) 11:34 AM Cary Millsap Project: TPS Area: logging Milestone: 1.1.0 Kanban Column 1.1.0.1 @CaryMillsap 44 10003 We’ve had intermittent performance problems with OE BOOK. We don’t want to trace OE BOOK every time it runs, but it would be nice if we could trace it for some percentage of executions. We want to control that percentage from a table that we can modify through a simple APEX application. Trace only some executions of a given program
  • 45. @CaryMillsap Trace every execution
 pseudocode dbms_session.session_trace_enable(true, false, 'FIRST_EXECUTION'); -- Your OE BOOK code dbms_session.session_trace_disable(); 45
  • 46. @CaryMillsap Trace only some executions
 pseudocode if (should_trace('OE BOOK') { dbms_session.session_trace_enable(true, false, 'FIRST_EXECUTION'); } -- Your OE BOOK code dbms_session.session_trace_disable(); 46
  • 47. @CaryMillsap Trace only some executions
 pseudocode if (should_trace('OE BOOK')) { dbms_session.session_trace_enable(true, false, 'FIRST_EXECUTION'); } -- Your OE BOOK code dbms_session.session_trace_disable(); sub should_trace(t) {
 select proportion from trace_control where task = :t; return (dbms_random.value(0,1) < proportion);
 } 47 task_name proportion OE BOOK 0.05 OE PICK 0.02 … … trace_control
  • 48. @CaryMillsap Trace only some executions
 pseudocode sub should_trace(t) {
 select proportion from trace_control where task = :t; return (dbms_random.value(0,1) < proportion);
 } task_name proportion OE BOOK 0.05 OE PICK 0.02 … … trace_control 48 p = 0.95 should_trace('OE BOOK') == false p = 0.05 should_trace('OE BOOK') == true 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
  • 49. @CaryMillsap The new code
 pseudocode sub begin_task(t) { (mod, act) = split(/ /, t, 2); setClientInfo(properties(mod, act, getUserName()); xid = uuid(); push(xid_stack, (xid, t)); dbms_log.ksdwrt(1, sprintf("EXPERIENCE ID:(%s)", xid)); if (should_trace(t)) { session_trace_enable(true, true, 'first_execution'); } } sub end_task() { setClientInfo(properties("", "", "")); pop(xid_stack); dbms_log.ksdwrt(1, "EXPERIENCE ID:()"); session_trace_disable(); } 49
  • 50. Edit Email Assign Resolve Active Priority 3 – Required Edit Email Assign Resolve Opened by Cary Millsap 05/24/2018 (Today) 11:34 AM Cary Millsap Project: TPS Area: logging Milestone: 1.1.0 Kanban Column 1.1.0.1 @CaryMillsap 50 10003 We don't always want to use bind=true and plan_stat='first_execution'. We want to control those from trace_control as well. Manage tracing levels from trace_control
  • 51. @CaryMillsap Measurement intrusion Enough detail, but not too much. Oracle uses events and levels. $ORACLE_HOME/rdbms/mesg/oraus.msg • 10046 “enable SQL statement timing” levels 1, 4, 8, 16, 32, 64, … (sql_trace) • 10053 “CBO Enable optimizer trace” • 10200 “consistent read buffer status” 51
  • 52. @CaryMillsap How we avoid 10046 MIE 1. sql_trace wait=true, bind=false, plan_stat=first_execution 2. If application has lightweight row-by-row executions, we fix it. 3. sql_trace wait=true, bind=true, plan_stat=all_executions 52
  • 53. @CaryMillsap The new codepseudocode sub begin_task(t) { (mod, act) = split(/ /, t, 2); setClientInfo(properties(mod, act, getUserName()); xid = uuid(); push(xid_stack, (xid, t)); dbms_log.ksdwrt(1, sprintf("EXPERIENCE ID:(%s)", xid)); if ((bind, stat) = should_trace(t)) { session_trace_enable(true, bind, stat); } } sub end_task() { setClientInfo(properties("", "", "")); pop(xid_stack); dbms_log.ksdwrt(1, "EXPERIENCE ID:()"); session_trace_disable(); } 53 task_name proportion bind stat OE BOOK 0.05 FALSE FIRST_EXECUTION OE PICK 0.02 TRUE ALL_EXECUTIONS … … … … trace_control
  • 54. Edit Email Assign Resolve Active Priority 3 – Required Edit Email Assign Resolve Opened by Cary Millsap 05/24/2018 (Today) 11:34 AM Cary Millsap Project: TPS Area: logging Milestone: 1.1.0 Kanban Column 1.1.0.1 @CaryMillsap 54 10004 When a user has a performance problem with the application, she should be able to click Help › Debug › Trace, which will inspire a properly time-scoped trace of the next business task she executes. User controls tracing with Help › Debug › Trace
  • 55. @CaryMillsap Help › Debug › Trace How it usually works: 1. User clicks Help › Debug › Trace. 2. This triggers immediate session trace enable. 3. User eventually executes her task. 4. Clicks Help › Debug › Stop Trace. Not what you want. 55
  • 56. @CaryMillsap It’s not the trace file you want You need: trace enable == task begin trace disable == task end Otherwise, you get either too much data,
 or not enough. 56 trace disable task end task begin trace enable trace file you got trace file you want time
  • 57. @CaryMillsap Help › Debug › Trace A user turns on tracing. vs. A user expresses the intention to trace the next task execution. Help › Debug › Trace should set a boolean. begin_task queries the boolean. 57
  • 58. @CaryMillsap The new codepseudocode sub begin_task(t) { (mod, act) = split(/ /, t, 2); setClientInfo(properties(mod, act, getUserName()); xid = uuid(); push(xid_stack, (xid, t)); dbms_log.ksdwrt(1, sprintf("EXPERIENCE ID:(%s)", xid)); if (isTraceIntended() or (bind, stat) = should_trace(t)) { session_trace_enable(true, bind, stat); } } sub end_task() { setClientInfo(properties("", "", "")); pop(xid_stack); dbms_log.ksdwrt(1, "EXPERIENCE ID:()"); session_trace_disable(); } 58
  • 60. @CaryMillsap More specs (discussion) • Trace the first OE BOOK execution every hour. • Trace p% of Larry’s executions, but q% of Nancy’s. • Trace p% of executions whose durations have one of the top ten variance-to- mean ratios (VMR) in your application. • Trace only if the job is less than p% complete after running for m minutes. Could you do these even if you don’t have source code access? How? 60
  • 61. @CaryMillsap Hundreds of specs you could meet Trace when you need. Persist every response time. Predict response time problems. Track pathway through the application. Write harvesters, uploaders, profilers for the data. Log to shared memory segments for ultra-high throughput. You can build anything you want; application self-measurement is no big deal. 61
  • 62. @CaryMillsap For more information… 62 The definitive guide to accurate, high-precision measurement of user performance experiences, for Oracle application developers and database administrators. Cary V. Millsap TM MeTHOD R TM The Guide to MASTERING ORACLE TRACE DATA Second Edition REVISED UPDA TED NEW PA G ES 1 3 2 Available at