Recently, one of my customer asked me to design him a tool to quickly see the database load. He already did that for another Rdbms with a heatmap.
To do that, I used two distinct part in my work: Data Extraction, and Data Vizualisation.
Data Extraction from AWRAs he has licensed his databases with the Diagnostic pack , I decided to use AWR repository, and as I’m a bit lazy, I found a query from Marcin Przepiorowski (@pioro) and I modified it to pivot data.
col "00-01_ " for 90.99col "01-02_ " for 90.99
col "02-03_ " for 90.99
col "03-04_ " for 90.99
col "04-05_ " for 90.99
col "05-06_ " for 90.99
col "06-07_ " for 90.99
col "07-08_ " for 90.99
col "08-09_ " for 90.99
col "09-10_ " for 90.99
col "10-11_ " for 90.99
col "11-12_ " for 90.99
col "12-13_ " for 90.99
col "13-14_ " for 90.99
col "14-15_ " for 90.99
col "15-16_ " for 90.99
col "16-17_ " for 90.99
col "17-18_ " for 90.99
col "18-19_ " for 90.99
col "19-20_ " for 90.99
col "20-21_ " for 90.99
col "21-22_ " for 90.99
col "22-23_ " for 90.99
col "23-24_ " for 90.99
WITH t AS
(SELECT TO_CHAR(mtime,'YYYY/MM/DD') mtime,
TO_CHAR(mtime,'HH24') d,
LOAD AS value
FROM
(SELECT to_date(mtime,'YYYY-MM-DD HH24') mtime,
ROUND(SUM(c1),2) AAS_WAIT,
ROUND(SUM(c2),2) AAS_CPU,
ROUND(SUM(cnt),2) AAS,
ROUND(SUM(load),2) LOAD
FROM
(SELECT TO_CHAR(sample_time,'YYYY-MM-DD HH24') mtime,
DECODE(session_state,'WAITING',COUNT(*),0)/360 c1,
DECODE(session_state,'ON CPU',COUNT( *),0) /360 c2,
COUNT( *)/360 cnt,
COUNT( *)/360/cpu.core_nb load
FROM dba_hist_active_sess_history,
(SELECT value AS core_nb FROM v$osstat WHERE stat_name='NUM_CPU_CORES'
) cpu
WHERE sample_time > sysdate - 30
GROUP BY TO_CHAR(sample_time,'YYYY-MM-DD HH24'),
session_state,
cpu.core_nb
)
GROUP BY mtime
)
)
SELECT mtime,
NVL("00-01_ ",0) "00-01_ ",
NVL("01-02_ ",0) "01-02_ ",
NVL("02-03_ ",0) "02-03_ ",
NVL("03-04_ ",0) "03-04_ ",
NVL("04-05_ ",0) "04-05_ ",
NVL("05-06_ ",0) "05-06_ ",
NVL("06-07_ ",0) "06-07_ ",
NVL("07-08_ ",0) "07-08_ ",
NVL("08-09_ ",0) "08-09_ ",
NVL("09-10_ ",0) "09-10_ ",
NVL("10-11_ ",0) "10-11_ ",
NVL("11-12_ ",0) "11-12_ ",
NVL("12-13_ ",0) "12-13_ ",
NVL("13-14_ ",0) "13-14_ ",
NVL("14-15_ ",0) "14-15_ ",
NVL("15-16_ ",0) "15-16_ ",
NVL("16-17_ ",0) "16-17_ ",
NVL("17-18_ ",0) "17-18_ ",
NVL("18-19_ ",0) "18-19_ ",
NVL("19-20_ ",0) "19-20_ ",
NVL("20-21_ ",0) "20-21_ ",
NVL("21-22_ ",0) "21-22_ ",
NVL("22-23_ ",0) "22-23_ ",
NVL("23-24_ ",0) "23-24_ "
FROM t pivot( SUM(value) AS " " FOR d IN ('00' AS "00-01",'01' AS "01-02",'02' AS "02-03",'03' AS "03-04",'04' AS "04-05",'05' AS "05-06",'06' AS "06-07",'07' AS "07-08",
'08' AS "08-09",'09' AS "09-10",'10' AS "10-11", '11' AS "11-12",'12' AS "12-13",'13' AS "13-14",'14' AS "14-15",'15' AS "15-16",
'16' AS "16-17",'17' AS "17-18",'18' AS "18-19",'19' AS "19-20",'20' AS "20-21",'21' AS "21-22", '22' AS "22-23",'23' AS "23-24")
)
ORDER BY mtime
Nota: this query can be used to extract Database Load, Active Average Session (AAS), CPU part of AAS, and the Wait part of AAS. You just have to replace the value alias in the WITH Block.
Another point, I didn’t look at the plan, so I didn’t tune the statement … if you have some tricks to tune it … feel free to comment:wink:
This query gives this kind of result:
MTIME 00-01_ 01-02_ 02-03_ 03-04_ 04-05_ 05-06_ 06-07_ 07-08_ 08-09_ 09-10_ 10-11_ 11-12_ 12-13_ 13-14_ 14-15_ 15-16_ 16-17_ 17-18_ 18-19_ 19-20_ 20-21_ 21-22_ 22-23_ 23-24_---------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- -------
2016/11/23 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.03 0.03 0.00 0.04 0.02 0.00 0.00 0.04 0.01 0.01 0.01 0.04 0.01
2016/11/24 0.02 0.03 0.01 0.03 0.05 0.02 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
2016/12/06 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 0.01 0.02 0.02 0.00 0.00 0.00 0.00
2016/12/07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.04 0.03 0.01 0.02 0.01 0.02 0.01 0.01 0.06 0.03
2016/12/08 0.03 0.05 0.02 0.02 0.03 0.03 0.02 0.02 0.03 0.02 0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
2016/12/12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.03 0.02 0.05 0.02
2016/12/13 0.03 0.01 0.01 0.01 0.02 0.03 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
2016/12/14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.02 0.02 0.02 0.02 0.18 0.03 0.02 0.01 0.01 0.00 0.00 0.00 0.00 0.00
When the result is greater than 1, your database is loaded, but if it’s greater or equal that 2 … it’s really overloaded. In both cases, you have to analyze why ?
The problem with this kind of results is it’s only numbers and you have to analyze the complete results to detect when the problem occurs, here comes the data vizualisation part:wink:
Data Vizualisation with pythonOn the Oracle database Area, a guy has made a lot for visualization of performance data, it’s Kyle Hailey ( @ dbavigil ). And Visualize your data is a very important thing to quickly identify bottleneck. So if you’re interested by data vizualisation you can visit his blog, you will find a lot of resources to extract AWR data and to visualize them (and other stuff).
So I decided to use Python to vizualise database load data extracted previously. To do that, I used python 3.4.5 with a bunch of packages installed:
cx_Oracle to connect Oracle Database and executequeries on your Oracle Database numpy for arrays manipulation plotly to graph the heatmapThe python script is available by following this URL: https://app.box.com/s/irjzi64lbne6xhw3t57aixqiy95toxht . Then, you have to modify it to enter the connection string (line 33).
My customer asked me that my script generates an HTML file to visualize the heatmap in a browser (One of the reason I used plotly).
This script generates the file in /var/tmp (but you can modify it at the end) and then open the browser locally (So don’t forget to export X11 display if you run it on a linux server).
Below you can see the heatmap (X Axis is the hour range, Y Axis represent a day analyzed, the most recent day is on the first line of the heatmap.).

This heatmap will help my