Visualizing Statspack Performance Data in SQL Developer

If you run Oracle Standard Edition or haven’t licenced Diagnostics Pack for Enterprise Edition, then you don’t have AWR and ASH Data available. This is when Statspack, the predecessor of AWR, comes in handy to keep a history of database performance metrics.

But although Oracle still deliver Statspack with their recent DB releases (yes, even in 12c it’s not dead!), there are few tools that support it. But wait – Oracle SQL Developer has a nice reporting feature built in, so why not build custom statspack reports for this great free tool?

This motivated me to start a series on leveraging SQL Developer Reports for DBA tasks, starting with visualizing logical I/O history.

First things first: I like my SQL Developer menus in English. Unfortunately, you cannot choose your preferred language from the preferences menu, so you have to add an entry to “<SQLDev Program Dir>/sqldeveloper/bin/sqldeveloper.conf”:

# Set language to English
AddVMOption -Duser.language=en

Okay, let’s fire up sqldev, go to the “Reports” tab an create a new user report:

10_new_report

and set the initial properties for the report – choose “Chart” as report type:

15_master_report

There are many, many ways to query Statspack data and to visualize performance metrics. Let me show you my way – your mileage may vary:

-- Pre-select snapshot detail using a WITH-clause,
-- particularly the time difference between snaps in seconds
WITH snaps AS(
     SELECT sn.snap_id
          , sn.snap_time
          , LAG( sn.snap_id, 1 ) OVER( ORDER BY sn.snap_id ) AS prev_snap_id
          , ( LAG( sn.snap_time, 1 ) OVER( ORDER BY sn.snap_id ) - sn.snap_time ) *24*3600 AS time_diff
          , sn.instance_number
          , sn.dbid
       FROM stats$snapshot sn
)
-- These are the columns SQL Developer needs for a graph:
-- X-axis, series name, Y-axis
SELECT TO_CHAR( snap_time, 'dd.mm. hh24:mi' ) time
     , stat_name
     , value_diff  * blksz / 1024 / 1024
       / DECODE( time_diff, 0, NULL, time_diff ) "MB/s"
  FROM
     (
     SELECT sn.snap_id
          -- the LAG distance has to match the number of metrics collected
          -- e.g., 2 metrics ==> LAG( x, 2 )
          , ( LAG( ss.value, 2 ) OVER( ORDER BY ss.snap_id, ss.name ) - ss.value ) AS value_diff
          , sn.time_diff
          , sn.snap_time
          , ss.name stat_name
          , ( select to_number(value) from v$parameter where name='db_block_size' ) blksz
       FROM stats$sysstat ss
          , snaps sn
      WHERE ss.name IN ('db block gets', 'consistent gets') --, 'session logical reads')
        AND sn.snap_id = ss.snap_id
        AND ss.dbid = sn.dbid
        -- use instance_number to be RAC-aware.
        -- restrict the selection to the current instance.
        AND ss.instance_number = sn.instance_number
        AND sn.instance_number = ( SELECT instance_number FROM v$instance )
     )
ORDER BY snap_time, stat_name DESC

Now the SQL is entered, choose an appropriate graph type. In our case, the sum of “db block gets” and “consistent gets” equals “session logical reads” – thus, a stacked area graph shows us three metrics by selecting only two.

20_report_props_area

Let’s give our report a self-explanatory title:

30_report_props_title

I don’t like the default colour, especially when it comes to series that differ by orders of magnitude. So let’s choose a brighter colour for the “db block gets” column:

35_report_props_plotarea

A title for the Y-Axis would also be nice. Furthermore, when the instance is restarted, many metrics are reset to zero, resulting in huge negative differences ruining our graph. You could either mitigate this with SQL or, as shown here, by setting the minimum Y-Axis value to 0 (zero).

40_report_props_y

Finally, let’s hit “Apply” an check out how our graph looks!

LIO_1

Looks good already, doesn’t it? Actually, this is real world data and quite typical for an OLTP system with many reads and little changes. If just the tiny area of the “db block gets” would show up better… But hey, there’s an option in the report properties that helps! Change the scale to “logarithmic” and see for yourself:

50_report_props_y_log

The logarithmic scale works only when the minimum value is set automatically, so check that box back again.

LIO_log10

Not too bad, either. Now you can easily check the values of that little metric by hovering with your mouse cursor over the area.

But wait – there’s more to those graphs: What if we want to plot a value that’s not part of the sum but also a component of logical I/O? Can we combine a stacked graph with a line for that separate series? Yes, we can (sorry, couldn’t resist the pun)!

Here’s our SQL, now with an additional metric:

WITH snaps AS(
     SELECT sn.snap_id
          , sn.snap_time
          , LAG( sn.snap_id, 1 ) OVER( ORDER BY sn.snap_id ) AS prev_snap_id
          , ( LAG( sn.snap_time, 1 ) OVER( ORDER BY sn.snap_id ) - sn.snap_time ) *24*3600 AS time_diff
          , sn.instance_number
          , sn.dbid
       FROM stats$snapshot sn
)
SELECT TO_CHAR( snap_time, 'dd.mm. hh24:mi' ) time
     , stat_name
     , value_diff  * blksz / 1024 / 1024
       / DECODE( time_diff, 0, NULL, time_diff ) "MB/s"
  FROM
     (
     SELECT sn.snap_id
          , ( LAG( ss.value, 3 ) OVER( ORDER BY ss.snap_id, ss.name ) - ss.value ) AS value_diff
          , sn.time_diff
          , sn.snap_time
          , ss.name stat_name
          , ( select to_number(value) from v$parameter where name='db_block_size' ) blksz
       FROM stats$sysstat ss
          , snaps sn
      WHERE ss.name IN ('db block changes', 'db block gets', 'consistent gets')
        AND sn.snap_id = ss.snap_id
        AND ss.dbid = sn.dbid
        AND ss.instance_number = sn.instance_number
        AND sn.instance_number = ( SELECT instance_number FROM v$instance )
     )
ORDER BY snap_time, stat_name DESC

60_report_props_combi

After changing the chart type to “Combination”, open the “Plot Area” properties again and choose colours and graph types for our series. We want to plot “db block changes” as a line and the other series as an area:

65_report_props_color

And this is how it looks in the end:LIO_log10_combi

Unfortunately, the graph library of SQL Developer 4.0.3 draws the yellow area with gaps inbetween. So far I haven’t found a way to change that; if you know a solution, let me know in the comments, please.

At this point you might consider saving this report. The saved XML file can then be transferred to another computer / SQL Developer installation or shared publicly as I do in my SQL Developer Repository on GitHub. So, in case you don’t want to walk through this article, feel free to download this report from there.

Hope this helps,

Uwe

Advertisements

One thought on “Visualizing Statspack Performance Data in SQL Developer

  1. Pingback: Log Buffer #414, A Carnival of the Vanities for DBAs | InsideMySQL

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s