Debug Slow Code in DB2 with DB2 Event Monitors
How to Capture DB2 Event Monitors with scripts? DB2 event monitors shows you in details, the
execution statistics about queries generated by your application. They allow analysis of the most time-consuming
database code therefore allow you to focus on fixing the most expensive queries.
DB2 has many monitors you can capture events for. For example:statements, deadlocks, database,
tables,connections, transactions, etc. The basic steps to capture event monitors include:
set them ON, run your app for a time interval, set them OFF (and data is capture at the same
time too).
__ 1. Set event monitors
~db2inst1/sqllib/db2profile
echo "set event monitors for ls db"
db2 connect to mydb user mydb_usr using password
echo "make sure cleaned up"
db2 drop event monitor x1mon
db2 update monitor switches using bufferpool on lock on uow on sort on table on statement on timestamp on
db2 reset monitor all
db2 "create event monitor x1mon for statements, deadlocks, database, tables, connections, \\
transactions write to file '/tmp/x1mon'"
db2 "set event monitor x1mon state 1"
Note: make sure permissions of the /tmp/x1mon dir is accessible by db2 owner
__ 2. Run your app, say, for 10 minutes (so long it is enough to execution the code paths you want)
__ 3. Set them OFF
~db2inst1/sqllib/db2profile
echo "generate event monitor data"
db2 set event monitor x1mon state 0
db2evmon -path /tmp/x1mon > /tmp/x1mon.out
echo "drop event monitors for ls db"
db2 drop event monitor x1mon
db2 get snapshot for dbm > /tmp/x1snapshot.txt
db2 get snapshot for all on mydb>> /tmp/x1snapshot.txt
db2 update monitor switches using bufferpool off lock off uow off sort off table off statement off t
imestamp off
db2 terminate
Look into /tmp/x1mon.out for details.
|
How to analyze event monitors?
When you browse through the db2evmon report file (somefilename.txt), look for
the SQL event records with Operation: Execute. Example below shows sample
output from the db2evmon program. Notice the detailed granularity of data
provided. For each SQL statement executed, you can find the total CPU time used
(user + system); when the statement started and stopped; statement elapsed time
(Exec Time); the number of sorts; sort overflows; rows read; rows fetched,
sort time (ms); and detailed bufferpool statistics.
-------------------------------------------
Type : Dynamic
Operation: Execute
Section : 4
Creator : NULLID
Package : SYSSH100
Consistency Token : SYSLVL01
Package Version ID :
Cursor : SQL_CURSH100C4
Cursor was blocking: FALSE
Text : CALL GETDEFINITION_SP(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
-------------------------------------------
Start Time: 01/25/2006 14:53:08.030149
Stop Time: 01/25/2006 14:53:08.115289
Exec Time: 0.085140 seconds
Number of Agents created: 1
User CPU: 0.006780 seconds
System CPU: 0.002360 seconds
Fetch Count: 0
Sorts: 0
Total sort time: 0
Sort overflows: 0
Rows read: 0
Rows written: 0
Internal rows deleted: 0
Internal rows updated: 0
Internal rows inserted: 0
Bufferpool data logical reads: 0
Bufferpool data physical reads: 0
Bufferpool temporary data logical reads: 0
Bufferpool temporary data physical reads: 0
Bufferpool index logical reads: 1
Bufferpool index physical reads: 0
Bufferpool temporary index logical reads: 0
Bufferpool temporary index physical reads: 0
SQLCA:
sqlcode: 0
sqlstate: 00000
You can then use AWK script to do all sorts of analysis. One example is to find out
the total time spent in database for a particular operation in your application. You
collect the event monitors for a single operation, then run a awk script like this:
# awk '/Exec Time:/{tt+=$3}; END {print tt}' myevent.out
8.14817
So if the entire operation took 10 seconds, and 8.14817 seconds are spent in database,
you may have to tune this particular query or stored procedure, because more than 81%
of the time is spent in database alone.
Another use is to show the histograms of all queries, therefore to spot perhpas the top
10 queries to focus on. The following awk script can help you do it (it removed duplicated
lines and counts them - works for sorted or unsorted files):
# Thanks to Byron Rakitzis for the general idea
{
if (data[$0]++ == 0)
lines[++count] = $0
}
END {
for (i = 1; i <= count; i++)
print data[lines[i]] "##" lines[i]
}
|
|