├── LICENSE
├── README.md
├── awr-generator.sql
├── awr-io.sh
├── awr-parser.sh
├── setup-kaminario-mpath.sh
├── setup-violin-mpath.sh
├── show_physical_io.sql
└── slob_harness.sh
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
341 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | scripts
2 | =======
3 |
4 | Scripts and tools from flashdba
5 |
--------------------------------------------------------------------------------
/awr-generator.sql:
--------------------------------------------------------------------------------
1 | -- AWR-Generator.sql: Script for creating multiple consecutive Oracle AWR Reports
2 | -- Creates an output SQL script which, when run, will generate
3 | -- all AWR Reports between the specificed start and end snapshot
4 | -- IDs, for all instances
5 | --
6 | -- See GitHub repository at https://github.com/flashdba/scripts
7 | --
8 | -- ###########################################################################
9 | -- # #
10 | -- # Copyright (C) {2014,2015} Author: flashdba (http://flashdba.com) #
11 | -- # #
12 | -- # This program is free software; you can redistribute it and/or modify #
13 | -- # it under the terms of the GNU General Public License as published by #
14 | -- # the Free Software Foundation; either version 2 of the License, or #
15 | -- # (at your option) any later version. #
16 | -- # #
17 | -- # This program is distributed in the hope that it will be useful, #
18 | -- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
19 | -- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
20 | -- # GNU General Public License for more details. #
21 | -- # #
22 | -- # You should have received a copy of the GNU General Public License along #
23 | -- # with this program; if not, write to the Free Software Foundation, Inc., #
24 | -- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #
25 | -- # #
26 | -- ###########################################################################
27 |
28 | set feedback off
29 | set echo off
30 | set verify off
31 | set timing off
32 |
33 | -- Set AWR_FORMAT to "text" or "html"
34 | define AWR_FORMAT = 'text'
35 | define DEFAULT_OUTPUT_FILENAME = 'awr-generate.sql'
36 | define NO_ADDM = 0
37 | -- start and end snap gap. For example to generate report for 1 hour interval with 15 mins snap set it to 4
38 | define snap_interval = 1
39 |
40 | -- Get values for dbid and inst_num before calling awrinput.sql
41 |
42 | set echo off heading on
43 | column inst_num heading "Inst Num" new_value inst_num format 99999;
44 | column inst_name heading "Instance" new_value inst_name format a12;
45 | column db_name heading "DB Name" new_value db_name format a12;
46 | column dbid heading "DB Id" new_value dbid format 9999999999 just c;
47 |
48 | prompt
49 | prompt Current Instance
50 | prompt ~~~~~~~~~~~~~~~~
51 |
52 | select d.dbid dbid
53 | , d.name db_name
54 | , i.instance_number inst_num
55 | , i.instance_name inst_name
56 | from v$database d,
57 | v$instance i;
58 |
59 |
60 | -- Call the Oracle common input script to setup start and end snap ids
61 | @@?/rdbms/admin/awrinput.sql
62 |
63 | -- Ask the user for the name of the output script
64 | prompt
65 | prompt Specify output script name
66 | prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~
67 | prompt This script produces output in the form of another SQL script
68 | prompt The output script contains the commands to generate the AWR Reports
69 | prompt
70 | prompt The default output file name is &DEFAULT_OUTPUT_FILENAME
71 | prompt To accept this name, press to continue, otherwise enter an alternative
72 | prompt
73 |
74 | set heading off
75 | column outfile_name new_value outfile_name noprint;
76 | select 'Using the output file name ' || nvl('&&outfile_name','&DEFAULT_OUTPUT_FILENAME')
77 | , nvl('&&outfile_name','&DEFAULT_OUTPUT_FILENAME') outfile_name
78 | from sys.dual;
79 |
80 | set linesize 800
81 | set serverout on
82 | set termout off
83 |
84 | -- spool to outputfile
85 | spool &outfile_name
86 |
87 | -- write script header comments
88 | prompt REM Temporary script created by awr-generator.sql
89 | prompt REM Used to create multiple AWR reports between two snapshots
90 | select 'REM Created by user '||user||' on '||sys_context('userenv', 'host')||' at '||to_char(sysdate, 'DD-MON-YYYY HH24:MI') from dual;
91 |
92 | set heading on
93 |
94 | DECLARE
95 |
96 | -- Begin iterating through snapshots and generating reports
97 | c_dbid CONSTANT NUMBER := :dbid;
98 | c_inst_num CONSTANT NUMBER := :inst_num;
99 | c_start_snap_id CONSTANT NUMBER := :bid;
100 | c_end_snap_id CONSTANT NUMBER := :eid;
101 | c_awr_options CONSTANT NUMBER := &&NO_ADDM;
102 | c_report_type CONSTANT CHAR(4):= '&&AWR_FORMAT';
103 | v_awr_reportname VARCHAR2(100);
104 | v_report_suffix CHAR(5);
105 | c_snap_internaval CONSTANT NUMBER := &&snap_interval;
106 |
107 | CURSOR c_snapshots IS
108 | select inst_num, start_snap_id, end_snap_id, seqnum
109 | from (
110 | select s.instance_number as inst_num,
111 | s.snap_id as start_snap_id,
112 | lead(s.snap_id,c_snap_internaval,null) over (partition by s.instance_number order by s.snap_id) as end_snap_id,
113 | row_number() over (partition by s.instance_number order by s.snap_id) as seqnum
114 | from dba_hist_snapshot s
115 | where s.dbid = c_dbid
116 | and s.snap_id >= c_start_snap_id
117 | and s.snap_id <= c_end_snap_id
118 | )
119 | where end_snap_id is not null
120 | and mod(seqnum, c_snap_internaval) = 0
121 | order by inst_num, start_snap_id;
122 |
123 | BEGIN
124 |
125 | dbms_output.put_line('');
126 | dbms_output.put_line('prompt Beginning AWR Generation...');
127 |
128 | dbms_output.put_line('set heading off feedback off lines 800 pages 5000 trimspool on trimout on');
129 |
130 | -- Determine report type (html or text)
131 | IF c_report_type = 'html' THEN
132 | v_report_suffix := '.html';
133 | ELSE
134 | v_report_suffix := '.txt';
135 | END IF;
136 |
137 | -- Iterate through snapshots
138 | FOR cr_snapshot in c_snapshots
139 | LOOP
140 | -- Construct filename for AWR report
141 | v_awr_reportname := 'awrrpt_'||cr_snapshot.inst_num||'_'||cr_snapshot.start_snap_id||'_'||cr_snapshot.end_snap_id||v_report_suffix;
142 |
143 | dbms_output.put_line('prompt Creating AWR Report '||v_awr_reportname
144 | ||' for instance number '||cr_snapshot.inst_num||' snapshots '||cr_snapshot.start_snap_id||' to '||cr_snapshot.end_snap_id);
145 | dbms_output.put_line('prompt');
146 |
147 | -- Disable terminal output to stop AWR text appearing on screen
148 | dbms_output.put_line('set termout off');
149 |
150 | -- Set spool to create AWR report file
151 | dbms_output.put_line('spool '||v_awr_reportname);
152 |
153 | -- call the table function to generate the report
154 | IF c_report_type = 'html' THEN
155 | dbms_output.put_line('select output from table(dbms_workload_repository.awr_report_html('
156 | ||c_dbid||','||cr_snapshot.inst_num||','||cr_snapshot.start_snap_id||','||cr_snapshot.end_snap_id||','||c_awr_options||'));');
157 | ELSE
158 | dbms_output.put_line('select output from table(dbms_workload_repository.awr_report_text('
159 | ||c_dbid||','||cr_snapshot.inst_num||','||cr_snapshot.start_snap_id||','||cr_snapshot.end_snap_id||','||c_awr_options||'));');
160 | END IF;
161 |
162 | dbms_output.put_line('spool off');
163 |
164 | -- Enable terminal output having finished generating AWR report
165 | dbms_output.put_line('set termout on');
166 |
167 | END LOOP;
168 |
169 | dbms_output.put_line('set heading on feedback 6 lines 100 pages 45');
170 |
171 | dbms_output.put_line('prompt AWR Generation Complete');
172 |
173 | -- EXCEPTION HANDLER?
174 |
175 | END;
176 | /
177 |
178 | spool off
179 |
180 | set termout on
181 |
182 | prompt
183 | prompt Script written to &outfile_name - check and run in order to generate AWR reports...
184 | prompt
185 |
186 | --clear columns sql
187 | undefine outfile_name
188 | undefine AWR_FORMAT
189 | undefine DEFAULT_OUTPUT_FILENAME
190 | undefine NO_ADDM
191 | undefine OUTFILE_NAME
192 |
193 | set feedback 6 verify on lines 100 pages 45
194 |
--------------------------------------------------------------------------------
/awr-io.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # awr-io.sh - Simple script to extract IO information from an Oracle AWR report
4 | #
5 | # Author: flashdba (http://flashdba.com)
6 | #
7 | # For educational purposes only - no warranty is provided
8 | # Test thoroughly - use at your own risk
9 |
10 | total_iops() {
11 | TOTAL_IOPS=`grep "Total Requests:" $file | awk '{ print $4 }'`
12 | return 0
13 | }
14 |
15 | total_throughput() {
16 | TOTAL_THROUGHPUT=`grep "Total (MB):" $file | grep -v Optimized | awk '{ print $4 }'`
17 | return 0
18 | }
19 |
20 | latency() {
21 | READ_LATENCY=`grep -A 10 "Top 10 Foreground" $file | grep "db file sequential read" | awk '{ print $7 }'`
22 | return 0
23 | }
24 |
25 | if [ "$#" -lt 1 ]; then
26 | echo "Usage: $0 "
27 | exit 1
28 | fi
29 |
30 | for file in $*; do
31 | total_iops
32 | total_throughput
33 | latency
34 | echo "$file: IOPS = $TOTAL_IOPS THROUGHPUT: $TOTAL_THROUGHPUT READ LATENCY = $READ_LATENCY"
35 | done
36 | exit 0
37 |
--------------------------------------------------------------------------------
/awr-parser.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # AWR Parser script : tool for extracting data from Oracle AWR reports
4 | #
5 | # See GitHub repository at https://github.com/flashdba/scripts
6 | #
7 | # ###########################################################################
8 | # # #
9 | # # Copyright (C) {2014,2015,2016} Author: flashdba (http://flashdba.com) #
10 | # # #
11 | # # This program is free software; you can redistribute it and/or modify #
12 | # # it under the terms of the GNU General Public License as published by #
13 | # # the Free Software Foundation; either version 2 of the License, or #
14 | # # (at your option) any later version. #
15 | # # #
16 | # # This program is distributed in the hope that it will be useful, #
17 | # # but WITHOUT ANY WARRANTY; without even the implied warranty of #
18 | # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
19 | # # GNU General Public License for more details. #
20 | # # #
21 | # # You should have received a copy of the GNU General Public License along #
22 | # # with this program; if not, write to the Free Software Foundation, Inc., #
23 | # # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #
24 | # # #
25 | # ###########################################################################
26 | #
27 | AWRSCRIPT_VERSION="1.02"
28 | AWRSCRIPT_LASTUPDATE="04/12/2016"
29 | #
30 | # Used to parse multiple AWR reports and extract useful information
31 | # The input is an AWR workload repository report **in TEXT format**
32 | # - HTML format reports will be ignored, as will STATSPACK reports
33 | # The output is a CSV file which can be used in Microsoft Excel etc
34 | #
35 | # Usage: ./awr-parser.sh [ -n | -H ] [ -s | -p | -v ] (wildcards are accepted)
36 | #
37 | # Script for parsing multiple AWR reports and extracting useful information
38 | # Redirect stdout to a CSV file to import into Excel
39 | # Errors and info are printed to stderr
40 | #
41 | # Options:
42 | # -h Help (print help and version information)
43 | # -H Header (print the header row only and then exit)
44 | # -n NoHeader (do not print the header row in the CSV file)
45 | # -p Print (print AWR report values to screen)
46 | # -s Silent (do not print AWR processing information)
47 | # -v Verbose (show extra AWR processing details)
48 | # -X DEBUG *** HIDDEN OPTION FOR DEBUGGING ***
49 | #
50 | # Return Values:
51 | # 0 Complete Success (all files processed)
52 | # 1 Partial Success (some files processed)
53 | # 2 Failure (no files processed)
54 | #
55 | # Example:
56 | # ./awr-parser.sh -v awrrpt*.txt > output.csv
57 | #
58 | # Version History
59 | #
60 | # 1.00 01/12/2014 flashdba Initial release (open sourced from AWR-Analyze.sh)
61 | # 1.01 05/01/2015 flashdba Added ability to read Wait Event Histogram sections
62 | # 1.02 04/12/2016 flashdba Bugfix: Exadata statistics cause incorrect read of physical read/write throughput
63 |
64 | # I have recently learnt that the way I calculate Redo write IOPS/Throughput is incorrect. The Oracle statistic "redo size" does
65 | # not take into account multiplexing of online redo logs, nor does it include the value of "redo wastage". For this reason the
66 | # parsed values for Redo Write IOPS/Throughput and Data Write IOPTS/Throughput are likely to be incorrect. The fix (TODO) will
67 | # be to read the values for Redo from the IOStat section of later AWR reports, or the IO Profile section of >= 11.2.0.4
68 |
69 | # A note about the use of bc - the Basic Calculator
70 | # This script uses bc in numerous places so if running via Cygwin ensure bc is installed (it is not part of the default install)
71 | # When reducing the scale of numbers in bc, the default behaviour is simply to drop the extra decimal places insetad of rounding
72 | # To make bc round we have to use a hack where we add half a decimal point and then divide by one
73 | # For example, when reducing to one decimal place we add 0.05 then divide by 1 causing bc to implement the scale reduction
74 | # Alternatively, when reducing to three decimal places we add 0.0005 then divide by 1...it's not pretty, but it works just fine
75 |
76 | # Define counters and flags
77 | ERRORCNT=0 # Count number of files where processing errors occurred
78 | FILECNT=0 # Count number of files where processing was attempted
79 | HEADERROW=1 # 0 = No, 1 = Yes, 2 = Only
80 | SILENT=0 # 0 = No, 1 = Yes
81 | PRINT_REPORT_INFO=0 # 0 = No, 1 = Yes
82 | VERBOSE=0 # 0 = No, 1 = Yes
83 | DEBUG=0 # 0 = No, 1 = Yes
84 | # Define constants
85 | EXIT_SUCCESS=0
86 | EXIT_PARTIAL_SUCCESS=1
87 | EXIT_FAILURE=2
88 | AWR_NOTFOUND=0
89 | AWR_PENDING=1
90 | AWR_FOUND=2
91 | # Define section terminators in AWR reports (a string of 61 hyphens)
92 | # Two variables are needed deending on whether we are searching by line or word (see comments on the IFS variable)
93 | OLD_AWR_SECTION_TERMINATOR_BY_WORD="-------------------------------------------------------------"
94 | OLD_AWR_SECTION_TERMINATOR_BY_LINE=" -------------------------------------------------------------"
95 | # In 12c format reports the section terminators are different - there are only 54 hyphens
96 | NEW_AWR_SECTION_TERMINATOR_BY_WORD="------------------------------------------------------"
97 | NEW_AWR_SECTION_TERMINATOR_BY_LINE=" ---------------------------------------------"
98 | # Define field terminator for use with debugging the contents of variables
99 | ENDCHAR=""
100 |
101 | # Define functions for printing messages - echodbg includes call to translate the # character into horizontal tab then expand back to spaces (makes debug easier to read)
102 | echoerr() { echo "Error: $@" 1>&2; let ERRORCNT++; }
103 | echoinf() { [[ "$SILENT" = 1 ]] || echo "Info : ${@}${ENDCHAR}" 1>&2; }
104 | echoprt() { echo "Info : ${@}${ENDCHAR}" 1>&2; }
105 | echovrb() { [[ "$VERBOSE" = 1 ]] && echo "Info : ${@}${ENDCHAR}" 1>&2; }
106 | echodbg() { [[ "$DEBUG" = 1 ]] && echo "Debug: ${@}" | tr '#' '\t' | expand -t 15 1>&2; }
107 | echocsv() { echo "$@"; }
108 |
109 | # Function for printing usage information
110 | usage() {
111 | if [ "$#" -gt 0 ]; then
112 | echo "Error: $@" 1>&2
113 | fi
114 | echo "Usage: $0 [ -n | -H ] [ -s | -p | -v ] (wildcards are accepted)" 1>&2
115 | echo "" 1>&2
116 | echo " Version v${AWRSCRIPT_VERSION} (published on $AWRSCRIPT_LASTUPDATE)"
117 | echo "" 1>&2
118 | echo " Script for parsing multiple AWR reports and extracting useful information"
119 | echo " Redirect stdout to a CSV file to import into Excel" 1>&2
120 | echo " Errors and info are printed to stderr" 1>&2
121 | echo "" 1>&2
122 | echo " Options:" 1>&2
123 | echo " -h Help (print help and version information)" 1>&2
124 | echo " -H Header (print the header row only and then exit)" 1>&2
125 | echo " -n NoHeader (do not print the header row in the CSV file)" 1>&2
126 | echo " -p Print (print AWR report values to screen)" 1>&2
127 | echo " -s Silent (do not print AWR processing information)" 1>&2
128 | echo " -v Verbose (show extra AWR processing details)" 1>&2
129 | echo "" 1>&2
130 | echo " Example usage:" 1>&2
131 | echo " $0 awr*.txt > awr.csv" 1>&2
132 | echo "" 1>&2
133 | exit $EXIT_FAILURE
134 | }
135 |
136 | # Function for setting the Internal Field Seperator so that lines read from the AWR file are word-delimited
137 | # This means that spaces, tabs and newlines are all used as field seperators
138 | set_ifs_to_word_delimited() {
139 | IFS_DELIMITER="WORD"
140 | IFS=$' \t\n' && echodbg " Setting IFS to SPACE, TAB and NEWLINE"
141 | }
142 |
143 | # Function for setting the Internal Field Seperator so that lines read from the AWR file are line-delimited
144 | # This means that only newlines are used as field seperators, while spaces and tabs are not
145 | set_ifs_to_line_delimited() {
146 | IFS_DELIMITER="LINE"
147 | IFS=$'\n' && echodbg " Setting IFS to NEWLINE"
148 | }
149 |
150 | # Function for determining the width and location of columns within each AWR section
151 | # It is passed the header row (a set of hyphens) as input and updates a set of variables accordingly
152 | process_header_row() {
153 | echodbg "Entering process_header_row() with argument $1"
154 | # Clear the column variables down
155 | unset AWRCOL1 AWRCOL2 AWRCOL3 AWRCOL4 AWRCOL5 AWRCOL6 AWRCOL7 AWRCOL8 AWRCOL9 AWRCOL10
156 | if [ -z "$1" ]; then
157 | echodbg "process_header_row() called with zero arguments - doing nothing"
158 | PROCESS_HEADER_ROW="NO_DATA"
159 | return $EXIT_FAILURE
160 | else
161 | # Set IFS to be word delimited
162 | [[ "$IFS_DELIMITER" = "LINE" ]] && IFS=$' \t\n'
163 | HEADERROW_ARRAY=($1)
164 | HEADERROW_COLUMNS="${#HEADERROW_ARRAY[@]}"
165 |
166 | # If necessary change the IFS back to line delimited
167 | [[ "$IFS_DELIMITER" = "LINE" ]] && IFS=$'\n'
168 |
169 | # If there are less than six words in this header then abandon attempt to process this section
170 | if [ "$HEADERROW_COLUMNS" -lt "6" ]; then
171 | echovrb "Failed during process_header_row() because header did not have enough arguments ($HEADERROW_COLUMNS)"
172 | PROCESS_HEADER_ROW="FAILED"
173 | return $EXIT_FAILURE
174 | elif [ "$HEADERROW_COLUMNS" -gt "10" ]; then
175 | echovrb "Failed during process_header_row() because header had too many arguments ($HEADERROW_COLUMNS)"
176 | PROCESS_HEADER_ROW="FAILED"
177 | return $EXIT_FAILURE
178 | else
179 | echodbg "Analyzing header row with $HEADERROW_COLUMNS columns"
180 | fi
181 |
182 | # Variable for use in while loop iterating through columns in header row
183 | AWRCOLNUM=1
184 | # Use a counter to keep track of the column locations
185 | COL_COUNTER=1
186 |
187 | # Begin calculating column locations
188 | while [ "$AWRCOLNUM" -le "$HEADERROW_COLUMNS" ]; do
189 | eval AWRCOL${AWRCOLNUM}="${COL_COUNTER}-$(($COL_COUNTER + ${#HEADERROW_ARRAY[${AWRCOLNUM} - 1]} - 1))"
190 | COL_COUNTER=$(($COL_COUNTER + ${#HEADERROW_ARRAY[${AWRCOLNUM}-1]} + 1))
191 | let AWRCOLNUM++
192 | done
193 | echodbg "Computed column widths: AWRCOL1=$AWRCOL1, AWRCOL2=$AWRCOL2, AWRCOL3=$AWRCOL3, AWRCOL4=$AWRCOL4, AWRCOL5=$AWRCOL5, AWRCOL6=$AWRCOL6, AWRCOL7=$AWRCOL7, AWRCOL3=$AWRCOL8, AWRCOL4=$AWRCOL9, AWRCOL5=$AWRCOL10"
194 | PROCESS_HEADER_ROW="SUCCESS"
195 | return $EXIT_SUCCESS
196 | fi
197 | }
198 |
199 | # Function for processing AWR header section and extracting information about the system
200 | process_awr_report() {
201 | # Read the AWR report looking for key sections containing required information
202 | # Note that different versions of Oracle have different formats for the AWR header
203 | # For the first two sections we have to look for a header and then set a flag (to $AWR_FOUND)
204 | # This flag then triggers specific behaviour over the next defined number of lines
205 | # For example, the phrase "DB Name" indicates the start of the DB Details section
206 | # We therefore know that two lines later will contain the DB name, instance num, version etc
207 | # After this the report is divided up into sections, each of which has its own handler below
208 | # There are two methods of parsing the data depending on the way it is formatted in the report
209 | # For one method (e.g. the Profile section) we read each word on the line into its own array element
210 | # We then pick the data out based on its position relative to the number of words in the line
211 | # The other method is to pick data out based on start and end character positions (e.g. the Top 5 section)
212 | # For this method we read the entire line into one array element and parse it using the cut tool
213 | # Switching between these two methods is a case of changing the Internal Field Seperator (IFS) variable
214 | # IFS is either set to space, tab and newline (word method) or just newline (character method)
215 |
216 | # Define a set of variables
217 | ROWCNT=0 # Counter for incrementing as rows of each report are read
218 | TOP5_LINENUM=0 # Counter for incrementing as wait details in Top 5 section are read
219 | AWR_FORMAT="Unknown" # Variable to hold the format version of the AWR report
220 | AWRLINE_SKIP=0 # When value n is greater than zero the next n non-empty lines will be skipped
221 | AWRSECTION_SKIP=0 # When value n is greater than zero the next n AWR sections will be skipped
222 | BAILOUT_COUNTER=0 # Counter for incrementing when searching for the header row of certain sections
223 | BAILOUT_LIMIT=10 # Threshold beyond which hander will abandon searching for the header row
224 | FOUND_SYS_DETAILS=$AWR_NOTFOUND # This is set to AWR_FOUND when the database system details are found
225 | FOUND_HOST_DETAILS=$AWR_NOTFOUND # This is set to AWR_FOUND when the host system details are found
226 | FOUND_TOP5_EVENTS=$AWR_NOTFOUND # This is set to AWR_FOUND when the Top 5 foreground event details are found (Top 10 in 12c)
227 | FOUND_FG_WAIT_CLASS=$AWR_NOTFOUND # This is set to AWR_FOUND when the foreground wait class details are found
228 | FOUND_FG_WAIT_EVENTS=$AWR_NOTFOUND # This is set to AWR_FOUND when the foreground wait event details are found
229 | FOUND_BG_WAIT_EVENTS=$AWR_NOTFOUND # This is set to AWR_FOUND when the background wait event details are found
230 | FOUND_HG_WAIT_EVENTS=$AWR_NOTFOUND # This is set to AWR_FOUND when the wait event histogram details are found
231 | TOTAL_WAIT_TIME=0 # Counter used in wait class section to sum wait times if DB TIME not present in report
232 | AWR_SECTION="AWRProfile" # Current section - influences which handler routine will be used to process data
233 | echodbg "State change AWR_SECTION: reset to Profile"
234 |
235 | # Reset the AWR section terminator varibles to those that match 10g and 11g
236 | AWR_SECTION_TERMINATOR_BY_WORD="$OLD_AWR_SECTION_TERMINATOR_BY_WORD"
237 | AWR_SECTION_TERMINATOR_BY_LINE="$OLD_AWR_SECTION_TERMINATOR_BY_LINE"
238 |
239 | # Process the file one line at a time using the read commant - each line will be read into the array AWRLINE and processed
240 | # For the first section of the AWR report (the Profile) we want each word on a line to live in a seperate element of an array
241 | # We therefore need to set the IFS (Internal Field Seperator) variable to recognise spaces and tabs as delimiters
242 | # Later on, when processing other sections, we will change this so that only new lines are recognised as delimiters
243 | set_ifs_to_word_delimited
244 |
245 | # Begin reading file line by line placing the contents into an array variable
246 | while read -r -a AWRLINE; do
247 | # Increment row counter
248 | let ROWCNT++
249 | # Remove carriage returns and form feed characters from first element of array to aid in pattern matching later on
250 | AWRLINE[0]=$(echo ${AWRLINE[0]} | tr -d '\r\f')
251 |
252 | # If line is empty (after removal of control characters) then do not process
253 | if [ "${#AWRLINE[@]}" = 1 ] && [ -z "${AWRLINE[0]}" ]; then
254 | echodbg " Skipping blank line#line $ROWCNT Size=${#AWRLINE[@]} IFS=$IFS_DELIMITER =#${ENDCHAR}${AWRLINE[@]}${ENDCHAR}"
255 | continue
256 |
257 | # Check for situation where report was generated using SELECT output FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXT)
258 | # and user did not set heading to 0 resulting in repeated header lines throughout report - skip these lines
259 | elif [ "${#AWRLINE[@]}" -le 2 ] && [ "${AWRLINE[0]:0:6}" = "OUTPUT" ]; then
260 | # The next line will be a set of SQLPlus underline characters (usually hyphens) which need to be ignored
261 | # Therefore increment the counter which controls line skipping
262 | echodbg " SQLPlus header at line $ROWCNT - ignoring this plus next line =#${ENDCHAR}${AWRLINE[@]}${ENDCHAR}"
263 | let AWRLINE_SKIP++
264 | continue
265 |
266 | # If AWRLINE_SKIP greater than zero then decrement and ignore current line
267 | elif [ "$AWRLINE_SKIP" -gt 0 ]; then
268 | echodbg " Skipping line $ROWCNT due to AWRLINE_SKIP counter ($AWRLINE_SKIP) =#${ENDCHAR}${AWRLINE[@]}${ENDCHAR}"
269 | let AWRLINE_SKIP--
270 | continue
271 |
272 | # Check for the standard AWR section terminator (a string of 61 hyphen characters) when IFS is set to word delimited
273 | elif [ "$IFS_DELIMITER" = "WORD" ] && [ "${AWRLINE[0]}" = "$AWR_SECTION_TERMINATOR_BY_WORD" ]; then
274 | echodbg " In $AWR_SECTION#line $ROWCNT Size=${#AWRLINE[@]} IFS=$IFS_DELIMITER =#${ENDCHAR}${AWRLINE[@]}${ENDCHAR}"
275 | if [ "$AWRSECTION_SKIP" -gt 0 ]; then
276 | let AWRSECTION_SKIP--
277 | echodbg "Found AWR section terminator at $ROWCNT - decrementing AWRSECTION_SKIP counter to $AWRSECTION_SKIP"
278 | elif [ "$AWR_SECTION" != "SearchingForNextSection" ]; then
279 | echovrb "Found AWR section terminator at $ROWCNT - marking end of section $AWR_SECTION"
280 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
281 | AWR_SECTION="SearchingForNextSection"
282 | # Switch Internal Field Seperator to only recognise newlines as delimiters
283 | set_ifs_to_line_delimited
284 | fi
285 | continue
286 |
287 | # Check for the standard AWR section terminator (a string of 61 hyphen characters) when IFS is set to line delimited
288 | elif [ "$IFS_DELIMITER" = "LINE" ] && [ "${AWRLINE[0]:0:71}" = "$AWR_SECTION_TERMINATOR_BY_LINE" ]; then
289 | echodbg " In $AWR_SECTION#line $ROWCNT Size=${#AWRLINE[@]} IFS=$IFS_DELIMITER =#${ENDCHAR}${AWRLINE[@]}${ENDCHAR}"
290 | if [ "$AWRSECTION_SKIP" -gt 0 ]; then
291 | let AWRSECTION_SKIP--
292 | echodbg "Found AWR section terminator at $ROWCNT - decrementing AWRSECTION_SKIP counter to $AWRSECTION_SKIP"
293 | elif [ "$AWR_SECTION" != "SearchingForNextSection" ]; then
294 | echovrb "Found AWR section terminator at $ROWCNT - marking end of section $AWR_SECTION"
295 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
296 | AWR_SECTION="SearchingForNextSection"
297 | # Switch Internal Field Seperator to only recognise newlines as delimiters
298 | set_ifs_to_line_delimited
299 | fi
300 | continue
301 |
302 | # If AWRSECTION_SKIP greater than zero then ignore current line
303 | elif [ "$AWRSECTION_SKIP" -gt 0 ]; then
304 | echodbg " Skipping line $ROWCNT due to AWRSECTION_SKIP counter ($AWRSECTION_SKIP) =#${ENDCHAR}${AWRLINE[@]}${ENDCHAR}"
305 | continue
306 |
307 | # If debug is enabled print the whole line
308 | else
309 | echodbg " In $AWR_SECTION#line $ROWCNT Size=${#AWRLINE[@]} IFS=$IFS_DELIMITER =#${ENDCHAR}${AWRLINE[@]}${ENDCHAR}"
310 | fi
311 | # Begin processing code - different sections of the report have different handling routines which are enabled through the AWR_SECTION variable
312 |
313 | ################################################################## Searching For Next Section ##################################################################
314 | if [ "$AWR_SECTION" = "SearchingForNextSection" ]; then
315 | # Routine for searching for the start of the next known section and identifying the correct handler routine
316 | # This section is also responsible for correctly settings the Internal Field Seperator prior to entering the next handler routine
317 | case "${AWRLINE[0]:0:40}" in
318 | "Top 5 Timed Events "*)
319 | # Start of the Top 5 Timed Events section found in 10g format AWR reports
320 | echovrb "Start of 10g Top 5 section found at line $ROWCNT"
321 | echodbg "State change AWR_SECTION: $AWR_SECTION -> Top5Foreground"
322 | AWR_SECTION="Top5Foreground"
323 | # There are three more rows of header to skip before processing this section
324 | AWRLINE_SKIP=2
325 | # Reset the bailout counter so that we can search for the header row of this section
326 | BAILOUT_COUNTER=0
327 | # Set Internal Field Seperator to read entire line into single array element
328 | set_ifs_to_line_delimited
329 | continue
330 | ;;
331 | "Top 5 Timed Foreground Events"*)
332 | # Start of the Top 5 Foreground Timed Events section found in 11g format AWR reports
333 | echovrb "Start of 11g Top 5 section found at line $ROWCNT"
334 | echodbg "State change AWR_SECTION: $AWR_SECTION -> Top5Foreground"
335 | AWR_SECTION="Top5Foreground"
336 | # Set Internal Field Seperator to read entire line into single array element
337 | set_ifs_to_line_delimited
338 | # There are five more rows of header to skip before processing this section
339 | AWRLINE_SKIP=4
340 | # Reset the bailout counter so that we can search for the header row of this section
341 | BAILOUT_COUNTER=0
342 | continue
343 | ;;
344 | "Top 10 Foreground Events by Total Wait T")
345 | # Start of the Top 10 Foreground Events section found in newer format 11g and 12c AWR reports
346 | # To process this we use the same handler as the Top 5 Events found in older 10g and 11g reports
347 | echovrb "Start of Top 10 section found at line $ROWCNT"
348 | echodbg "State change AWR_SECTION: $AWR_SECTION -> Top5Foreground"
349 | AWR_SECTION="Top5Foreground"
350 | # Set Internal Field Seperator to read entire line into single array element
351 | set_ifs_to_line_delimited
352 | # There are four more rows of header to skip before processing this section
353 | AWRLINE_SKIP=3
354 | # Reset the bailout counter so that we can search for the header row of this section
355 | BAILOUT_COUNTER=0
356 | continue
357 | ;;
358 | "Cache Sizes"*)
359 | # Start of the Cache Sizes section
360 | echovrb "Start of CacheSizes section found at line $ROWCNT"
361 | echodbg "State change AWR_SECTION: $AWR_SECTION -> CacheSizes"
362 | AWR_SECTION="CacheSizes"
363 | # Set Internal Field Seperator to read each word into a different element of the array
364 | set_ifs_to_word_delimited
365 | # There is one more row of header to skip before processing this section
366 | AWRLINE_SKIP=1
367 | continue
368 | ;;
369 | "Time Model Statistics "*)
370 | # Start of the Time Model Statistics section
371 | echovrb "Start of Time Model Statistics section found at line $ROWCNT"
372 | # We only need information from this section if this is a 10g format AWR Report
373 | if [ "$AWR_FORMAT" != "10" ]; then
374 | echovrb "Ignoring Time Model Statistics because AWR_FORMAT $AWR_FORMAT not 10"
375 | AWRSECTION_SKIP=1
376 | continue
377 | fi
378 | echodbg "State change AWR_SECTION: $AWR_SECTION -> TimeModelStatistics"
379 | AWR_SECTION="TimeModelStatistics"
380 | # Set Internal Field Seperator to read each word into a different element of the array
381 | set_ifs_to_word_delimited
382 | # There are six more rows of header to skip before processing this section
383 | AWRLINE_SKIP=6
384 | continue
385 | ;;
386 | "Operating System Statistics "*)
387 | # Start of the Operating System Statistics section
388 | echovrb "Start of Operating System Stats section found at line $ROWCNT"
389 | echodbg "State change AWR_SECTION: $AWR_SECTION -> OperatingSystemStats"
390 | AWR_SECTION="OperatingSystemStats"
391 | # Set Internal Field Seperator to read each word into a different element of the array
392 | set_ifs_to_word_delimited
393 | # Depending on the AWR format there are more rows of header to skip before processing the Operating System Stats section
394 | if [ "$AWR_FORMAT" = "10" ]; then
395 | AWRLINE_SKIP=2
396 | else
397 | AWRLINE_SKIP=5
398 | fi
399 | continue
400 | ;;
401 | "Wait Class "*)
402 | # If this is not 10g then ignore
403 | if [ "$AWR_FORMAT" != "10" ]; then
404 | echovrb "Ignoring Wait Class header because AWR_FORMAT $AWR_FORMAT not 10"
405 | continue
406 | fi
407 | # Start of Foreground Wait Class section in 10g versions
408 | echovrb "Start of Foreground Wait Class section found at line $ROWCNT"
409 | echodbg "State change AWR_SECTION: $AWR_SECTION -> ForegroundWaitClass"
410 | AWR_SECTION="ForegroundWaitClass"
411 | # Set the FOUND_FG_WAIT_CLASS variable to AWR_FOUND for use with 10g calculation of DB Time in post-processing section
412 | FOUND_FG_WAIT_CLASS=$AWR_FOUND
413 | # Set Internal Field Seperator to read entire line into single array element
414 | set_ifs_to_line_delimited
415 | # There are nine more rows of header to skip before processing the Foreground Wait Class section
416 | AWRLINE_SKIP=7
417 | continue
418 | ;;
419 | "Foreground Wait Class "*)
420 | # Start of Foreground Wait Class section in 11g and 12c versions
421 | echovrb "Start of Foreground Wait Class section found at line $ROWCNT"
422 | echodbg "State change AWR_SECTION: $AWR_SECTION -> ForegroundWaitClass"
423 | AWR_SECTION="ForegroundWaitClass"
424 | # Set Internal Field Seperator to read entire line into single array element
425 | set_ifs_to_line_delimited
426 | # There are nine more rows of header to skip before processing the Foreground Wait Class section
427 | AWRLINE_SKIP=7
428 | continue
429 | ;;
430 | "Wait Events "*)
431 | # Start of the Foreground Wait Events section in 10g versions
432 | echovrb "Start of Foreground Wait Events section found at line $ROWCNT"
433 | echodbg "State change AWR_SECTION: $AWR_SECTION -> ForegroundWaitEvents"
434 | AWR_SECTION="ForegroundWaitEvents"
435 | # Set Internal Field Seperator to read entire line into single array element
436 | set_ifs_to_line_delimited
437 | # There are nine more rows of header to skip before processing the Foreground Wait Class section
438 | AWRLINE_SKIP=3
439 | # Reset the bailout counter so that we can search for the header row of this section
440 | BAILOUT_COUNTER=0
441 | continue
442 | ;;
443 | "Foreground Wait Events "*)
444 | # Start of the Foreground Wait Events section in versions later than 10g
445 | echovrb "Start of Foreground Wait Events section found at line $ROWCNT"
446 | echodbg "State change AWR_SECTION: $AWR_SECTION -> ForegroundWaitEvents"
447 | AWR_SECTION="ForegroundWaitEvents"
448 | # Set Internal Field Seperator to read entire line into single array element
449 | set_ifs_to_line_delimited
450 | # There are eight more rows of header to skip before processing the Foreground Wait Class section
451 | AWRLINE_SKIP=3
452 | # Reset the bailout counter so that we can search for the header row of this section
453 | BAILOUT_COUNTER=0
454 | continue
455 | ;;
456 | "Background Wait Events "*)
457 | # Start of the Background Wait Events section
458 | echovrb "Start of Background Wait Events section found at line $ROWCNT"
459 | echodbg "State change AWR_SECTION: $AWR_SECTION -> BackgroundWaitEvents"
460 | AWR_SECTION="BackgroundWaitEvents"
461 | # Set Internal Field Seperator to read entire line into single array element
462 | set_ifs_to_line_delimited
463 | # Depending on the AWR format there are more rows of header to skip before processing the Background Wait Events section
464 | AWRLINE_SKIP=3
465 | # Reset the bailout counter so that we can search for the header row of this section
466 | BAILOUT_COUNTER=0
467 | continue
468 | ;;
469 | "Wait Event Histogram "*)
470 | # Start of the Wait Event Histogram section
471 | echovrb "Start of Wait Event Histogram section found at line $ROWCNT"
472 | echodbg "State change AWR_SECTION: $AWR_SECTION -> WaitEventHistogram"
473 | AWR_SECTION="WaitEventHistogram"
474 | # Set Internal Field Seperator to read entire line into single array element
475 | set_ifs_to_line_delimited
476 | # Depending on the AWR format there are more rows of header to skip before processing the Background Wait Events section
477 | AWRLINE_SKIP=8
478 | # Reset the bailout counter so that we can search for the header row of this section
479 | BAILOUT_COUNTER=0
480 | continue
481 | ;;
482 | "Instance Activity Stats "*)
483 | # Start of the Instance Activity Stats section in 10g and 11g format AWR reports
484 | echovrb "Start of Instance Activity Stats section found at line $ROWCNT"
485 | echodbg "State change AWR_SECTION: $AWR_SECTION -> InstanceActivityStats"
486 | AWR_SECTION="InstanceActivityStats"
487 | # Set Internal Field Seperator to read entire line into single array element
488 | set_ifs_to_line_delimited
489 | # Depending on the AWR format there are more rows of header to skip before processing the Instance Activity Stats section
490 | if [ "$AWR_FORMAT" = "10" ]; then
491 | AWRLINE_SKIP=2
492 | else
493 | AWRLINE_SKIP=3
494 | fi
495 | continue
496 | ;;
497 | "SQL ordered by"*)
498 | # One of the SQL sections - these should be ignored because punctuation characters in SQL can cause problems
499 | echodbg "Found start of SQL ordered by section at line $ROWCNT - setting AWRSECTION_SKIP"
500 | # There are eight more rows of header to skip before processing the Foreground Wait Class section
501 | let AWRSECTION_SKIP++
502 | continue
503 | ;;
504 | "Other Instance Activity Stats "*)
505 | # Start of the Other Instance Activity Stats section in 12c format AWR reports
506 | # Use the normal Instance Activity Stats handler
507 | echovrb "Start of Other Instance Activity Stats section found at line $ROWCNT"
508 | echodbg "State change AWR_SECTION: $AWR_SECTION -> InstanceActivityStats"
509 | AWR_SECTION="InstanceActivityStats"
510 | # Set Internal Field Seperator to read entire line into single array element
511 | set_ifs_to_line_delimited
512 | # Depending on the AWR format there are more rows of header to skip before processing the Instance Activity Stats section
513 | AWRLINE_SKIP=3
514 | continue
515 | ;;
516 | "Instance Activity Stats - Thread Activit")
517 | # Start of the Instance Activity Stats - Thread Activity section which contains the Log Switches information
518 | echovrb "Start of Instance Activity Stats - Thread Activity section found at line $ROWCNT"
519 | echodbg "State change AWR_SECTION: $AWR_SECTION -> ThreadActivity"
520 | AWR_SECTION="ThreadActivity"
521 | # Set Internal Field Seperator to read each word into a different element of the array
522 | set_ifs_to_word_delimited
523 | # Depending on the AWR format there are more rows of header to skip before processing the Instance Activity Stats section
524 | AWRLINE_SKIP=3
525 | continue
526 | ;;
527 | esac
528 |
529 | # If we make it here, we are searching for the start of a new section and haven't found it, so move on to next line
530 | continue
531 | fi
532 |
533 | ################################################################## AWR Profile Section ##################################################################
534 | if [ "$AWR_SECTION" = "AWRProfile" ]; then
535 | # Routine for handling the AWR Profile section of the report
536 | if [ "$FOUND_SYS_DETAILS" = "$AWR_PENDING" ]; then
537 | # This line contains the database system details
538 | FOUND_SYS_DETAILS=$AWR_FOUND
539 | # Extract data
540 | PROFILE_DBNAME=${AWRLINE[0]}
541 | PROFILE_INSTANCENAME=${AWRLINE[2]}
542 | PROFILE_INSTANCENUM=${AWRLINE[3]}
543 | if [ "$AWR_FORMAT" = "10" ]; then
544 | PROFILE_DBVERSION=${AWRLINE[4]}
545 | PROFILE_CLUSTER=$(echo ${AWRLINE[5]} | cut -c1-1)
546 | if [ -n "${AWRLINE[6]}" ]; then
547 | # AWR reports in Oracle version 10 have the hostname at the end of the DB details line
548 | # The call to tr is necessary to remove the trailing return character
549 | DB_HOSTNAME=$(echo ${AWRLINE[6]} | tr -d '\r')
550 | DB_HOST_OS="Unknown"
551 | else
552 | echovrb "Unable to find Hostname at end of System Details section"
553 | fi
554 | echodbg "Sys Details: DBName=$PROFILE_DBNAME, InstName=$PROFILE_INSTANCENAME, InstNum=$PROFILE_INSTANCENUM, Ver=$PROFILE_DBVERSION, Cluster=$PROFILE_CLUSTER, Hostname=$DB_HOSTNAME, OS=$DB_HOST_OS"
555 | else
556 | PROFILE_DBVERSION=${AWRLINE[6]}
557 | PROFILE_CLUSTER=$(echo ${AWRLINE[7]} | cut -c1-1)
558 | echodbg "Sys Details: DBName=$PROFILE_DBNAME, InstName=$PROFILE_INSTANCENAME, InstNum=$PROFILE_INSTANCENUM, Ver=$PROFILE_DBVERSION, Cluster=$PROFILE_CLUSTER"
559 | fi
560 | continue
561 | elif [ "$FOUND_HOST_DETAILS" = "$AWR_PENDING" ]; then
562 | # This line contains the host system details
563 | FOUND_HOST_DETAILS=$AWR_FOUND
564 | # Call function to extract data
565 | DB_HOSTNAME=$(echo "${AWRLINE[0]}"| cut -c1-16|sed -e 's/^[ \t]*//;s/[ \t]*$//')
566 | DB_HOST_OS=$(echo "${AWRLINE[0]}"| cut -c17-49|sed -e 's/^[ \t]*//;s/[ \t]*$//')
567 | DB_HOST_MEM=$(echo "${AWRLINE[0]}"| cut -c69-79|sed -e 's/^[ \t]*//;s/[ \t]*$//')
568 | echodbg "Host Details: Hostname=$DB_HOSTNAME, OS=$DB_HOST_OS, HostMem=$DB_HOST_MEM"
569 | # Return Internal Field Seperator to reading each word into a different array element
570 | set_ifs_to_word_delimited
571 | continue
572 | fi
573 |
574 | # Examine first two words
575 | case ${AWRLINE[@]:0:2} in
576 | "DB Name")
577 | # Found Database System Details
578 | [[ "$FOUND_SYS_DETAILS" = "$AWR_FOUND" ]] && continue
579 | echovrb "Start of Database System details at line $ROWCNT"
580 | # AWR reports from 11g on have an extra "Startup Time" column in the profile
581 | if [ "${AWRLINE[@]:7:1}" = "Startup" ]; then
582 | AWR_FORMAT=11
583 | # Later on we will discover if it is actually a 12c report rather than 11g as we assume initially
584 | else
585 | # Assume this is version 10 format
586 | AWR_FORMAT=10
587 | fi
588 | echovrb "Using AWR Format $AWR_FORMAT"
589 | # Skip next line as this is part of the header
590 | AWRLINE_SKIP=1
591 | FOUND_SYS_DETAILS=$AWR_PENDING
592 | continue
593 | ;;
594 | "Host Name")
595 | # Found Host System Details
596 | [[ "$FOUND_HOST_DETAILS" = "$AWR_FOUND" ]] && continue
597 | echovrb "Start of Host System details at line $ROWCNT"
598 | # Skip next line as this is part of the header
599 | AWRLINE_SKIP=1
600 | FOUND_HOST_DETAILS=$AWR_PENDING
601 | # Set Internal Field Seperator to read full line into first array element
602 | set_ifs_to_line_delimited
603 | continue
604 | ;;
605 | "Begin Snap:")
606 | # Found details for start of snapshot
607 | AWR_BEGIN_SNAP=${AWRLINE[2]}
608 | AWR_BEGIN_TIME="${AWRLINE[3]} ${AWRLINE[4]}"
609 | echodbg "AWR_BEGIN_SNAP = ${ENDCHAR}$AWR_BEGIN_SNAP${ENDCHAR}"
610 | echodbg "AWR_BEGIN_TIME = ${ENDCHAR}$AWR_BEGIN_TIME${ENDCHAR}"
611 | continue
612 | ;;
613 | "End Snap:")
614 | # Found details for end of snapshot
615 | AWR_END_SNAP=${AWRLINE[2]}
616 | AWR_END_TIME="${AWRLINE[3]} ${AWRLINE[4]}"
617 | echodbg "AWR_END_SNAP = ${ENDCHAR}$AWR_END_SNAP${ENDCHAR}"
618 | echodbg "AWR_END_TIME = ${ENDCHAR}$AWR_END_TIME${ENDCHAR}"
619 | continue
620 | ;;
621 | "Elapsed:"*)
622 | # Found details for elapsed time
623 | AWR_ELAPSED_TIME=$(echo ${AWRLINE[1]} |sed -e 's/,//g')
624 | echodbg "AWR_ELAPSED_TIME = ${ENDCHAR}$AWR_ELAPSED_TIME${ENDCHAR}"
625 | # Calculate elapsed time in seconds for use when working out throughput values
626 | if [ -n "$AWR_ELAPSED_TIME" ]; then
627 | if [ "$AWR_ELAPSED_TIME" = 0 ]; then
628 | echovrb "Found zero value for AWR_ELAPSED_TIME"
629 | AWR_ELAPSED_TIME_SECS=0
630 | else
631 | echodbg "Calling BC: echo 'scale=3; $AWR_ELAPSED_TIME * 60' | bc -l"
632 | AWR_ELAPSED_TIME_SECS=`echo "scale=3; $AWR_ELAPSED_TIME * 60" | bc -l`
633 | fi
634 | echodbg "AWR_ELAPSED_TIME_SECS = ${ENDCHAR}$AWR_ELAPSED_TIME_SECS${ENDCHAR}"
635 | continue
636 | fi
637 | ;;
638 | "DB Time:")
639 | # Found details for DB time
640 | AWR_DB_TIME=$(echo ${AWRLINE[2]} |sed -e 's/,//g')
641 | echodbg "AWR_DB_TIME = ${ENDCHAR}$AWR_DB_TIME${ENDCHAR}"
642 | # If Elapsed Time known then calculate Average Active Sessions (AAS)
643 | if [ -n "$AWR_ELAPSED_TIME" ]; then
644 | if [ "$AWR_ELAPSED_TIME" = 0 ]; then
645 | echoinf "Cannot calculate Average Active Sessions due to zero AWR_ELAPSED_TIME value"
646 | else
647 | echodbg "Calling BC: AWR_AAS=echo 'scale=1; $AWR_DB_TIME / $AWR_ELAPSED_TIME' | bc -l"
648 | AWR_AAS=`echo "scale=1; $AWR_DB_TIME / $AWR_ELAPSED_TIME" | bc -l`
649 | fi
650 | else
651 | echoinf "Found DB Time but not Elapsed Time - unable to calculate Average Active Sessions"
652 | fi
653 | echodbg "AWR_ELAPSED_TIME = ${ENDCHAR}$AWR_ELAPSED_TIME${ENDCHAR}"
654 | continue
655 | ;;
656 | "Buffer Cache:")
657 | # Found Cache Sizes section containing database block size
658 | # The call to tr is necessary to remove the trailing return character
659 | DB_BLOCK_SIZE=$(echo ${AWRLINE[${#AWRLINE[@]}-1]} | tr -d '\r')
660 | echodbg "DB_BLOCK_SIZE = ${ENDCHAR}$DB_BLOCK_SIZE${ENDCHAR}"
661 | continue
662 | ;;
663 | "Redo size:")
664 | # Found details for redo bytes per second in the 10g and 11g format AWR reports
665 | # Because this number is occasionally very large Oracle may print it in scientific notation so we have to convert this if neccessary
666 | REDO_WRITE_THROUGHPUT=$(echo ${AWRLINE[2]} |sed -e 's/,//g'| sed -e 's/E+/\*10\^/')
667 | # Convert to MB/sec
668 | if [ -n "$REDO_WRITE_THROUGHPUT" ]; then
669 | if [ "$REDO_WRITE_THROUGHPUT" != 0 ]; then
670 | echodbg "Calling BC: REDO_WRITE_THROUGHPUT=echo 'scale=2; (\$(echo 'scale=6; $REDO_WRITE_THROUGHPUT / 1048576' | bc -l)+0.005)/1' | bc -l"
671 | REDO_WRITE_THROUGHPUT=`echo "scale=2; ($(echo "scale=6; $REDO_WRITE_THROUGHPUT / 1048576" | bc -l)+0.005)/1" | bc -l`
672 | fi
673 | fi
674 | echodbg "REDO_WRITE_THROUGHPUT = ${ENDCHAR}${REDO_WRITE_THROUGHPUT}${ENDCHAR}"
675 | continue
676 | ;;
677 | "Redo size")
678 | # Found details for redo bytes per second in the 12c format AWR reports
679 | # Because this number is occasionally very large Oracle may print it in scientific notation so we have to convert this if neccessary
680 | REDO_WRITE_THROUGHPUT=$(echo ${AWRLINE[3]} |sed -e 's/,//g'| sed -e 's/E+/\*10\^/')
681 | # Convert to MB/sec
682 | if [ -n "$REDO_WRITE_THROUGHPUT" ]; then
683 | if [ "$REDO_WRITE_THROUGHPUT" != 0 ]; then
684 | echodbg "Calling BC: REDO_WRITE_THROUGHPUT=echo 'scale=2; (\$(echo 'scale=6; $REDO_WRITE_THROUGHPUT / 1048576' | bc -l)+0.005)/1' | bc -l"
685 | REDO_WRITE_THROUGHPUT=`echo "scale=2; ($(echo "scale=6; $REDO_WRITE_THROUGHPUT / 1048576" | bc -l)+0.005)/1" | bc -l`
686 | fi
687 | fi
688 | echodbg "REDO_WRITE_THROUGHPUT = ${ENDCHAR}${REDO_WRITE_THROUGHPUT}${ENDCHAR}"
689 | # We now know that this is a 12c format AWR report so update the AWR_FORMAT variable accordingly
690 | AWR_FORMAT=12
691 | echovrb "Amending AWR Format to $AWR_FORMAT"
692 | # Amend the section terminator variables accordingly
693 | AWR_SECTION_TERMINATOR_BY_WORD="$NEW_AWR_SECTION_TERMINATOR_BY_WORD"
694 | AWR_SECTION_TERMINATOR_BY_LINE="$NEW_AWR_SECTION_TERMINATOR_BY_LINE"
695 | continue
696 | ;;
697 | "Logical reads:")
698 | # Found details for logical reads per second in the 10g and 11g format AWR reports
699 | AWR_LOGICAL_READS=$(echo ${AWRLINE[2]} |sed -e 's/,//g')
700 | echodbg "AWR_LOGICAL_READS = ${ENDCHAR}${AWR_LOGICAL_READS}${ENDCHAR}"
701 | continue
702 | ;;
703 | "Logical read")
704 | # Found details for logical reads per second in the 12c format AWR reports
705 | AWR_LOGICAL_READS=$(echo ${AWRLINE[3]} |sed -e 's/,//g')
706 | echodbg "AWR_LOGICAL_READS = ${ENDCHAR}${AWR_LOGICAL_READS}${ENDCHAR}"
707 | continue
708 | ;;
709 | "Block changes:")
710 | # Found details for block changes per second
711 | AWR_BLOCK_CHANGES=$(echo ${AWRLINE[2]} |sed -e 's/,//g')
712 | echodbg "AWR_BLOCK_CHANGES = ${ENDCHAR}${AWR_BLOCK_CHANGES}${ENDCHAR}"
713 | continue
714 | ;;
715 | "User calls:")
716 | # Found details for user calls per second
717 | AWR_USER_CALLS=$(echo ${AWRLINE[2]} |sed -e 's/,//g')
718 | echodbg "AWR_USER_CALLS = ${ENDCHAR}${AWR_USER_CALLS}${ENDCHAR}"
719 | continue
720 | ;;
721 | "Parses:"*)
722 | # Found details for parses per second in the 10g and 11g format AWR reports
723 | AWR_PARSES=$(echo ${AWRLINE[1]} |sed -e 's/,//g')
724 | echodbg "AWR_PARSES = ${ENDCHAR}${AWR_PARSES}${ENDCHAR}"
725 | continue
726 | ;;
727 | "Parses"*)
728 | # Found details for parses per second in the 12c format AWR reports
729 | AWR_PARSES=$(echo ${AWRLINE[2]} |sed -e 's/,//g')
730 | echodbg "AWR_PARSES = ${ENDCHAR}${AWR_PARSES}${ENDCHAR}"
731 | continue
732 | ;;
733 | "Hard parses:")
734 | # Found details for hard parses per second in the 10g and 11g format AWR reports
735 | AWR_HARD_PARSES=$(echo ${AWRLINE[2]} |sed -e 's/,//g')
736 | echodbg "AWR_HARD_PARSES = ${ENDCHAR}${AWR_HARD_PARSES}${ENDCHAR}"
737 | continue
738 | ;;
739 | "Hard parses")
740 | # Found details for hard parses per second in the 12c format AWR reports
741 | AWR_HARD_PARSES=$(echo ${AWRLINE[3]} |sed -e 's/,//g')
742 | echodbg "AWR_HARD_PARSES = ${ENDCHAR}${AWR_HARD_PARSES}${ENDCHAR}"
743 | continue
744 | ;;
745 | "Logons:"*)
746 | # Found details for logons per second
747 | AWR_LOGONS=$(echo ${AWRLINE[1]} |sed -e 's/,//g')
748 | echodbg "AWR_LOGONS = ${ENDCHAR}${AWR_LOGONS}${ENDCHAR}"
749 | continue
750 | ;;
751 | "Executes:"*)
752 | # Found details for executes per second in the 10g and 11g format AWR reports
753 | AWR_EXECUTES=$(echo ${AWRLINE[1]} |sed -e 's/,//g')
754 | echodbg "AWR_EXECUTES = ${ENDCHAR}${AWR_EXECUTES}${ENDCHAR}"
755 | continue
756 | ;;
757 | "Executes"*)
758 | # Found details for executes per second in the 12c format AWR reports
759 | AWR_EXECUTES=$(echo ${AWRLINE[2]} |sed -e 's/,//g')
760 | echodbg "AWR_EXECUTES = ${ENDCHAR}${AWR_EXECUTES}${ENDCHAR}"
761 | continue
762 | ;;
763 | "Transactions:"*)
764 | # Found details for transactions per second
765 | # The call to tr is necessary to remove the trailing return character
766 | AWR_TRANSACTIONS=$(echo ${AWRLINE[1]} |sed -e 's/,//g' | tr -d '\r')
767 | echodbg "AWR_TRANSACTIONS = ${ENDCHAR}${AWR_TRANSACTIONS}${ENDCHAR}"
768 | continue
769 | ;;
770 | "Buffer Hit")
771 | # Found buffer hit and in-memory sort ratios
772 | BUFFER_HIT_RATIO=${AWRLINE[3]}
773 | echodbg "BUFFER_HIT_RATION = ${ENDCHAR}${BUFFER_HIT_RATION}${ENDCHAR}"
774 | # The call to tr is necessary to remove the trailing return character
775 | INMEMORY_SORT_RATIO=$(echo ${AWRLINE[7]} | tr -d '\r')
776 | echodbg "INMEMORY_SORT_RATIO = ${ENDCHAR}${INMEMORY_SORT_RATIO}${ENDCHAR}"
777 | continue
778 | ;;
779 | "Instance Efficiency")
780 | # End of AWR Profile section
781 | echovrb "End of AWR Profile section found at line $ROWCNT"
782 | echodbg "State change AWR_SECTION: $AWR_SECTION -> InstanceEfficiency"
783 | AWR_SECTION="InstanceEfficiency"
784 | # Set Internal Field Seperator to read each word into a different element of the array
785 | set_ifs_to_word_delimited
786 | # Skip the following row which is a header
787 | AWRLINE_SKIP=1
788 | continue
789 | ;;
790 | esac
791 | continue
792 | fi # End of handler routine for profile section of AWR report
793 |
794 | ################################################################## Instance Efficiency ##################################################################
795 | if [ "$AWR_SECTION" = "InstanceEfficiency" ]; then
796 | # Routine for handling the Instance Efficiency section of the report
797 | # Examine two words
798 | case ${AWRLINE[@]:0:2} in
799 | "Buffer Hit")
800 | # Found buffer hit and in-memory sort ratios
801 | BUFFER_HIT_RATIO=${AWRLINE[3]}
802 | echodbg "BUFFER_HIT_RATIO = ${ENDCHAR}${BUFFER_HIT_RATIO}${ENDCHAR}"
803 | # The call to tr is necessary to remove the trailing return character
804 | INMEMORY_SORT_RATIO=$(echo ${AWRLINE[7]} | tr -d '\r')
805 | echodbg "INMEMORY_SORT_RATIO = ${ENDCHAR}${INMEMORY_SORT_RATIO}${ENDCHAR}"
806 | echovrb "End of Instance Efficiency section found at line $ROWCNT"
807 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
808 | AWR_SECTION="SearchingForNextSection"
809 | # Switch Internal Field Seperator to only recognise newlines as delimiters
810 | set_ifs_to_line_delimited
811 | continue
812 | ;;
813 | *)
814 | # Catch all other lines and ignore
815 | continue
816 | ;;
817 | esac
818 | fi
819 |
820 | ################################################################## Top 5 Foreground Events ##################################################################
821 | if [ "$AWR_SECTION" = "Top5Foreground" ]; then
822 | # Routine for handling the Top 5 section of the report
823 | if [ "$FOUND_TOP5_EVENTS" = "$AWR_NOTFOUND" ]; then
824 | # We have just begun processing the Top 5 section so first we need to discover the header row (a set of dashes showing the column headings)
825 | if [ "${AWRLINE[0]:0:6}" = "------" ]; then
826 | echodbg "Searching for header row... found"
827 | FOUND_TOP5_EVENTS=$AWR_FOUND
828 | process_header_row "${AWRLINE[0]}"
829 | if [ "$PROCESS_HEADER_ROW" != "SUCCESS" ]; then
830 | echovrb "Unable to determine width of rows in Top 5 / Top 10 Foreground Events section"
831 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
832 | AWR_SECTION="SearchingForNextSection"
833 | # Switch Internal Field Seperator to only recognise newlines as delimiters
834 | set_ifs_to_line_delimited
835 | # Give up trying to process this section
836 | if [ "$AWR_FORMAT" = "12" ]; then
837 | AWRLINE_SKIP=10
838 | else
839 | AWRLINE_SKIP=5
840 | fi
841 | fi
842 | else
843 | let BAILOUT_COUNTER++
844 | if [ "$BAILOUT_COUNTER" -eq "$BAILOUT_LIMIT" ]; then
845 | echodbg "Failed to find header row (BAILOUT_COUNTER hit threshold = $BAILOUT_COUNTER)"
846 | echovrb "Unable to determine width of rows in Top 5 / Top 10 Foreground Events section"
847 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
848 | AWR_SECTION="SearchingForNextSection"
849 | # Switch Internal Field Seperator to only recognise newlines as delimiters
850 | set_ifs_to_line_delimited
851 | # Give up trying to process this section
852 | if [ "$AWR_FORMAT" = "12" ]; then
853 | AWRLINE_SKIP=10
854 | else
855 | AWRLINE_SKIP=5
856 | fi
857 | else
858 | echodbg "Searching for header row... not found (BAILOUT_COUNTER = $BAILOUT_COUNTER)"
859 | fi
860 | fi
861 | continue
862 | else
863 | # Start processing the Top 5 section
864 | let TOP5_LINENUM++
865 | # If we are past the fifth line of the Top 5 then the section is over so exit the section handler
866 | # For the Top 10 sections in 12c format reports we do not care about events above the top 5
867 | if [ "$TOP5_LINENUM" -gt "5" ]; then
868 | # End of Top 5 section
869 | echovrb "End of Top 5 section found at line $ROWCNT"
870 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
871 | AWR_SECTION="SearchingForNextSection"
872 | # Switch Internal Field Seperator to only recognise newlines as delimiters
873 | set_ifs_to_line_delimited
874 | continue
875 | fi
876 | fi
877 |
878 | # The variables AWRCOLn are set in the process_header_row function call in the preceding if statement
879 | if [ "${AWRLINE[0]:0:6}" = "DB CPU" -o "${AWRLINE[0]:0:6}" = "CPU tim" ]; then
880 | # This is the DB CPU line which has a different format to the rest
881 | echodbg "Top 5 line $TOP5_LINENUM is DB CPU"
882 | TOP5EVENT_NAME="DB CPU"
883 | TOP5EVENT_WAITS=""
884 | TOP5EVENT_TIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL3}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
885 | TOP5EVENT_AVERAGE=""
886 | TOP5EVENT_PCT_DBTIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL5}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
887 | TOP5EVENT_CLASS=""
888 | else
889 | # This is a normal Top 5 line so handle accordingly
890 | TOP5EVENT_NAME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL1}|sed -e 's/^[ \t]*//;s/[ \t]*$//')
891 | TOP5EVENT_WAITS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL2}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
892 | TOP5EVENT_TIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL3}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
893 | TOP5EVENT_AVERAGE=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL4}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
894 | TOP5EVENT_PCT_DBTIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL5}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
895 | TOP5EVENT_CLASS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL6}|sed -e 's/^[ \t]*//;s/[ \t]*$//')
896 |
897 | if [ -n "$TOP5EVENT_WAITS" ]; then
898 | # Check the values extracted are valid numbers
899 | if [[ "$TOP5EVENT_TIME" != *[!0-9,.]* ]]; then
900 | if [[ "$TOP5EVENT_WAITS" != *[!0-9,]* ]]; then
901 | if [ "$TOP5EVENT_WAITS" = 0 ]; then
902 | echovrb "Found zero waits for Top 5 wait event $TOP5EVENT_NAME"
903 | else
904 | # See comments in header section for explanation of the way bc is used in calculating the average on the next lines
905 | echodbg "Calling BC: TOP5EVENT_AVERAGE=echo 'scale=3; (\$(echo 'scale=7; ($TOP5EVENT_TIME / $TOP5EVENT_WAITS) * 1000' | bc -l)+0.0005)/1' | bc -l"
906 | TOP5EVENT_AVERAGE=`echo "scale=3; ($(echo "scale=7; ($TOP5EVENT_TIME / $TOP5EVENT_WAITS) * 1000" | bc -l)+0.0005)/1" | bc -l`
907 | fi
908 | else
909 | echodbg "Unable to parse Top 5 wait event $TOP5EVENT_NAME due to non-numeric string found in TOP5EVENT_WAITS: $TOP5EVENT_WAITS"
910 | fi
911 | else
912 | echodbg "Unable to parse Top 5 wait event $TOP5EVENT_NAME due to non-numeric string found in TOP5EVENT_TIME: $TOP5EVENT_TIME"
913 | fi
914 | fi
915 | fi
916 | echodbg "Top 5 Line $TOP5_LINENUM: Name=$TOP5EVENT_NAME, Waits=$TOP5EVENT_WAITS, Time=$TOP5EVENT_TIME, Ave=$TOP5EVENT_AVERAGE, PctDBTime=$TOP5EVENT_PCT_DBTIME, Class=$TOP5EVENT_CLASS"
917 |
918 | # Now place discovered values into the correct array of variables based on TOP5_LINENUM
919 | #echodbg "eval TOP5EVENT${TOP5_LINENUM}_NAME='$TOP5EVENT_NAME'"
920 | eval TOP5EVENT${TOP5_LINENUM}_NAME='$TOP5EVENT_NAME'
921 | #echodbg "eval TOP5EVENT${TOP5_LINENUM}_NAME='$TOP5EVENT_WAITS'"
922 | eval TOP5EVENT${TOP5_LINENUM}_WAITS='$TOP5EVENT_WAITS'
923 | #echodbg "eval TOP5EVENT${TOP5_LINENUM}_NAME='$TOP5EVENT_TIME'"
924 | eval TOP5EVENT${TOP5_LINENUM}_TIME='$TOP5EVENT_TIME'
925 | #echodbg "eval TOP5EVENT${TOP5_LINENUM}_NAME='$TOP5EVENT_AVERAGE'"
926 | eval TOP5EVENT${TOP5_LINENUM}_AVERAGE='$TOP5EVENT_AVERAGE'
927 | #echodbg "eval TOP5EVENT${TOP5_LINENUM}_NAME='$TOP5EVENT_PCT_DBTIME'"
928 | eval TOP5EVENT${TOP5_LINENUM}_PCT_DBTIME='$TOP5EVENT_PCT_DBTIME'
929 | #echodbg "eval TOP5EVENT${TOP5_LINENUM}_NAME='$TOP5EVENT_CLASS'"
930 | eval TOP5EVENT${TOP5_LINENUM}_CLASS='$TOP5EVENT_CLASS'
931 |
932 | fi # End of handler routine for Top 5 section of AWR report
933 |
934 | ################################################################## Cache Sizes ##################################################################
935 | if [ "$AWR_SECTION" = "CacheSizes" ]; then
936 | # Routine for handling the Cache Sizes section of the report - only called with 12c format reports
937 | # Examine two words
938 | case ${AWRLINE[@]:0:2} in
939 | "Buffer Cache:")
940 | # Found Cache Sizes section containing database block size
941 | # The call to tr is necessary to remove the trailing return character
942 | DB_BLOCK_SIZE=$(echo ${AWRLINE[${#AWRLINE[@]}-1]} | tr -d '\r')
943 | echodbg "DB_BLOCK_SIZE = ${ENDCHAR}$DB_BLOCK_SIZE${ENDCHAR}"
944 | continue
945 | ;;
946 | "Shared Pool"*)
947 | # End of Cache Sizes section
948 | echovrb "End of Cache Sizes section found at line $ROWCNT"
949 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
950 | AWR_SECTION="SearchingForNextSection"
951 | # Switch Internal Field Seperator to only recognise newlines as delimiters
952 | set_ifs_to_line_delimited
953 | ;;
954 | *)
955 | # Catch all other lines and ignore
956 | continue
957 | ;;
958 | esac
959 | fi
960 |
961 | ################################################################## Time Model Statistics ##################################################################
962 | if [ "$AWR_SECTION" = "TimeModelStatistics" ]; then
963 | # Routine for handling the Time Model Statistics section of the report (only called for reports in 10g format)
964 | # Examine first two words
965 | case ${AWRLINE[@]:0:2} in
966 | "DB CPU")
967 | # Remember to strip out carriage returns and commas
968 | AWR_DB_CPU=$(echo "${AWRLINE[2]}" | tr -d '\r,')
969 | AWR_DB_CPU_PCT_DBTIME=$(echo "${AWRLINE[3]}" | tr -d '\r,')
970 | echodbg "AWR_DB_CPU = ${ENDCHAR}${AWR_DB_CPU}${ENDCHAR}"
971 | echodbg "AWR_DB_CPU_PCT_DBTIME = ${ENDCHAR}${AWR_DB_CPU_PCT_DBTIME}${ENDCHAR}"
972 | ;;
973 | *)
974 | # Ignore other lines
975 | continue
976 | esac
977 | continue
978 | fi
979 |
980 | ################################################################## Operating System Stats ##################################################################
981 | if [ "$AWR_SECTION" = "OperatingSystemStats" ]; then
982 | # Routine for handling the Operating System Stats section of the report
983 | # Examine first word
984 | case ${AWRLINE[@]:0:1} in
985 | "BUSY_TIME")
986 | # Remember to strip out carriage returns and commas
987 | OS_BUSY_TIME=$(echo "${AWRLINE[1]}" | tr -d '\r,')
988 | echodbg "OS_BUSY_TIME = ${ENDCHAR}${OS_BUSY_TIME}${ENDCHAR}"
989 | ;;
990 | "IDLE_TIME")
991 | # Remember to strip out carriage returns and commas
992 | OS_IDLE_TIME=$(echo "${AWRLINE[1]}" | tr -d '\r,')
993 | echodbg "OS_IDLE_TIME = ${ENDCHAR}${OS_IDLE_TIME}${ENDCHAR}"
994 | ;;
995 | "IOWAIT_TIME")
996 | # Remember to strip out carriage returns and commas
997 | OS_IOWAIT_TIME=$(echo "${AWRLINE[1]}" | tr -d '\r,')
998 | echodbg "OS_IOWAIT_TIME = ${ENDCHAR}${OS_IOWAIT_TIME}${ENDCHAR}"
999 | ;;
1000 | "SYS_TIME")
1001 | # Remember to strip out carriage returns and commas
1002 | OS_SYS_TIME=$(echo "${AWRLINE[1]}" | tr -d '\r,')
1003 | echodbg "OS_SYS_TIME = ${ENDCHAR}${OS_SYS_TIME}${ENDCHAR}"
1004 | ;;
1005 | "USER_TIME")
1006 | # Remember to strip out carriage returns and commas
1007 | OS_USER_TIME=$(echo "${AWRLINE[1]}" | tr -d '\r,')
1008 | echodbg "OS_USER_TIME = ${ENDCHAR}${OS_USER_TIME}${ENDCHAR}"
1009 | ;;
1010 | "OS_CPU_WAIT_TIME")
1011 | # Remember to strip out carriage returns and commas
1012 | OS_CPU_WAIT_TIME=$(echo "${AWRLINE[1]}" | tr -d '\r,')
1013 | echodbg "OS_CPU_WAIT_TIME = ${ENDCHAR}${OS_CPU_WAIT_TIME}${ENDCHAR}"
1014 | ;;
1015 | "RSRC_MGR_CPU_WAIT_TIME")
1016 | # Remember to strip out carriage returns and commas
1017 | OS_RSRC_MGR_WAIT_TIME=$(echo "${AWRLINE[1]}" | tr -d '\r,')
1018 | echodbg "OS_RSRC_MGR_WAIT_TIME = ${ENDCHAR}${OS_RSRC_MGR_WAIT_TIME}${ENDCHAR}"
1019 | ;;
1020 | "PHYSICAL_MEMORY_BYTES")
1021 | # Reports in 10g format to not show server memory in header section
1022 | if [ "$AWR_FORMAT" = "10" ]; then
1023 | # Convert from bytes to GB remembering to strip out carriage returns and commas
1024 | echodbg "Calling BC: DB_HOST_MEM=echo \"scale=3; $(echo ${AWRLINE[1]} | tr -d '\r,') / 1073741824\" | bc -l"
1025 | DB_HOST_MEM=`echo "scale=3; $(echo ${AWRLINE[1]} | tr -d '\r,') / 1073741824" | bc -l`
1026 | echodbg "DB_HOST_MEM = ${ENDCHAR}${DB_HOST_MEM}${ENDCHAR}"
1027 | fi
1028 | ;;
1029 | "NUM_CPUS")
1030 | # Remember to strip out carriage returns and commas
1031 | DB_NUM_CPUS=$(echo "${AWRLINE[1]}" | tr -d '\r,')
1032 | echodbg "DB_NUM_CPUS = ${ENDCHAR}${DB_NUM_CPUS}${ENDCHAR}"
1033 | ;;
1034 | *)
1035 | # Ignore other lines
1036 | continue
1037 | esac
1038 | continue
1039 | fi
1040 |
1041 | ################################################################## Foreground Wait Class ##################################################################
1042 | if [ "$AWR_SECTION" = "ForegroundWaitClass" ]; then
1043 | # Routine for handling the Foreground Wait Class section of the report
1044 | # For 10g AWR format this includes a tracker for totalling wait time in order to calculate DB CPU
1045 | case ${AWRLINE[0]:0:20} in
1046 | "Wait Class"*)
1047 | # Still in the header so ignore and carry on to the next line
1048 | echodbg "Still in section header - ignore"
1049 | continue
1050 | ;;
1051 | "--------"*)
1052 | # The header row - call process_header_row function to find widths of columns
1053 | process_header_row "${AWRLINE[0]}"
1054 | if [ "$PROCESS_HEADER_ROW" != "SUCCESS" ]; then
1055 | echovrb "Unable to determine width of rows in Foreground Wait Class section"
1056 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
1057 | AWR_SECTION="SearchingForNextSection"
1058 | # Switch Internal Field Seperator to only recognise newlines as delimiters
1059 | set_ifs_to_line_delimited
1060 | # Give up trying to process this section
1061 | let AWRSECTION_SKIP++
1062 | fi
1063 | continue
1064 | ;;
1065 | "DB CPU"*)
1066 | # This string will only be found in 11g and above AWR reports
1067 | # The variables AWRCOLn are set in the process_header_row function call earlier in the handler
1068 | AWR_DB_CPU=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL4}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1069 | AWR_DB_CPU_PCT_DBTIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL6}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1070 | echovrb "Processing Foreground Wait Class DB CPU"
1071 | echodbg "AWR_DB_CPU = ${ENDCHAR}${AWR_DB_CPU}${ENDCHAR}"
1072 | echodbg "AWR_DB_CPU_PCT_DBTIME = ${ENDCHAR}${AWR_DB_CPU_PCT_DBTIME}${ENDCHAR}"
1073 | continue
1074 | ;;
1075 | "Administrative"*)
1076 | WAIT_CLASS_NAME="ADMIN"
1077 | echovrb "Processing Foreground Wait Class Administrative"
1078 | ;;
1079 | "Application"*)
1080 | WAIT_CLASS_NAME="APPLN"
1081 | echovrb "Processing Foreground Wait Class Application"
1082 | ;;
1083 | "Cluster"*)
1084 | WAIT_CLASS_NAME="CLSTR"
1085 | echovrb "Processing Foreground Wait Class Cluster"
1086 | ;;
1087 | "Commit"*)
1088 | WAIT_CLASS_NAME="COMMT"
1089 | echovrb "Processing Foreground Wait Class Commit"
1090 | ;;
1091 | "Concurrency"*)
1092 | WAIT_CLASS_NAME="CNCUR"
1093 | echovrb "Processing Foreground Wait Class Concurrency"
1094 | ;;
1095 | "Configuration"*)
1096 | WAIT_CLASS_NAME="CONFG"
1097 | echovrb "Processing Foreground Wait Class Configuration"
1098 | ;;
1099 | "Network"*)
1100 | WAIT_CLASS_NAME="NETWK"
1101 | echovrb "Processing Foreground Wait Class Network"
1102 | ;;
1103 | "Other"*)
1104 | WAIT_CLASS_NAME="OTHER"
1105 | echovrb "Processing Foreground Wait Class Other"
1106 | ;;
1107 | "Scheduler"*)
1108 | WAIT_CLASS_NAME="SCHED"
1109 | echovrb "Processing Foreground Wait Class Scheduler"
1110 | ;;
1111 | "User I/O"*)
1112 | WAIT_CLASS_NAME="USRIO"
1113 | echovrb "Processing Foreground Wait Class User I/O"
1114 | ;;
1115 | "System I/O"*)
1116 | WAIT_CLASS_NAME="SYSIO"
1117 | echovrb "Processing Foreground Wait Class System I/O"
1118 | ;;
1119 | *)
1120 | # One of the other wait classes that we do not explicitely capture
1121 | echovrb "Ignoring wait class: ${AWRLINE[0]:0:20}"
1122 | # If this is 10g add to the running total for calculating DB Time
1123 | if [ "$AWR_FORMAT" = '10' ]; then
1124 | # Attempt to extract value for total wait time
1125 | # The variables AWRCOLn are set in the process_header_row function call earlier in the handler
1126 | TOTAL_WAIT_TIME_TMP=$(echo '${AWRLINE[0]}'| cut -c${AWRCOL4}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1127 | echodbg "TOTAL_WAIT_TIME_TMP = ${ENDCHAR}${TOTAL_WAIT_TIME_TMP}${ENDCHAR}"
1128 | # First check that the value we extract is actually a number, otherwise things will go bad when we inject it into the calculation below
1129 | if [ -n "$TOTAL_WAIT_TIME_TMP" ]; then
1130 | if [[ "$TOTAL_WAIT_TIME_TMP" != *[!0-9,]* ]]; then
1131 | echodbg "Calling BC: TOTAL_WAIT_TIME=echo 'scale=3; $TOTAL_WAIT_TIME + $TOTAL_WAIT_TIME_TMP' | bc -l"
1132 | TOTAL_WAIT_TIME=`echo "scale=3; $TOTAL_WAIT_TIME + $TOTAL_WAIT_TIME_TMP" | bc -l`
1133 | echodbg "TOTAL_WAIT_TIME = ${ENDCHAR}${TOTAL_WAIT_TIME}${ENDCHAR}"
1134 | else
1135 | # Value extracted was non-blank but non-numeric
1136 | echodbg "Unable to determine TOTAL_WAIT_TIME from non-numeric string: $TOTAL_WAIT_TIME_TMP"
1137 | fi
1138 | else
1139 | # Value extracted was blank
1140 | echodbg "Unable to determine TOTAL_WAIT_TIME from empty variable TOTAL_WAIT_TIME_TMP"
1141 | fi
1142 | unset TOTAL_WAIT_TIME_TMP
1143 | fi
1144 | continue
1145 | ;;
1146 | esac
1147 |
1148 | # Get the values for number of waits and wait time, then calculate average wait time
1149 | # The format of this section is slightly different between releases 10 and 11
1150 | # For 10g we keep a running total to calculate the percentage of DB Time, for 11g we just read it from the report
1151 | # The 12c format matches the 11g format for once, so we reuse the same code
1152 | # The variables AWRCOLn are set in the process_header_row function call earlier in the handler
1153 | WAIT_CLASS_NUM_WAITS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL2}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1154 | WAIT_CLASS_WAIT_TIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL4}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1155 | if [ "$AWR_FORMAT" = '10' ]; then
1156 | if [ -n "$WAIT_CLASS_WAIT_TIME" ]; then
1157 | echodbg "Calling BC: TOTAL_WAIT_TIME=echo 'scale=3; $TOTAL_WAIT_TIME + $WAIT_CLASS_WAIT_TIME' | bc -l"
1158 | TOTAL_WAIT_TIME=`echo "scale=3; $TOTAL_WAIT_TIME + $WAIT_CLASS_WAIT_TIME" | bc -l`
1159 | echodbg "TOTAL_WAIT_TIME = ${ENDCHAR}${TOTAL_WAIT_TIME}${ENDCHAR}"
1160 | fi
1161 | unset WAIT_CLASS_PCT_DBTIME
1162 | elif [ "$AWR_FORMAT" = '11' ] || [ "$AWR_FORMAT" = '12' ]; then
1163 | WAIT_CLASS_PCT_DBTIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL6}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1164 | else
1165 | # Set WAIT_CLASS_WAIT_TIME to zero to avoid breaking the call to BC below
1166 | WAIT_CLASS_WAIT_TIME=0
1167 | fi
1168 | # Calculate average wait - but first check that the number of waits is greater than zero
1169 | if [ -n "$WAIT_CLASS_NUM_WAITS" ]; then
1170 | if [ "$WAIT_CLASS_NUM_WAITS" != "0" ]; then
1171 | # See comments in header section for explanation of the way bc is used in calculating the average values below
1172 | echodbg "Calling BC: WAIT_CLASS_AVEWAIT=echo 'scale=3; (\$(echo 'scale=7; ($WAIT_CLASS_WAIT_TIME / $WAIT_CLASS_NUM_WAITS) * 1000' | bc -l)+0.0005)/1' | bc -l"
1173 | WAIT_CLASS_AVEWAIT=`echo "scale=3; ($(echo "scale=7; ($WAIT_CLASS_WAIT_TIME / $WAIT_CLASS_NUM_WAITS) * 1000" | bc -l)+0.0005)/1" | bc -l`
1174 | else
1175 | WAIT_CLASS_AVEWAIT=0
1176 | fi
1177 | else
1178 | unset WAIT_CLASS_AVEWAIT
1179 | fi
1180 |
1181 | echodbg "Foreground Wait Class $WAIT_CLASS_NAME: Waits=$WAIT_CLASS_NUM_WAITS, Time=$WAIT_CLASS_WAIT_TIME, PctDBTime=$WAIT_CLASS_PCT_DBTIME, Ave=$WAIT_CLASS_AVEWAIT"
1182 |
1183 | # Now place discovered values into the correct array of variables based on the WAIT_CLASS_NAME
1184 | eval WCLASS_${WAIT_CLASS_NAME}_NUM_WAITS='$WAIT_CLASS_NUM_WAITS'
1185 | eval WCLASS_${WAIT_CLASS_NAME}_WAIT_TIME='$WAIT_CLASS_WAIT_TIME'
1186 | [[ -n "$WAIT_CLASS_AVEWAIT" ]] && eval WCLASS_${WAIT_CLASS_NAME}_AVEWAIT='$WAIT_CLASS_AVEWAIT'
1187 | [[ -n "$WAIT_CLASS_PCT_DBTIME" ]] && eval WCLASS_${WAIT_CLASS_NAME}_PCT_DBTIME='$WAIT_CLASS_PCT_DBTIME'
1188 |
1189 | fi # End of handler routine for Foreground Wait Class section of AWR report
1190 |
1191 | ################################################################## Foreground Wait Events ##################################################################
1192 | if [ "$AWR_SECTION" = "ForegroundWaitEvents" ]; then
1193 | # Routine for handling the Foreground Wait Events section of the report
1194 | # The format of this section is slightly different between releases 10 and 11
1195 |
1196 | if [ "$FOUND_FG_WAIT_EVENTS" = "$AWR_NOTFOUND" ]; then
1197 | # We have just begun processing the Foreground Wait Events section so first we need to discover the header row (a set of dashes showing the column headings)
1198 | if [ "${AWRLINE[0]:0:6}" = "------" ]; then
1199 | echodbg "Searching for header row... found"
1200 | FOUND_FG_WAIT_EVENTS=$AWR_FOUND
1201 | process_header_row "${AWRLINE[0]}"
1202 | if [ "$PROCESS_HEADER_ROW" != "SUCCESS" ]; then
1203 | echovrb "Unable to determine width of rows in Foreground Wait Events section"
1204 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
1205 | AWR_SECTION="SearchingForNextSection"
1206 | # Switch Internal Field Seperator to only recognise newlines as delimiters
1207 | set_ifs_to_line_delimited
1208 | # Give up trying to process this section
1209 | if [ "$AWR_FORMAT" = "12" ]; then
1210 | AWRLINE_SKIP=10
1211 | else
1212 | AWRLINE_SKIP=5
1213 | fi
1214 | fi
1215 | else
1216 | let BAILOUT_COUNTER++
1217 | if [ "$BAILOUT_COUNTER" -eq "$BAILOUT_LIMIT" ]; then
1218 | echodbg "Failed to find header row (BAILOUT_COUNTER hit threshold = $BAILOUT_COUNTER)"
1219 | echovrb "Unable to determine width of rows in Foreground Wait Events section"
1220 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
1221 | AWR_SECTION="SearchingForNextSection"
1222 | # Switch Internal Field Seperator to only recognise newlines as delimiters
1223 | set_ifs_to_line_delimited
1224 | # Give up trying to process this section
1225 | if [ "$AWR_FORMAT" = "12" ]; then
1226 | AWRLINE_SKIP=10
1227 | else
1228 | AWRLINE_SKIP=5
1229 | fi
1230 | else
1231 | echodbg "Searching for header row... not found (BAILOUT_COUNTER = $BAILOUT_COUNTER)"
1232 | fi
1233 | fi
1234 | continue
1235 | fi
1236 |
1237 | # Start processing the section
1238 | case ${AWRLINE[0]:0:26} in
1239 | "cell multiblock physical r")
1240 | [[ "$EXADATA_FLAG" = "N" ]] && echovrb "Found evidence of Exadata system"
1241 | EXADATA_FLAG="Y"
1242 | ;;
1243 | "cell single block physical")
1244 | [[ "$EXADATA_FLAG" = "N" ]] && echovrb "Found evidence of Exadata system"
1245 | EXADATA_FLAG="Y"
1246 | ;;
1247 | "db file sequential read"*)
1248 | WAIT_NAME="DFSR"
1249 | ;;
1250 | "db file scattered read"*)
1251 | WAIT_NAME="DFXR"
1252 | ;;
1253 | "direct path read"*)
1254 | # This could be either direct path read or direct path read temp - so check and act accordingly
1255 | if [ "${AWRLINE[0]:0:21}" = "direct path read temp" ]; then
1256 | WAIT_NAME="DPRT"
1257 | else
1258 | WAIT_NAME="DPRD"
1259 | fi
1260 | ;;
1261 | "direct path write"*)
1262 | # This could be either direct path write or direct path write temp - so check and act accordingly
1263 | if [ "${AWRLINE[0]:0:22}" = "direct path write temp" ]; then
1264 | WAIT_NAME="DPWT"
1265 | else
1266 | WAIT_NAME="DPWR"
1267 | fi
1268 | ;;
1269 | "log file sync"*)
1270 | WAIT_NAME="LFSY"
1271 | ;;
1272 | *)
1273 | # Catch all other lines and set WAIT_NAME to be blank
1274 | WAIT_NAME=""
1275 | continue
1276 | ;;
1277 | esac
1278 |
1279 | # Now check WAIT_TIME and if set begin handling the line
1280 | # The variables AWRCOLn are set in the process_header_row function call earlier in the handler
1281 | if [ -n "$WAIT_NAME" ]; then
1282 | if [ "$AWR_FORMAT" = "10" ]; then
1283 | WAIT_NUM_WAITS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL2}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1284 | WAIT_TIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL4}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1285 | # No %DB Time column present in 10g reports - calculate value manually then round to one decimal place
1286 | if [ -n "$AWR_DB_TIME" ] && [ "$AWR_DB_TIME" != "0" ]; then
1287 | # See comments in header section for explanation of the way bc is used in calculating the average on the next line
1288 | echodbg "Calling BC: WAIT_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1289 | WAIT_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1290 | else
1291 | WAIT_PCT_DBTIME=""
1292 | fi
1293 | elif [ "$AWR_FORMAT" = "11" ] || [ "$AWR_FORMAT" = "12" ]; then
1294 | WAIT_NUM_WAITS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL2}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1295 | WAIT_TIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL4}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1296 | WAIT_PCT_DBTIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL7}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1297 | else
1298 | # Set WAIT_TIME to zero to avoid breaking call to BC below
1299 | WAIT_TIME=0
1300 | fi
1301 | # Calculate the average wait time in milliseconds with three decimal places
1302 | if [ -n "$WAIT_NUM_WAITS" ] && [ "$WAIT_NUM_WAITS" != "0" ]; then
1303 | # See comments in header section for explanation of the way bc is used in calculating the average on the next line
1304 | echodbg "Calling BC: WAIT_AVERAGE=echo 'scale=3; (\$(echo 'scale=7; ($WAIT_TIME / $WAIT_NUM_WAITS) * 1000' | bc -l)+0.0005)/1' | bc -l"
1305 | WAIT_AVERAGE=`echo "scale=3; ($(echo "scale=7; ($WAIT_TIME / $WAIT_NUM_WAITS) * 1000" | bc -l)+0.0005)/1" | bc -l`
1306 | else
1307 | WAIT_AVERAGE=""
1308 | fi
1309 |
1310 | echodbg "Foreground Wait Events $WAIT_NAME: Waits=$WAIT_NUM_WAITS, Time=$WAIT_TIME, PctDBTime=$WAIT_PCT_DBTIME, Ave=$WAIT_AVERAGE"
1311 |
1312 | # Set variable based on name of wait
1313 | eval WAIT_${WAIT_NAME}_WAITS='$WAIT_NUM_WAITS'
1314 | eval WAIT_${WAIT_NAME}_TIME='$WAIT_TIME'
1315 | eval WAIT_${WAIT_NAME}_AVERAGE='$WAIT_AVERAGE'
1316 | eval WAIT_${WAIT_NAME}_PCT_DBTIME='$WAIT_PCT_DBTIME'
1317 | fi
1318 | continue
1319 | fi # End of handler routine for Foreground Wait Events section of AWR report
1320 |
1321 | ################################################################## Background Wait Events ##################################################################
1322 | if [ "$AWR_SECTION" = "BackgroundWaitEvents" ]; then
1323 | # Routine for handling the Background Wait Events section of the report
1324 | # The format of this section is slightly different between releases 10 and 11
1325 |
1326 | if [ "$FOUND_BG_WAIT_EVENTS" = "$AWR_NOTFOUND" ]; then
1327 | # We have just begun processing the Background Wait Events section so first we need to discover the header row (a set of dashes showing the column headings)
1328 | if [ "${AWRLINE[0]:0:6}" = "------" ]; then
1329 | echodbg "Searching for header row... found"
1330 | FOUND_BG_WAIT_EVENTS=$AWR_FOUND
1331 | process_header_row "${AWRLINE[0]}"
1332 | if [ "$PROCESS_HEADER_ROW" != "SUCCESS" ]; then
1333 | echovrb "Unable to determine width of rows in Background Wait Events section"
1334 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
1335 | AWR_SECTION="SearchingForNextSection"
1336 | # Switch Internal Field Seperator to only recognise newlines as delimiters
1337 | set_ifs_to_line_delimited
1338 | # Give up trying to process this section
1339 | if [ "$AWR_FORMAT" = "12" ]; then
1340 | AWRLINE_SKIP=10
1341 | else
1342 | AWRLINE_SKIP=5
1343 | fi
1344 | fi
1345 | else
1346 | let BAILOUT_COUNTER++
1347 | if [ "$BAILOUT_COUNTER" -eq "$BAILOUT_LIMIT" ]; then
1348 | echodbg "Failed to find header row (BAILOUT_COUNTER hit threshold = $BAILOUT_COUNTER)"
1349 | echovrb "Unable to determine width of rows in Background Wait Events section"
1350 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
1351 | AWR_SECTION="SearchingForNextSection"
1352 | # Switch Internal Field Seperator to only recognise newlines as delimiters
1353 | set_ifs_to_line_delimited
1354 | # Give up trying to process this section
1355 | if [ "$AWR_FORMAT" = "12" ]; then
1356 | AWRLINE_SKIP=10
1357 | else
1358 | AWRLINE_SKIP=5
1359 | fi
1360 | else
1361 | echodbg "Searching for header row... not found (BAILOUT_COUNTER = $BAILOUT_COUNTER)"
1362 | fi
1363 | fi
1364 | continue
1365 | fi
1366 |
1367 | # Start processing the section
1368 | case ${AWRLINE[0]:0:26} in
1369 | "db file parallel write"*)
1370 | WAIT_NAME="DFPW"
1371 | ;;
1372 | "log file parallel write"*)
1373 | WAIT_NAME="LFPW"
1374 | ;;
1375 | "log file sequential read"*)
1376 | WAIT_NAME="LFSR"
1377 | ;;
1378 | "log file parallel write"*)
1379 | WAIT_NAME="LFPW"
1380 | ;;
1381 | "LNS wait on SENDREQ"*)
1382 | echovrb "Found evidence of Data Guard in use on this system"
1383 | DATA_GUARD_FLAG="Y"
1384 | ;;
1385 | *)
1386 | # Catch all other lines and set WAIT_NAME to be blank
1387 | WAIT_NAME=""
1388 | ;;
1389 | esac
1390 |
1391 | # Now check WAIT_TIME and if set begin handling the line
1392 | # The variables AWRCOLn are set in the process_header_row function call earlier in the handler
1393 | if [ -n "$WAIT_NAME" ]; then
1394 | if [ "$AWR_FORMAT" = "10" ]; then
1395 | WAIT_NUM_WAITS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL2}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1396 | WAIT_TIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL4}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1397 | # No %BG Time column present in 10g reports - cannot calculate manually so leave blank
1398 | WAIT_PCT_DBTIME=""
1399 | elif [ "$AWR_FORMAT" = "11" ] || [ "$AWR_FORMAT" = "12" ]; then
1400 | WAIT_NUM_WAITS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL2}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1401 | WAIT_TIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL4}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1402 | WAIT_PCT_DBTIME=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL7}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1403 | else
1404 | # Set WAIT_TIME to zero to avoid breaking call to BC below
1405 | WAIT_TIME=0
1406 | fi
1407 |
1408 | # Calculate the average wait time in milliseconds with three decimal places
1409 | if [ -n "$WAIT_NUM_WAITS" ] && [ "$WAIT_NUM_WAITS" != "0" ]; then
1410 | # See comments in header section for explanation of the way bc is used in calculating the average on the next line
1411 | echodbg "Calling BC: WAIT_AVERAGE=echo 'scale=3; (\$(echo 'scale=7; ($WAIT_TIME / $WAIT_NUM_WAITS) * 1000' | bc -l)+0.0005)/1' | bc -l"
1412 | WAIT_AVERAGE=`echo "scale=3; ($(echo "scale=7; ($WAIT_TIME / $WAIT_NUM_WAITS) * 1000" | bc -l)+0.0005)/1" | bc -l`
1413 | else
1414 | WAIT_AVERAGE=""
1415 | fi
1416 |
1417 | echodbg "Background Wait Events $WAIT_NAME: Waits=$WAIT_NUM_WAITS, Time=$WAIT_TIME, PctDBTime=$WAIT_PCT_DBTIME, Ave=$WAIT_AVERAGE"
1418 |
1419 | # Set variable based on name of wait
1420 | eval WAIT_${WAIT_NAME}_WAITS='$WAIT_NUM_WAITS'
1421 | eval WAIT_${WAIT_NAME}_TIME='$WAIT_TIME'
1422 | eval WAIT_${WAIT_NAME}_AVERAGE='$WAIT_AVERAGE'
1423 | eval WAIT_${WAIT_NAME}_PCT_DBTIME='$WAIT_PCT_DBTIME'
1424 | fi
1425 | continue
1426 | fi # End of handler routine for Background Wait Events section of AWR report
1427 |
1428 | ################################################################## Wait Event Histogram ##################################################################
1429 | if [ "$AWR_SECTION" = "WaitEventHistogram" ]; then
1430 | # Routine for handling the Background Wait Events section of the report
1431 | # The format of this section is slightly different between releases 10 and 11
1432 |
1433 | if [ "$FOUND_HG_WAIT_EVENTS" = "$AWR_NOTFOUND" ]; then
1434 | # We have just begun processing the Wait Event Histogram section so first we need to discover the header row (a set of dashes showing the column headings)
1435 | if [ "${AWRLINE[0]:0:6}" = "------" ]; then
1436 | echodbg "Searching for header row... found"
1437 | FOUND_HG_WAIT_EVENTS=$AWR_FOUND
1438 | process_header_row "${AWRLINE[0]}"
1439 | if [ "$PROCESS_HEADER_ROW" != "SUCCESS" ]; then
1440 | echovrb "Unable to determine width of rows in Wait Event Histogram section"
1441 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
1442 | AWR_SECTION="SearchingForNextSection"
1443 | # Switch Internal Field Seperator to only recognise newlines as delimiters
1444 | set_ifs_to_line_delimited
1445 | fi
1446 | else
1447 | let BAILOUT_COUNTER++
1448 | if [ "$BAILOUT_COUNTER" -eq "$BAILOUT_LIMIT" ]; then
1449 | echodbg "Failed to find header row (BAILOUT_COUNTER hit threshold = $BAILOUT_COUNTER)"
1450 | echovrb "Unable to determine width of rows in Wait Event Histogram section"
1451 | echodbg "State change AWR_SECTION: $AWR_SECTION -> SearchingForNextSection"
1452 | AWR_SECTION="SearchingForNextSection"
1453 | # Switch Internal Field Seperator to only recognise newlines as delimiters
1454 | set_ifs_to_line_delimited
1455 | # Give up trying to process this section
1456 | echodbg "Searching for header row... not found (BAILOUT_COUNTER = $BAILOUT_COUNTER)"
1457 | fi
1458 | fi
1459 | continue
1460 | fi
1461 |
1462 | # Start processing the section
1463 | case ${AWRLINE[0]:0:26} in
1464 | "db file sequential read"*)
1465 | WAIT_NAME="DFSR"
1466 | ;;
1467 | "log file parallel write"*)
1468 | WAIT_NAME="LFPW"
1469 | ;;
1470 | *)
1471 | # Catch all other lines and set WAIT_NAME to be blank
1472 | WAIT_NAME=""
1473 | ;;
1474 | esac
1475 |
1476 | # Now check WAIT_TIME and if set begin handling the line
1477 | # The variables AWRCOLn are set in the process_header_row function call earlier in the handler
1478 | if [ -n "$WAIT_NAME" ]; then
1479 | HGRM_1MS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL3}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1480 | HGRM_2MS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL4}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1481 | HGRM_4MS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL5}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1482 | HGRM_8MS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL6}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1483 | HGRM_16MS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL7}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1484 | HGRM_32MS=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL8}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1485 | HGRM_LT1S=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL9}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1486 | HGRM_GT1S=$(echo "${AWRLINE[0]}"| cut -c${AWRCOL10}|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1487 |
1488 | echodbg "Wait Event Histogram $WAIT_NAME: <1ms=$HGRM_1MS, <2ms=$HGRM_2MS, <4ms=$HGRM_4MS, <8ms=$HGRM_8MS, <16ms=$HGRM_16MS, <32ms=$HGRM_32MS, <1s=$HGRM_LT1S, >1s=$HGRM_GT1S"
1489 |
1490 | # Set variable based on name of wait
1491 | eval HGRM_${WAIT_NAME}_1MS='$HGRM_1MS'
1492 | eval HGRM_${WAIT_NAME}_2MS='$HGRM_2MS'
1493 | eval HGRM_${WAIT_NAME}_4MS='$HGRM_4MS'
1494 | eval HGRM_${WAIT_NAME}_8MS='$HGRM_8MS'
1495 | eval HGRM_${WAIT_NAME}_16MS='$HGRM_16MS'
1496 | eval HGRM_${WAIT_NAME}_32MS='$HGRM_32MS'
1497 | eval HGRM_${WAIT_NAME}_LT1S='$HGRM_LT1S'
1498 | eval HGRM_${WAIT_NAME}_GT1S='$HGRM_GT1S'
1499 | fi
1500 | continue
1501 | fi # End of handler routine for Wait Event Histogram section of AWR report
1502 |
1503 | ################################################################## Instance Activity Stats ##################################################################
1504 | if [ "$AWR_SECTION" = "InstanceActivityStats" ]; then
1505 | # Routine for handling the Instance Activity Stats section of the report
1506 | case ${AWRLINE[0]:0:32} in
1507 | "physical read total IO requests"*)
1508 | READ_IOPS=$(echo "${AWRLINE[0]}"| cut -c52-66|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1509 | echodbg "READ_IOPS = ${ENDCHAR}${READ_IOPS}${ENDCHAR}"
1510 | ;;
1511 | "physical read total bytes "*)
1512 | # Because this number is often very large Oracle may print it in scientific notation so we have to convert this if neccessary
1513 | READ_THROUGHPUT=$(echo "${AWRLINE[0]}"| cut -c52-66|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g'| sed -e 's/E+/\*10\^/')
1514 | # Convert to MB/sec
1515 | if [ -n "$READ_THROUGHPUT" ]; then
1516 | echodbg "Calling BC: READ_THROUGHPUT=echo 'scale=2; (\$(echo 'scale=6; $READ_THROUGHPUT / 1048576' | bc -l)+0.005)/1' | bc -l"
1517 | READ_THROUGHPUT=`echo "scale=2; ($(echo "scale=6; $READ_THROUGHPUT / 1048576" | bc -l)+0.005)/1" | bc -l`
1518 | echodbg "READ_THROUGHPUT = ${ENDCHAR}${READ_THROUGHPUT}${ENDCHAR}"
1519 | else
1520 | echovrb "WARNING: Unable to calculate value for READ_THROUGHPUT: $READ_THROUGHPUT"
1521 | READ_THROUGHPUT=""
1522 | fi
1523 | ;;
1524 | "physical write total IO requests")
1525 | ALL_WRITE_IOPS=$(echo "${AWRLINE[0]}"| cut -c52-66|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1526 | echodbg "ALL_WRITE_IOPS = ${ENDCHAR}${ALL_WRITE_IOPS}${ENDCHAR}"
1527 | ;;
1528 | "physical write total bytes "*)
1529 | # Because this number is often very large Oracle may print it in scientific notation so we have to convert this if neccessary
1530 | ALL_WRITE_THROUGHPUT=$(echo "${AWRLINE[0]}"| cut -c52-66|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g'| sed -e 's/E+/\*10\^/')
1531 | # Convert to MB/sec
1532 | if [ -n "$ALL_WRITE_THROUGHPUT" ]; then
1533 | echodbg "Calling BC: ALL_WRITE_THROUGHPUT=echo 'scale=2; (\$(echo 'scale=6; $ALL_WRITE_THROUGHPUT / 1048576' | bc -l)+0.005)/1' | bc -l"
1534 | ALL_WRITE_THROUGHPUT=`echo "scale=2; ($(echo "scale=6; $ALL_WRITE_THROUGHPUT / 1048576" | bc -l)+0.005)/1" | bc -l`
1535 | echodbg "ALL_WRITE_THROUGHPUT = ${ENDCHAR}${ALL_WRITE_THROUGHPUT}${ENDCHAR}"
1536 | else
1537 | echovrb "WARNING: Unable to calculate value for ALL_WRITE_THROUGHPUT: $ALL_WRITE_THROUGHPUT"
1538 | ALL_WRITE_THROUGHPUT=""
1539 | fi
1540 | ;;
1541 | "redo writes"*)
1542 | REDO_WRITE_IOPS=$(echo "${AWRLINE[0]}"| cut -c52-66|sed -e 's/^[ \t]*//;s/[ \t]*$//;s/,//g')
1543 | echodbg "REDO_WRITE_IOPS = ${ENDCHAR}${REDO_WRITE_IOPS}${ENDCHAR}"
1544 | ;;
1545 | " ----------------------")
1546 | # End of Instance Activity Stats section of the report
1547 | echovrb "End of Instance Activity Stats section found at line $ROWCNT"
1548 | echovrb "No further sections to search for - jump to post-processing"
1549 | AWR_SECTION="EndOfReport"
1550 | # This is the last section so break out of the while loop to begin post processing
1551 | break
1552 | ;;
1553 | esac
1554 | continue
1555 | fi
1556 |
1557 | ################################################################## Thread Activity ##################################################################
1558 | if [ "$AWR_SECTION" = "ThreadActivity" ]; then
1559 | # Routine for handling the Instance Activity Stats - Thread Activity section of the report
1560 | # Examine two words
1561 | case ${AWRLINE[@]:0:2} in
1562 | "log switches")
1563 | # Read information on log switches - remove commas and any carriage return
1564 | AWR_LOG_SWITCHES_TOTAL=$(echo ${AWRLINE[3]} |sed -e 's/,//g')
1565 | AWR_LOG_SWITCHES_PERHOUR=$(echo ${AWRLINE[4]} |sed -e 's/,//g' | tr -d '\r')
1566 | echodbg "AWR_LOG_SWITCHES_TOTAL = ${ENDCHAR}${AWR_LOG_SWITCHES_TOTAL}${ENDCHAR}"
1567 | echodbg "AWR_LOG_SWITCHES_PERHOUR = ${ENDCHAR}${AWR_LOG_SWITCHES_PERHOUR}${ENDCHAR}"
1568 | echovrb "Finished scanning file at line $ROWCNT"
1569 | break
1570 | ;;
1571 | *)
1572 | # Catch all other lines and ignore
1573 | continue
1574 | ;;
1575 | esac
1576 | fi
1577 |
1578 | # End of the while read loop
1579 | done < $AWRFILE
1580 | # Finished reading AWR report on line by line basis
1581 |
1582 | ################################################################## Post Processing Section ##################################################################
1583 | # Start post processing section for files of known format
1584 | if [ "$AWR_FORMAT" != 'Unknown' ]; then
1585 | echovrb "Start post-processing section"
1586 | # Based on comparison of NUM_CPUS and Average Active Sessions, set BUSY flag to Y or N
1587 | if [ -n "$DB_NUM_CPUS" ] && [ -n "$AWR_AAS" ]; then
1588 | # Set BUSY flag if AAS higher than number of CPUs
1589 | echodbg "Calling BC: echo '$AWR_AAS > $DB_NUM_CPUS' | bc -l"
1590 | if [ $(echo "$AWR_AAS > $DB_NUM_CPUS" | bc -l) = 1 ]; then
1591 | AWR_BUSY_FLAG="Y"
1592 | else
1593 | AWR_BUSY_FLAG="N"
1594 | fi
1595 | fi
1596 |
1597 | # Calculate total and data write IOPS values
1598 | TOTAL_IOPS=0
1599 | DATA_WRITE_IOPS=0
1600 | if [ -n "$READ_IOPS" ]; then
1601 | echodbg "Calling BC: TOTAL_IOPS=echo 'scale=1; $TOTAL_IOPS + $READ_IOPS' | bc -l"
1602 | TOTAL_IOPS=`echo "scale=1; $TOTAL_IOPS + $READ_IOPS" | bc -l`
1603 | echodbg "TOTAL_IOPS = ${ENDCHAR}${TOTAL_IOPS}${ENDCHAR}"
1604 | fi
1605 | if [ -n "$ALL_WRITE_IOPS" ]; then
1606 | echodbg "Calling BC: TOTAL_IOPS=echo 'scale=1; $TOTAL_IOPS + $ALL_WRITE_IOPS' | bc -l"
1607 | TOTAL_IOPS=`echo "scale=1; $TOTAL_IOPS + $ALL_WRITE_IOPS" | bc -l`
1608 | echodbg "TOTAL_IOPS = ${ENDCHAR}${TOTAL_IOPS}${ENDCHAR}"
1609 | if [ -n "$REDO_WRITE_IOPS" ]; then
1610 | echodbg "Calling BC: ALL_WRITE_IOPS=echo 'scale=1; $ALL_WRITE_IOPS - $REDO_WRITE_IOPS' | bc -l"
1611 | DATA_WRITE_IOPS=`echo "scale=1; $ALL_WRITE_IOPS - $REDO_WRITE_IOPS" | bc -l`
1612 | echodbg "DATA_WRITE_IOPS = ${ENDCHAR}${DATA_WRITE_IOPS}${ENDCHAR}"
1613 | fi
1614 | fi
1615 | [[ "$TOTAL_IOPS" = "0" ]] && unset TOTAL_IOPS
1616 | [[ "$READ_IOPS" = "0" ]] && unset READ_IOPS
1617 | [[ "$ALL_WRITE_IOPS" = "0" ]] && unset ALL_WRITE_IOPS
1618 | [[ "$DATA_WRITE_IOPS" = "0" ]] && unset DATA_WRITE_IOPS
1619 |
1620 | # Calculate total and data write throughput values
1621 | TOTAL_THROUGHPUT=0
1622 | DATA_WRITE_THROUGHPUT=0
1623 | if [ -n "$READ_THROUGHPUT" ]; then
1624 | echodbg "Calling BC: TOTAL_THROUGHPUT=echo 'scale=1; $TOTAL_THROUGHPUT + $READ_THROUGHPUT' | bc -l"
1625 | TOTAL_THROUGHPUT=`echo "scale=1; $TOTAL_THROUGHPUT + $READ_THROUGHPUT" | bc -l`
1626 | echodbg "TOTAL_THROUGHPUT = ${ENDCHAR}${TOTAL_THROUGHPUT}${ENDCHAR}"
1627 | fi
1628 | if [ -n "$ALL_WRITE_THROUGHPUT" ]; then
1629 | echodbg "Calling BC: TOTAL_THROUGHPUT=echo 'scale=1; $TOTAL_THROUGHPUT + $ALL_WRITE_THROUGHPUT | bc -l"
1630 | TOTAL_THROUGHPUT=`echo "scale=1; $TOTAL_THROUGHPUT + $ALL_WRITE_THROUGHPUT" | bc -l`
1631 | echodbg "TOTAL_THROUGHPUT = ${ENDCHAR}${TOTAL_THROUGHPUT}${ENDCHAR}"
1632 | if [ -n "$REDO_WRITE_THROUGHPUT" ]; then
1633 | echodbg "Calling BC: ALL_WRITE_THROUGHPUT=echo 'scale=1; $ALL_WRITE_THROUGHPUT - $REDO_WRITE_THROUGHPUT' | bc -l"
1634 | DATA_WRITE_THROUGHPUT=`echo "scale=1; $ALL_WRITE_THROUGHPUT - $REDO_WRITE_THROUGHPUT" | bc -l`
1635 | echodbg "DATA_WRITE_THROUGHPUT = ${ENDCHAR}${DATA_WRITE_THROUGHPUT}${ENDCHAR}"
1636 | fi
1637 | fi
1638 | [[ "$TOTAL_THROUGHPUT" = "0" ]] && unset TOTAL_THROUGHPUT
1639 | [[ "$READ_THROUGHPUT" = "0" ]] && unset READ_THROUGHPUT
1640 | [[ "$ALL_WRITE_THROUGHPUT" = "0" ]] && unset ALL_WRITE_THROUGHPUT
1641 | [[ "$DATA_WRITE_THROUGHPUT" = "0" ]] && unset DATA_WRITE_THROUGHPUT
1642 |
1643 | # No %DB Time column present in 10g reports - calculate value for wait classes manually then round to one decimal place
1644 | if [ "$AWR_FORMAT" = '10' ] && [ "$FOUND_FG_WAIT_CLASS"="$AWR_FOUND" ]; then
1645 | echovrb "Calculating Wait Class data: note that %DBTime in 10g reports can total to >100%"
1646 | echovrb " - this is a known issue and is fixed in 11g"
1647 | # First check that we have a value for %DB Time otherwise skip the calculation section
1648 | if [ -z "$AWR_DB_TIME" ] || [ "$AWR_DB_TIME" = 0 ]; then
1649 | echovrb "WARNING: Unable to calculate Wait Class %DBTime values due to unknown value for DB Time: $AWR_DB_TIME"
1650 | continue
1651 | fi
1652 | # See comments in header section for explanation of the way bc is used in calculating the average on the following lines
1653 | if [ -n "$WCLASS_ADMIN_WAIT_TIME" ]; then
1654 | echodbg "Calling BC: WCLASS_ADMIN_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_ADMIN_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1655 | WCLASS_ADMIN_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_ADMIN_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1656 | echovrb "Calculated Administrative Wait Class %DBTime as $WCLASS_ADMIN_PCT_DBTIME %"
1657 | else
1658 | echovrb "No values found for Administrative Wait Class"
1659 | fi
1660 | if [ -n "$WCLASS_APPLN_WAIT_TIME" ]; then
1661 | echodbg "Calling BC: WCLASS_APPLN_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_APPLN_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1662 | WCLASS_APPLN_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_APPLN_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1663 | echovrb "Calculated Application Wait Class %DBTime as $WCLASS_APPLN_PCT_DBTIME %"
1664 | else
1665 | echovrb "No values found for Application Wait Class"
1666 | fi
1667 | if [ -n "$WCLASS_CLSTR_WAIT_TIME" ]; then
1668 | echodbg "Calling BC: WCLASS_CLSTR_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_CLSTR_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1669 | WCLASS_CLSTR_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_CLSTR_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1670 | echovrb "Calculated Cluster Wait Class %DBTime as $WCLASS_CLSTR_PCT_DBTIME %"
1671 | else
1672 | echovrb "No values found for Cluster Wait Class"
1673 | fi
1674 | if [ -n "$WCLASS_COMMT_WAIT_TIME" ]; then
1675 | echodbg "Calling BC: WCLASS_COMMT_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_COMMT_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1676 | WCLASS_COMMT_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_COMMT_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1677 | echovrb "Calculated Commit Wait Class %DBTime as $WCLASS_COMMT_PCT_DBTIME %"
1678 | else
1679 | echovrb "No values found for Commit Wait Class"
1680 | fi
1681 | if [ -n "$WCLASS_CNCUR_WAIT_TIME" ]; then
1682 | echodbg "Calling BC: WCLASS_CNCUR_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_CNCUR_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1683 | WCLASS_CNCUR_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_CNCUR_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1684 | echovrb "Calculated Concurrency Wait Class %DBTime as $WCLASS_CNCUR_PCT_DBTIME %"
1685 | else
1686 | echovrb "No values found for Concurrency Wait Class"
1687 | fi
1688 | if [ -n "$WCLASS_CONFG_WAIT_TIME" ]; then
1689 | echodbg "Calling BC: WCLASS_CONFG_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_CONFG_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1690 | WCLASS_CONFG_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_CONFG_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1691 | echovrb "Calculated Configuration Wait Class %DBTime as $WCLASS_CONFG_PCT_DBTIME %"
1692 | else
1693 | echovrb "No values found for Configuration Wait Class"
1694 | fi
1695 | if [ -n "$WCLASS_NETWK_WAIT_TIME" ]; then
1696 | echodbg "Calling BC: WCLASS_NETWK_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_NETWK_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1697 | WCLASS_NETWK_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_NETWK_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1698 | echovrb "Calculated Network Wait Class %DBTime as $WCLASS_NETWK_PCT_DBTIME %"
1699 | else
1700 | echovrb "No values found for Network Wait Class"
1701 | fi
1702 | if [ -n "$WCLASS_OTHER_WAIT_TIME" ]; then
1703 | echodbg "Calling BC: WCLASS_OTHER_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_OTHER_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1704 | WCLASS_OTHER_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_OTHER_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1705 | echovrb "Calculated Other Wait Class %DBTime as $WCLASS_OTHER_PCT_DBTIME %"
1706 | else
1707 | echovrb "No values found for Other Wait Class"
1708 | fi
1709 | if [ -n "$WCLASS_SCHED_WAIT_TIME" ]; then
1710 | echodbg "Calling BC: WCLASS_SCHED_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_SCHED_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1711 | WCLASS_SCHED_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_SCHED_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1712 | echovrb "Calculated Scheduler Wait Class %DBTime as $WCLASS_SCHED_PCT_DBTIME %"
1713 | else
1714 | echovrb "No values found for Scheduler Wait Class"
1715 | fi
1716 | if [ -n "$WCLASS_USRIO_WAIT_TIME" ]; then
1717 | echodbg "Calling BC: WCLASS_USRIO_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_USRIO_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1718 | WCLASS_USRIO_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_USRIO_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1719 | echovrb "Calculated User I/O %DBTime as $WCLASS_USRIO_PCT_DBTIME %"
1720 | else
1721 | echovrb "No values found for User I/O Wait Class"
1722 | fi
1723 | if [ -n "$WCLASS_SYSIO_WAIT_TIME" ]; then
1724 | echodbg "Calling BC: WCLASS_SYSIO_PCT_DBTIME=echo 'scale=1; (\$(echo 'scale=5; ($WCLASS_SYSIO_WAIT_TIME/($AWR_DB_TIME*60))*100' | bc -l)+0.05)/1' | bc -l"
1725 | WCLASS_SYSIO_PCT_DBTIME=`echo "scale=1; ($(echo "scale=5; ($WCLASS_SYSIO_WAIT_TIME/($AWR_DB_TIME*60))*100" | bc -l)+0.05)/1" | bc -l`
1726 | echovrb "Calculated System I/O %DBTime as $WCLASS_SYSIO_PCT_DBTIME %"
1727 | else
1728 | echovrb "No values found for System I/O Wait Class"
1729 | fi
1730 | fi
1731 |
1732 | # Print warnings if certain sections were not found
1733 | [[ "$FOUND_SYS_DETAILS" != "$AWR_FOUND" ]] && echoinf "Unable to find database system details"
1734 | if [ "$AWR_FORMAT" -ne "10" ]; then
1735 | [[ "$FOUND_HOST_DETAILS" != "$AWR_FOUND" ]] && echoinf "Unable to find host system details"
1736 | [[ -z "$AWR_AAS" ]] && echoinf "Unable to calculate Average Active Sessions"
1737 | [[ -z "$AWR_BUSY_FLAG" ]] && echoinf "Unable to determine value for BUSY flag"
1738 | fi
1739 |
1740 | # Raise error if any critical values are null
1741 | if [ -z "$PROFILE_DBNAME" ]; then
1742 | echoerr "Post-process complete: unable to determine Database name"
1743 | elif [ -z "$READ_IOPS" ]; then
1744 | echoerr "Post-process complete: unable to determine read IOPS values"
1745 | elif [ -z "$ALL_WRITE_IOPS" ]; then
1746 | echoerr "Post-process complete: unable to determine write IOPS values"
1747 | elif [ -z "$READ_THROUGHPUT" ]; then
1748 | echoerr "Post-process complete: unable to determine read throughput values"
1749 | elif [ -z "$ALL_WRITE_THROUGHPUT" ]; then
1750 | echoerr "Post-process complete: unable to determine write throughput values"
1751 | else
1752 | echovrb "Post-processing complete"
1753 | fi
1754 | fi
1755 | }
1756 |
1757 | # Function for printing the header row in the CSV file i.e. the descriptions of each column
1758 | print_header_row() {
1759 | # Write header row for CSV file
1760 | echocsv "Filename,Database Name,Instance Number,Instance Name,Database Version,Cluster,Hostname,Host OS,Num CPUs,Server Memory (GB),DB Block Size,Begin Snap,Begin Time,End Snap,End Time,Elapsed Time (mins),DB Time (mins),Average Active Sessions,Busy Flag,Logical Reads/sec,Block Changes/sec,Read IOPS,Write IOPS,Redo IOPS,All Write IOPS,Total IOPS,Read Throughput (MiB/sec),Write Throughput (MiB/sec),Redo Throughput (MiB/sec),All Write Throughput (MiB/sec),Total Throughput (MiB/sec),DB CPU Time (s),DB CPU %DBTime,Wait Class User I/O Waits,Wait Class User I/O Time (s),Wait Class User I/O Latency (ms),Wait Class User I/O %DBTime,User Calls/sec,Parses/sec,Hard Parses/sec,Logons/sec,Executes/sec,Transactions/sec,Buffer Hit Ratio (%),In-Memory Sort Ratio (%),Log Switches (Total),Log Switches (Per Hour),Top5 Event1 Name,Top5 Event1 Class,Top5 Event1 Waits,Top5 Event1 Time (s),Top5 Event1 Average Time (ms),Top5 Event1 %DBTime,Top5 Event2 Name,Top5 Event2 Class,Top5 Event2 Waits,Top5 Event2 Time (s),Top5 Event2 Average Time (ms),Top5 Event2 %DBTime,Top5 Event3 Name,Top5 Event3 Class,Top5 Event3 Waits,Top5 Event3 Time (s),Top5 Event3 Average Time (ms),Top5 Event3 %DBTime,Top5 Event4 Name,Top5 Event4 Class,Top5 Event4 Waits,Top5 Event4 Time (s),Top5 Event4 Average Time (ms),Top5 Event4 %DBTime,Top5 Event5 Name,Top5 Event5 Class,Top5 Event5 Waits,Top5 Event5 Time (s),Top5 Event5 Average Time (ms),Top5 Event5 %DBTime,db file sequential read Waits,db file sequential read Time (s),db file sequential read Latency (ms),db file sequential read %DBTime,db file scattered read Waits,db file scattered read Time (s),db file scattered read Latency (ms),db file scattered read %DBTime,direct path read Waits,direct path read Time (s),direct path read Latency (ms),direct path read %DBTime,direct path write Waits,direct path write Time (s),direct path write Latency (ms),direct path write %DBTime,direct path read temp Waits,direct path read temp Time (s),direct path read temp Latency (ms),direct path read temp %DBTime,direct path write temp Waits,direct path write temp Time (s),direct path write temp Latency (ms),direct path write temp %DBTime,log file sync Waits,log file sync Time (s),log file sync Latency (ms),log file sync %DBTime,db file parallel write Waits,db file parallel write Time (s),db file parallel write Latency (ms),db file parallel write %DBTime,log file parallel write Waits,log file parallel write Time (s),log file parallel write Latency (ms),log file parallel write %DBTime,log file sequential read Waits,log file sequential read Time (s),log file sequential read Latency (ms),log file sequential read %DBTime,OS busy time,OS idle time,OS iowait time,OS sys time,OS user time,OS cpu wait time,OS resource mgr wait time,Data Guard Flag,Exadata Flag,Wait Class Admin Waits,Wait Class Admin Time (s),Wait Class Admin Latency (ms),Wait Class Admin %DBTime,Wait Class Application Waits,Wait Class Application Time (s),Wait Class Application Latency (ms),Wait Class Application %DBTime,Wait Class Cluster Waits,Wait Class Cluster Time (s),Wait Class Cluster Latency (ms),Wait Class Cluster %DBTime,Wait Class Commit Waits,Wait Class Commit Time (s),Wait Class Commit Latency (ms),Wait Class Commit %DBTime,Wait Class Concurrency Waits,Wait Class Concurrency Time (s),Wait Class Concurrency Latency (ms),Wait Class Concurrency %DBTime,Wait Class Configuration Waits,Wait Class Configuration Time (s),Wait Class Configuration Latency (ms),Wait Class Configuration %DBTime,Wait Class Network Waits,Wait Class Network Time (s),Wait Class Network Latency (ms),Wait Class Network %DBTime,Wait Class Other Waits,Wait Class Other Time (s),Wait Class Other Latency (ms),Wait Class Other %DBTime,Wait Class System I/O Waits,Wait Class System I/O Time (s),Wait Class System I/O Latency (ms),Wait Class System I/O %DBTime,Histogram <1ms db file sequential read,Histogram <2ms db file sequential read,Histogram <4ms db file sequential read,Histogram <8ms db file sequential read,Histogram <16ms db file sequential read,Histogram <32ms db file sequential read,Histogram <1s db file sequential read,Histogram >1s db file sequential read,Histogram <1ms log file parallel write,Histogram <2ms log file parallel write,Histogram <4ms log file parallel write,Histogram <8ms log file parallel write,Histogram <16ms log file parallel write,Histogram <32ms log file parallel write,Histogram <1s log file parallel write,Histogram >1s log file parallel write"
1761 | }
1762 |
1763 | # Function for printing extracted AWR information when in verbose mode
1764 | print_report_info() {
1765 | # Print harvested information to errinf function
1766 | echoprt " Filename = $AWRFILENAME"
1767 | echoprt " AWR Format = $AWR_FORMAT"
1768 | echoprt " Database Name = $PROFILE_DBNAME"
1769 | echoprt " Instance Number = $PROFILE_INSTANCENUM"
1770 | echoprt " Instance Name = $PROFILE_INSTANCENAME"
1771 | echoprt " Database Version = $PROFILE_DBVERSION"
1772 | echoprt " Cluster Y/N = $PROFILE_CLUSTER"
1773 | echoprt " Hostname = $DB_HOSTNAME"
1774 | echoprt " Host OS = $DB_HOST_OS"
1775 | echoprt " Number of CPUs = $DB_NUM_CPUS"
1776 | echoprt " Server Memory = $DB_HOST_MEM"
1777 | echoprt " DB Blocksize = $DB_BLOCK_SIZE"
1778 | echoprt " Begin Snap = $AWR_BEGIN_SNAP"
1779 | echoprt " Begin Time = $AWR_BEGIN_TIME"
1780 | echoprt " End Snap = $AWR_END_SNAP"
1781 | echoprt " End Time = $AWR_END_TIME"
1782 | echoprt " Elapsed Time = $AWR_ELAPSED_TIME"
1783 | echoprt " DB Time = $AWR_DB_TIME"
1784 | echoprt " AAS = $AWR_AAS"
1785 | echoprt " Busy? = $AWR_BUSY_FLAG"
1786 | echoprt " Logical Reads/sec = $AWR_LOGICAL_READS"
1787 | echoprt " Block Changes/sec = $AWR_BLOCK_CHANGES"
1788 | echoprt " Read IOPS = $READ_IOPS"
1789 | echoprt " Data Write IOPS = $DATA_WRITE_IOPS"
1790 | echoprt " Redo Write IOPS = $REDO_WRITE_IOPS"
1791 | echoprt " Total Write IOPS = $ALL_WRITE_IOPS"
1792 | echoprt " Total IOPS = $TOTAL_IOPS"
1793 | echoprt " Read Throughput (MiB/sec) = $READ_THROUGHPUT"
1794 | echoprt " Data Write Throughput (MiB/sec) = $DATA_WRITE_THROUGHPUT"
1795 | echoprt " Redo Write Throughput (MiB/sec) = $REDO_WRITE_THROUGHPUT"
1796 | echoprt " Total Write Throughput (MiB/sec) = $ALL_WRITE_THROUGHPUT"
1797 | echoprt " Total Throughput (MiB/sec) = $TOTAL_THROUGHPUT"
1798 | echoprt " DB CPU Time ms = $AWR_DB_CPU"
1799 | echoprt " DB CPU %DBTime = $AWR_DB_CPU_PCT_DBTIME"
1800 | echoprt " Wait Class User IO Num Waits = $WCLASS_USRIO_NUM_WAITS"
1801 | echoprt " Wait Class User IO Wait Time = $WCLASS_USRIO_WAIT_TIME"
1802 | echoprt " Wait Class User IO Latency ms = $WCLASS_USRIO_AVEWAIT"
1803 | echoprt " Wait Class User IO %DBTime = $WCLASS_USRIO_PCT_DBTIME"
1804 | echoprt " User Calls/sec = $AWR_USER_CALLS"
1805 | echoprt " Parses/sec = $AWR_PARSES"
1806 | echoprt " Hard Parses/sec = $AWR_HARD_PARSES"
1807 | echoprt " Logons/sec = $AWR_LOGONS"
1808 | echoprt " Executes/sec = $AWR_EXECUTES"
1809 | echoprt " Transactions/sec = $AWR_TRANSACTIONS"
1810 | echoprt " Buffer Hit Ratio = $BUFFER_HIT_RATIO"
1811 | echoprt " In-Memory Sort Ratio = $INMEMORY_SORT_RATIO"
1812 | echoprt " Log Switches Total = $AWR_LOG_SWITCHES_TOTAL"
1813 | echoprt " Log Switches Per Hour = $AWR_LOG_SWITCHES_PERHOUR"
1814 | echoprt " Top 5 Timed Event1 Name = $TOP5EVENT1_NAME"
1815 | echoprt " Top 5 Timed Event1 Class = $TOP5EVENT1_CLASS"
1816 | echoprt " Top 5 Timed Event1 Waits = $TOP5EVENT1_WAITS"
1817 | echoprt " Top 5 Timed Event1 Time ms = $TOP5EVENT1_TIME"
1818 | echoprt " Top 5 Timed Event1 Average = $TOP5EVENT1_AVERAGE"
1819 | echoprt " Top 5 Timed Event1 %DBTime = $TOP5EVENT1_PCT_DBTIME"
1820 | echoprt " Top 5 Timed Event2 Name = $TOP5EVENT2_NAME"
1821 | echoprt " Top 5 Timed Event2 Class = $TOP5EVENT2_CLASS"
1822 | echoprt " Top 5 Timed Event2 Waits = $TOP5EVENT2_WAITS"
1823 | echoprt " Top 5 Timed Event2 Time ms = $TOP5EVENT2_TIME"
1824 | echoprt " Top 5 Timed Event2 Average = $TOP5EVENT2_AVERAGE"
1825 | echoprt " Top 5 Timed Event2 %DBTime = $TOP5EVENT2_PCT_DBTIME"
1826 | echoprt " Top 5 Timed Event3 Name = $TOP5EVENT3_NAME"
1827 | echoprt " Top 5 Timed Event3 Class = $TOP5EVENT3_CLASS"
1828 | echoprt " Top 5 Timed Event3 Waits = $TOP5EVENT3_WAITS"
1829 | echoprt " Top 5 Timed Event3 Time ms = $TOP5EVENT3_TIME"
1830 | echoprt " Top 5 Timed Event3 Average = $TOP5EVENT3_AVERAGE"
1831 | echoprt " Top 5 Timed Event3 %DBTime = $TOP5EVENT3_PCT_DBTIME"
1832 | echoprt " Top 5 Timed Event4 Name = $TOP5EVENT4_NAME"
1833 | echoprt " Top 5 Timed Event4 Class = $TOP5EVENT4_CLASS"
1834 | echoprt " Top 5 Timed Event4 Waits = $TOP5EVENT4_WAITS"
1835 | echoprt " Top 5 Timed Event4 Time ms = $TOP5EVENT4_TIME"
1836 | echoprt " Top 5 Timed Event4 Average = $TOP5EVENT4_AVERAGE"
1837 | echoprt " Top 5 Timed Event4 %DBTime = $TOP5EVENT4_PCT_DBTIME"
1838 | echoprt " Top 5 Timed Event5 Name = $TOP5EVENT5_NAME"
1839 | echoprt " Top 5 Timed Event5 Class = $TOP5EVENT5_CLASS"
1840 | echoprt " Top 5 Timed Event5 Waits = $TOP5EVENT5_WAITS"
1841 | echoprt " Top 5 Timed Event5 Time ms = $TOP5EVENT5_TIME"
1842 | echoprt " Top 5 Timed Event5 Average = $TOP5EVENT5_AVERAGE"
1843 | echoprt " Top 5 Timed Event5 %DBTime = $TOP5EVENT5_PCT_DBTIME"
1844 | echoprt " FG db file sequential read Waits = $WAIT_DFSR_WAITS"
1845 | echoprt " FG db file sequential read Time ms = $WAIT_DFSR_TIME"
1846 | echoprt " FG db file sequential read Average = $WAIT_DFSR_AVERAGE"
1847 | echoprt " FG db file sequential read %DBTime = $WAIT_DFSR_PCT_DBTIME"
1848 | echoprt " FG db file scattered read Waits = $WAIT_DFXR_WAITS"
1849 | echoprt " FG db file scattered read Time ms = $WAIT_DFXR_TIME"
1850 | echoprt " FG db file scattered read Average = $WAIT_DFXR_AVERAGE"
1851 | echoprt " FG db file scattered read %DBTime = $WAIT_DFXR_PCT_DBTIME"
1852 | echoprt " FG direct path read Waits = $WAIT_DPRD_WAITS"
1853 | echoprt " FG direct path read Time ms = $WAIT_DPRD_TIME"
1854 | echoprt " FG direct path read Average = $WAIT_DPRD_AVERAGE"
1855 | echoprt " FG direct path read %DBTime = $WAIT_DPRD_PCT_DBTIME"
1856 | echoprt " FG direct path write Waits = $WAIT_DPWR_WAITS"
1857 | echoprt " FG direct path write Time ms = $WAIT_DPWR_TIME"
1858 | echoprt " FG direct path write Average = $WAIT_DPWR_AVERAGE"
1859 | echoprt " FG direct path write %DBTime = $WAIT_DPWR_PCT_DBTIME"
1860 | echoprt " FG direct path read temp Waits = $WAIT_DPRT_WAITS"
1861 | echoprt " FG direct path read temp Time ms = $WAIT_DPRT_TIME"
1862 | echoprt " FG direct path read temp Average = $WAIT_DPRT_AVERAGE"
1863 | echoprt " FG direct path read temp %DBTime = $WAIT_DPRT_PCT_DBTIME"
1864 | echoprt " FG direct path write temp Waits = $WAIT_DPWT_WAITS"
1865 | echoprt " FG direct path write temp Time ms = $WAIT_DPWT_TIME"
1866 | echoprt " FG direct path write temp Average = $WAIT_DPWT_AVERAGE"
1867 | echoprt " FG direct path write temp %DBTime = $WAIT_DPWT_PCT_DBTIME"
1868 | echoprt " FG log file sync Waits = $WAIT_LFSY_WAITS"
1869 | echoprt " FG log file sync Time ms = $WAIT_LFSY_TIME"
1870 | echoprt " FG log file sync Average = $WAIT_LFSY_AVERAGE"
1871 | echoprt " FG log file sync %DBTime = $WAIT_LFSY_PCT_DBTIME"
1872 | echoprt " BG db file parallel write Waits = $WAIT_DFPW_WAITS"
1873 | echoprt " BG db file parallel write Time ms = $WAIT_DFPW_TIME"
1874 | echoprt " BG db file parallel write Average = $WAIT_DFPW_AVERAGE"
1875 | echoprt " BG db file parallel write %BGTime = $WAIT_DFPW_PCT_DBTIME"
1876 | echoprt " BG log file parallel write Waits = $WAIT_LFPW_WAITS"
1877 | echoprt " BG log file parallel write Time ms = $WAIT_LFPW_TIME"
1878 | echoprt " BG log file parallel write Average = $WAIT_LFPW_AVERAGE"
1879 | echoprt " BG log file parallel write %BGTime = $WAIT_LFPW_PCT_DBTIME"
1880 | echoprt " BG log file sequential read Waits = $WAIT_LFSR_WAITS"
1881 | echoprt " BG log file sequential read Time ms = $WAIT_LFSR_TIME"
1882 | echoprt " BG log file sequential read Average = $WAIT_LFSR_AVERAGE"
1883 | echoprt " BG log file sequential read %BGTime = $WAIT_LFSR_PCT_DBTIME"
1884 | echoprt " OS busy time (sec/100) = $OS_BUSY_TIME"
1885 | echoprt " OS idle time (sec/100) = $OS_IDLE_TIME"
1886 | echoprt " OS iowait time (sec/100) = $OS_IOWAIT_TIME"
1887 | echoprt " OS sys time (sec/100) = $OS_SYS_TIME"
1888 | echoprt " OS user time (sec/100) = $OS_USER_TIME"
1889 | echoprt " OS cpu wait time (sec/100) = $OS_CPU_WAIT_TIME"
1890 | echoprt " OS resource mgr wait time (sec/100) = $OS_RSRC_MGR_WAIT_TIME"
1891 | echoprt " Data Guard in use? = $DATA_GUARD_FLAG"
1892 | echoprt " Exadata in use? = $EXADATA_FLAG"
1893 | echoprt " Wait Class Admin Num Waits = $WCLASS_ADMIN_NUM_WAITS"
1894 | echoprt " Wait Class Admin Wait Time = $WCLASS_ADMIN_WAIT_TIME"
1895 | echoprt " Wait Class Admin Latency ms = $WCLASS_ADMIN_AVEWAIT"
1896 | echoprt " Wait Class Admin %DBTime = $WCLASS_ADMIN_PCT_DBTIME"
1897 | echoprt " Wait Class Application Num Waits = $WCLASS_APPLN_NUM_WAITS"
1898 | echoprt " Wait Class Application Wait Time = $WCLASS_APPLN_WAIT_TIME"
1899 | echoprt " Wait Class Application Latency ms = $WCLASS_APPLN_AVEWAIT"
1900 | echoprt " Wait Class Application %DBTime = $WCLASS_APPLN_PCT_DBTIME"
1901 | echoprt " Wait Class Cluster Num Waits = $WCLASS_CLSTR_NUM_WAITS"
1902 | echoprt " Wait Class Cluster Wait Time = $WCLASS_CLSTR_WAIT_TIME"
1903 | echoprt " Wait Class Cluster Latency ms = $WCLASS_CLSTR_AVEWAIT"
1904 | echoprt " Wait Class Cluster %DBTime = $WCLASS_CLSTR_PCT_DBTIME"
1905 | echoprt " Wait Class Commit Num Waits = $WCLASS_COMMT_NUM_WAITS"
1906 | echoprt " Wait Class Commit Wait Time = $WCLASS_COMMT_WAIT_TIME"
1907 | echoprt " Wait Class Commit Latency ms = $WCLASS_COMMT_AVEWAIT"
1908 | echoprt " Wait Class Commit %DBTime = $WCLASS_COMMT_PCT_DBTIME"
1909 | echoprt " Wait Class Concurrency Num Waits = $WCLASS_CNCUR_NUM_WAITS"
1910 | echoprt " Wait Class Concurrency Wait Time = $WCLASS_CNCUR_WAIT_TIME"
1911 | echoprt " Wait Class Concurrency Latency ms = $WCLASS_CNCUR_AVEWAIT"
1912 | echoprt " Wait Class Concurrency %DBTime = $WCLASS_CNCUR_PCT_DBTIME"
1913 | echoprt " Wait Class Configuration Num Waits = $WCLASS_CONFG_NUM_WAITS"
1914 | echoprt " Wait Class Configuration Wait Time = $WCLASS_CONFG_WAIT_TIME"
1915 | echoprt " Wait Class Configuration Latency ms = $WCLASS_CONFG_AVEWAIT"
1916 | echoprt " Wait Class Configuration %DBTime = $WCLASS_CONFG_PCT_DBTIME"
1917 | echoprt " Wait Class Network Num Waits = $WCLASS_NETWK_NUM_WAITS"
1918 | echoprt " Wait Class Network Wait Time = $WCLASS_NETWK_WAIT_TIME"
1919 | echoprt " Wait Class Network Latency ms = $WCLASS_NETWK_AVEWAIT"
1920 | echoprt " Wait Class Network %DBTime = $WCLASS_NETWK_PCT_DBTIME"
1921 | echoprt " Wait Class Other Num Waits = $WCLASS_OTHER_NUM_WAITS"
1922 | echoprt " Wait Class Other Wait Time = $WCLASS_OTHER_WAIT_TIME"
1923 | echoprt " Wait Class Other Latency ms = $WCLASS_OTHER_AVEWAIT"
1924 | echoprt " Wait Class Other %DBTime = $WCLASS_OTHER_PCT_DBTIME"
1925 | echoprt " Wait Class System IO Num Waits = $WCLASS_SYSIO_NUM_WAITS"
1926 | echoprt " Wait Class System IO Wait Time = $WCLASS_SYSIO_WAIT_TIME"
1927 | echoprt " Wait Class System IO Latency ms = $WCLASS_SYSIO_AVEWAIT"
1928 | echoprt " Wait Class System IO %DBTime = $WCLASS_SYSIO_PCT_DBTIME"
1929 | echoprt " Histogram db file sequential read <1ms = $HGRM_DFSR_1MS"
1930 | echoprt " Histogram db file sequential read <2ms = $HGRM_DFSR_2MS"
1931 | echoprt " Histogram db file sequential read <4ms = $HGRM_DFSR_4MS"
1932 | echoprt " Histogram db file sequential read <8ms = $HGRM_DFSR_8MS"
1933 | echoprt " Histogram db file sequential read <16ms = $HGRM_DFSR_16MS"
1934 | echoprt " Histogram db file sequential read <32ms = $HGRM_DFSR_32MS"
1935 | echoprt " Histogram db file sequential read <1s = $HGRM_DFSR_LT1S"
1936 | echoprt " Histogram db file sequential read >1s = $HGRM_DFSR_GT1S"
1937 | echoprt " Histogram log file parallel write <1ms = $HGRM_LFPW_1MS"
1938 | echoprt " Histogram log file parallel write <2ms = $HGRM_LFPW_2MS"
1939 | echoprt " Histogram log file parallel write <4ms = $HGRM_LFPW_4MS"
1940 | echoprt " Histogram log file parallel write <8ms = $HGRM_LFPW_8MS"
1941 | echoprt " Histogram log file parallel write <16ms = $HGRM_LFPW_16MS"
1942 | echoprt " Histogram log file parallel write <32ms = $HGRM_LFPW_32MS"
1943 | echoprt " Histogram log file parallel write <1s = $HGRM_LFPW_LT1S"
1944 | echoprt " Histogram log file parallel write >1s = $HGRM_LFPW_GT1S"
1945 | }
1946 |
1947 | # Start of main program - check that parameters have been passed in
1948 | echo "" 1>&2
1949 | [[ "$#" -eq 0 ]] && usage
1950 |
1951 | # Process calling parameters
1952 | while getopts ":hHnpsvX" opt; do
1953 | case $opt in
1954 | h)
1955 | # Print usage information and then exit
1956 | usage
1957 | ;;
1958 | H)
1959 | # Print the header row and then exit
1960 | [[ "$HEADERROW" = 0 ]] && usage "Header and NoHeader are conflicting options"
1961 | HEADERROW=2
1962 | ;;
1963 | n)
1964 | # Do not print the header row in the CSV file
1965 | [[ "$HEADERROW" = 2 ]] && usage "Header and NoHeader are conflicting options"
1966 | HEADERROW=0
1967 | ;;
1968 | p)
1969 | [[ "$SILENT" = 1 ]] && usage "Silent and Print Report Info are conflicting options"
1970 | PRINT_REPORT_INFO=1
1971 | ;;
1972 | s)
1973 | [[ "$VERBOSE" = 1 ]] && usage "Silent and Verbose are conflicting options"
1974 | [[ "$PRINT_REPORT_INFO" = 1 ]] && usage "Silent and Print Report Info are conflicting options"
1975 | SILENT=1
1976 | ;;
1977 | v)
1978 | [[ "$SILENT" = 1 ]] && usage "Silent and Verbose are conflicting options"
1979 | VERBOSE=1
1980 | PRINT_REPORT_INFO=1
1981 | echovrb "Running in verbose mode"
1982 | ;;
1983 | X)
1984 | DEBUG=1
1985 | echodbg "Running in debug mode - expect lots of output..."
1986 | ;;
1987 | \?)
1988 | usage "Invalid option -$OPTARG"
1989 | ;;
1990 | esac
1991 | done
1992 |
1993 | # If debug mode enabled, automatically enable verbose mode and disable silent mode
1994 | if [ "$DEBUG" = 1 ]; then
1995 | VERBOSE=1
1996 | SILENT=0
1997 | # Add an field terminator for use with debugging the contents of variables
1998 | ENDCHAR="|"
1999 | echodbg "Script called with parameters: $*"
2000 | fi
2001 |
2002 | # Determine if we are just printing the header row and then exiting
2003 | if [ "$HEADERROW" = 2 ]; then
2004 | echoinf "Printing header row and then exiting (found -H flag)"
2005 | print_header_row
2006 | exit $EXIT_SUCCESS
2007 | fi
2008 |
2009 | # Check that basic calculator is installed, otherwise exit with error
2010 | command -v bc >/dev/null 2>&1
2011 | if [ "$?" = 0 ]; then
2012 | echodbg "Found basic calculator installed in path $PATH"
2013 | else
2014 | echovrb "Basic Calculator not found in path $PATH"
2015 | echoerr "Basic Calculator (bc) not found - see Appendix in Manual if using Cygwin"
2016 | exit $EXIT_FAILURE
2017 | fi
2018 |
2019 | # Set Internal Field Seperator to be word delimited
2020 | set_ifs_to_word_delimited
2021 |
2022 | # Once switches have been processed, check filenames have been passed in too
2023 | shift $(($OPTIND - 1))
2024 | [[ "$#" -eq 0 ]] && usage "Filename(s) required"
2025 |
2026 | # Determine if we should print the header row as the first line of the CSV file
2027 | if [ "$HEADERROW" = 1 ]; then
2028 | echovrb "Printing header row"
2029 | print_header_row
2030 | else
2031 | echoinf "Printing of header row disabled with -n flag"
2032 | fi
2033 |
2034 | # Main loop - Iterate through all files
2035 | while (( "$#" )); do
2036 | let FILECNT++
2037 | # Check file is readable
2038 | if [ -r "$1" ]; then
2039 | AWRFILE=$1
2040 | echovrb " "
2041 | echoinf "Parsing file $AWRFILE at `date +'%F %T'`"
2042 | # Perform checks to ensure file is an AWR report but not in HTML format
2043 | CHECK_HTML=$(sed -n -e '1,5 p' $AWRFILE | grep -i "" | wc -l)
2044 | CHECK_STATSPACK=$(sed -n -e '1,5 p' $AWRFILE | grep STATSPACK | wc -l)
2045 | CHECK_AWR=$(sed -n -e '1,5 p' $AWRFILE | grep "WORKLOAD REPOSITORY" | wc -l)
2046 | if [ "$CHECK_HTML" -gt "0" ]; then
2047 | # File was in HTML format
2048 | echoerr "$1 is in HTML format - ignoring..."
2049 | elif [ "$CHECK_STATSPACK" -gt "0" ]; then
2050 | # File was STATSPACK and not AWR Report
2051 | echoerr "$1 is a STATSPACK file - ignoring..."
2052 | elif [ "$CHECK_AWR" -gt "0" ]; then
2053 | # Reset global variables
2054 | unset PROFILE_DBNAME PROFILE_INSTANCENUM PROFILE_INSTANCENAME PROFILE_DBVERSION PROFILE_CLUSTER DB_HOSTNAME DB_HOST_OS DB_NUM_CPUS DB_HOST_MEM DB_BLOCK_SIZE AWR_BEGIN_SNAP AWR_BEGIN_TIME AWR_END_SNAP AWR_END_TIME AWR_ELAPSED_TIME AWR_ELAPSED_TIME_SECS AWR_DB_TIME AWR_AAS AWR_BUSY_FLAG AWR_LOGICAL_READS AWR_BLOCK_CHANGES READ_IOPS DATA_WRITE_IOPS REDO_WRITE_IOPS ALL_WRITE_IOPS TOTAL_IOPS READ_THROUGHPUT DATA_WRITE_THROUGHPUT REDO_WRITE_THROUGHPUT ALL_WRITE_THROUGHPUT TOTAL_THROUGHPUT AWR_DB_CPU AWR_DB_CPU_PCT_DBTIME WCLASS_USRIO_NUM_WAITS WCLASS_USRIO_WAIT_TIME WCLASS_USRIO_AVEWAIT WCLASS_USRIO_PCT_DBTIME AWR_USER_CALLS AWR_PARSES AWR_HARD_PARSES AWR_LOGONS AWR_EXECUTES AWR_TRANSACTIONS BUFFER_HIT_RATIO INMEMORY_SORT_RATIO AWR_LOG_SWITCHES_TOTAL AWR_LOG_SWITCHES_PERHOUR
2055 | unset TOP5EVENT1_NAME TOP5EVENT1_CLASS TOP5EVENT1_WAITS TOP5EVENT1_TIME TOP5EVENT1_AVERAGE TOP5EVENT1_PCT_DBTIME TOP5EVENT2_NAME TOP5EVENT2_CLASS TOP5EVENT2_WAITS TOP5EVENT2_TIME TOP5EVENT2_AVERAGE TOP5EVENT2_PCT_DBTIME TOP5EVENT3_NAME TOP5EVENT3_CLASS TOP5EVENT3_WAITS TOP5EVENT3_TIME TOP5EVENT3_AVERAGE TOP5EVENT3_PCT_DBTIME TOP5EVENT4_NAME TOP5EVENT4_CLASS TOP5EVENT4_WAITS TOP5EVENT4_TIME TOP5EVENT4_AVERAGE TOP5EVENT4_PCT_DBTIME TOP5EVENT5_NAME TOP5EVENT5_CLASS TOP5EVENT5_WAITS TOP5EVENT5_TIME TOP5EVENT5_AVERAGE TOP5EVENT5_PCT_DBTIME
2056 | unset WAIT_DFSR_WAITS WAIT_DFSR_TIME WAIT_DFSR_AVERAGE WAIT_DFSR_PCT_DBTIME WAIT_DFXR_WAITS WAIT_DFXR_TIME WAIT_DFXR_AVERAGE WAIT_DFXR_PCT_DBTIME WAIT_DPRD_WAITS WAIT_DPRD_TIME WAIT_DPRD_AVERAGE WAIT_DPRD_PCT_DBTIME WAIT_DPWR_WAITS WAIT_DPWR_TIME WAIT_DPWR_AVERAGE WAIT_DPWR_PCT_DBTIME WAIT_DPRT_WAITS WAIT_DPRT_TIME WAIT_DPRT_AVERAGE WAIT_DPRT_PCT_DBTIME WAIT_DPWT_WAITS WAIT_DPWT_TIME WAIT_DPWT_AVERAGE WAIT_DPWT_PCT_DBTIME WAIT_LFSY_WAITS WAIT_LFSY_TIME WAIT_LFSY_AVERAGE WAIT_LFSY_PCT_DBTIME WAIT_DFPW_WAITS WAIT_DFPW_TIME WAIT_DFPW_AVERAGE WAIT_DFPW_PCT_DBTIME WAIT_LFPW_WAITS WAIT_LFPW_TIME WAIT_LFPW_AVERAGE WAIT_LFPW_PCT_DBTIME WAIT_LFSR_WAITS WAIT_LFSR_TIME WAIT_LFSR_AVERAGE WAIT_LFSR_PCT_DBTIME
2057 | unset OS_BUSY_TIME OS_IDLE_TIME OS_IOWAIT_TIME OS_SYS_TIME OS_USER_TIME OS_CPU_WAIT_TIME OS_RSRC_MGR_WAIT_TIME DATA_GUARD_FLAG EXADATA_FLAG WCLASS_ADMIN_NUM_WAITS WCLASS_ADMIN_WAIT_TIME WCLASS_ADMIN_AVEWAIT WCLASS_ADMIN_PCT_DBTIME WCLASS_APPLN_NUM_WAITS WCLASS_APPLN_WAIT_TIME WCLASS_APPLN_AVEWAIT WCLASS_APPLN_PCT_DBTIME WCLASS_CLSTR_NUM_WAITS WCLASS_CLSTR_WAIT_TIME WCLASS_CLSTR_AVEWAIT WCLASS_CLSTR_PCT_DBTIME WCLASS_COMMT_NUM_WAITS WCLASS_COMMT_WAIT_TIME WCLASS_COMMT_AVEWAIT WCLASS_COMMT_PCT_DBTIME WCLASS_CNCUR_NUM_WAITS WCLASS_CNCUR_WAIT_TIME WCLASS_CNCUR_AVEWAIT WCLASS_CNCUR_PCT_DBTIME WCLASS_CONFG_NUM_WAITS WCLASS_CONFG_WAIT_TIME WCLASS_CONFG_AVEWAIT WCLASS_CONFG_PCT_DBTIME WCLASS_NETWK_NUM_WAITS WCLASS_NETWK_WAIT_TIME WCLASS_NETWK_AVEWAIT WCLASS_NETWK_PCT_DBTIME WCLASS_OTHER_NUM_WAITS WCLASS_OTHER_WAIT_TIME WCLASS_OTHER_AVEWAIT WCLASS_OTHER_PCT_DBTIME WCLASS_SYSIO_NUM_WAITS WCLASS_SYSIO_WAIT_TIME WCLASS_SYSIO_AVEWAIT WCLASS_SYSIO_PCT_DBTIME
2058 | unset HGRM_DFSR_1MS HGRM_DFSR_2MS HGRM_DFSR_4MS HGRM_DFSR_8MS HGRM_DFSR_16MS HGRM_DFSR_32MS HGRM_DFSR_LT1S HGRM_DFSR_GT1S HGRM_LFPW_1MS HGRM_LFPW_2MS HGRM_LFPW_4MS HGRM_LFPW_8MS HGRM_LFPW_16MS HGRM_LFPW_32MS HGRM_LFPW_LT1S HGRM_LFPW_GT1S
2059 | # Set Data Guard and Exadata flags to N
2060 | DATA_GUARD_FLAG="N"
2061 | EXADATA_FLAG="N"
2062 | # Strip any path from filename
2063 | AWRFILENAME=`basename $AWRFILE`
2064 | # Harvest data from report
2065 | process_awr_report
2066 | # Print harvested information to errinf function
2067 | [[ "$PRINT_REPORT_INFO" = 1 ]] && print_report_info
2068 | # Write values to CSV file
2069 | echocsv "$AWRFILENAME,$PROFILE_DBNAME,$PROFILE_INSTANCENUM,$PROFILE_INSTANCENAME,$PROFILE_DBVERSION,$PROFILE_CLUSTER,$DB_HOSTNAME,$DB_HOST_OS,$DB_NUM_CPUS,$DB_HOST_MEM,$DB_BLOCK_SIZE,$AWR_BEGIN_SNAP,$AWR_BEGIN_TIME,$AWR_END_SNAP,$AWR_END_TIME,$AWR_ELAPSED_TIME,$AWR_DB_TIME,$AWR_AAS,$AWR_BUSY_FLAG,$AWR_LOGICAL_READS,$AWR_BLOCK_CHANGES,$READ_IOPS,$DATA_WRITE_IOPS,$REDO_WRITE_IOPS,$ALL_WRITE_IOPS,$TOTAL_IOPS,$READ_THROUGHPUT,$DATA_WRITE_THROUGHPUT,$REDO_WRITE_THROUGHPUT,$ALL_WRITE_THROUGHPUT,$TOTAL_THROUGHPUT,$AWR_DB_CPU,$AWR_DB_CPU_PCT_DBTIME,$WCLASS_USRIO_NUM_WAITS,$WCLASS_USRIO_WAIT_TIME,$WCLASS_USRIO_AVEWAIT,$WCLASS_USRIO_PCT_DBTIME,$AWR_USER_CALLS,$AWR_PARSES,$AWR_HARD_PARSES,$AWR_LOGONS,$AWR_EXECUTES,$AWR_TRANSACTIONS,$BUFFER_HIT_RATIO,$INMEMORY_SORT_RATIO,$AWR_LOG_SWITCHES_TOTAL,$AWR_LOG_SWITCHES_PERHOUR,$TOP5EVENT1_NAME,$TOP5EVENT1_CLASS,$TOP5EVENT1_WAITS,$TOP5EVENT1_TIME,$TOP5EVENT1_AVERAGE,$TOP5EVENT1_PCT_DBTIME,$TOP5EVENT2_NAME,$TOP5EVENT2_CLASS,$TOP5EVENT2_WAITS,$TOP5EVENT2_TIME,$TOP5EVENT2_AVERAGE,$TOP5EVENT2_PCT_DBTIME,$TOP5EVENT3_NAME,$TOP5EVENT3_CLASS,$TOP5EVENT3_WAITS,$TOP5EVENT3_TIME,$TOP5EVENT3_AVERAGE,$TOP5EVENT3_PCT_DBTIME,$TOP5EVENT4_NAME,$TOP5EVENT4_CLASS,$TOP5EVENT4_WAITS,$TOP5EVENT4_TIME,$TOP5EVENT4_AVERAGE,$TOP5EVENT4_PCT_DBTIME,$TOP5EVENT5_NAME,$TOP5EVENT5_CLASS,$TOP5EVENT5_WAITS,$TOP5EVENT5_TIME,$TOP5EVENT5_AVERAGE,$TOP5EVENT5_PCT_DBTIME,$WAIT_DFSR_WAITS,$WAIT_DFSR_TIME,$WAIT_DFSR_AVERAGE,$WAIT_DFSR_PCT_DBTIME,$WAIT_DFXR_WAITS,$WAIT_DFXR_TIME,$WAIT_DFXR_AVERAGE,$WAIT_DFXR_PCT_DBTIME,$WAIT_DPRD_WAITS,$WAIT_DPRD_TIME,$WAIT_DPRD_AVERAGE,$WAIT_DPRD_PCT_DBTIME,$WAIT_DPWR_WAITS,$WAIT_DPWR_TIME,$WAIT_DPWR_AVERAGE,$WAIT_DPWR_PCT_DBTIME,$WAIT_DPRT_WAITS,$WAIT_DPRT_TIME,$WAIT_DPRT_AVERAGE,$WAIT_DPRT_PCT_DBTIME,$WAIT_DPWT_WAITS,$WAIT_DPWT_TIME,$WAIT_DPWT_AVERAGE,$WAIT_DPWT_PCT_DBTIME,$WAIT_LFSY_WAITS,$WAIT_LFSY_TIME,$WAIT_LFSY_AVERAGE,$WAIT_LFSY_PCT_DBTIME,$WAIT_DFPW_WAITS,$WAIT_DFPW_TIME,$WAIT_DFPW_AVERAGE,$WAIT_DFPW_PCT_DBTIME,$WAIT_LFPW_WAITS,$WAIT_LFPW_TIME,$WAIT_LFPW_AVERAGE,$WAIT_LFPW_PCT_DBTIME,$WAIT_LFSR_WAITS,$WAIT_LFSR_TIME,$WAIT_LFSR_AVERAGE,$WAIT_LFSR_PCT_DBTIME,$OS_BUSY_TIME,$OS_IDLE_TIME,$OS_IOWAIT_TIME,$OS_SYS_TIME,$OS_USER_TIME,$OS_CPU_WAIT_TIME,$OS_RSRC_MGR_WAIT_TIME,$DATA_GUARD_FLAG,$EXADATA_FLAG,$WCLASS_ADMIN_NUM_WAITS,$WCLASS_ADMIN_WAIT_TIME,$WCLASS_ADMIN_AVEWAIT,$WCLASS_ADMIN_PCT_DBTIME,$WCLASS_APPLN_NUM_WAITS,$WCLASS_APPLN_WAIT_TIME,$WCLASS_APPLN_AVEWAIT,$WCLASS_APPLN_PCT_DBTIME,$WCLASS_CLSTR_NUM_WAITS,$WCLASS_CLSTR_WAIT_TIME,$WCLASS_CLSTR_AVEWAIT,$WCLASS_CLSTR_PCT_DBTIME,$WCLASS_COMMT_NUM_WAITS,$WCLASS_COMMT_WAIT_TIME,$WCLASS_COMMT_AVEWAIT,$WCLASS_COMMT_PCT_DBTIME,$WCLASS_CNCUR_NUM_WAITS,$WCLASS_CNCUR_WAIT_TIME,$WCLASS_CNCUR_AVEWAIT,$WCLASS_CNCUR_PCT_DBTIME,$WCLASS_CONFG_NUM_WAITS,$WCLASS_CONFG_WAIT_TIME,$WCLASS_CONFG_AVEWAIT,$WCLASS_CONFG_PCT_DBTIME,$WCLASS_NETWK_NUM_WAITS,$WCLASS_NETWK_WAIT_TIME,$WCLASS_NETWK_AVEWAIT,$WCLASS_NETWK_PCT_DBTIME,$WCLASS_OTHER_NUM_WAITS,$WCLASS_OTHER_WAIT_TIME,$WCLASS_OTHER_AVEWAIT,$WCLASS_OTHER_PCT_DBTIME,$WCLASS_SYSIO_NUM_WAITS,$WCLASS_SYSIO_WAIT_TIME,$WCLASS_SYSIO_AVEWAIT,$WCLASS_SYSIO_PCT_DBTIME,$HGRM_DFSR_1MS,$HGRM_DFSR_2MS,$HGRM_DFSR_4MS,$HGRM_DFSR_8MS,$HGRM_DFSR_16MS,$HGRM_DFSR_32MS,$HGRM_DFSR_LT1S,$HGRM_DFSR_GT1S,$HGRM_LFPW_1MS,$HGRM_LFPW_2MS,$HGRM_LFPW_4MS,$HGRM_LFPW_8MS,$HGRM_LFPW_16MS,$HGRM_LFPW_32MS,$HGRM_LFPW_LT1S,$HGRM_LFPW_GT1S"
2070 | else
2071 | # File was not an AWR report
2072 | echoerr "$1 is not an AWR file"
2073 | fi
2074 | else
2075 | # File was not readable so throw error
2076 | echoerr "Cannot read file $1 - ignoring..."
2077 | fi
2078 | shift
2079 |
2080 | done
2081 |
2082 | echoinf "No more files found"
2083 | # Print summary information
2084 | echoinf ""
2085 | echoinf "______SUMMARY______"
2086 | echoinf "Files found : $FILECNT"
2087 | echoinf "Files processed : $(($FILECNT - $ERRORCNT))"
2088 | echoinf "Processing errors : $ERRORCNT"
2089 | echoinf ""
2090 |
2091 | # Calculate exit status and then exit
2092 | if [ "$FILECNT" -eq 0 ]; then
2093 | echoinf "Completed with no files processes"
2094 | exit $EXIT_FAILURE
2095 | elif [ "$ERRORCNT" -gt 0 ]; then
2096 | echoinf "Completed with $ERRORCNT errors"
2097 | exit $EXIT_PARTIAL_SUCCESS
2098 | else
2099 | echoinf "Completed successfully"
2100 | exit $EXIT_SUCCESS
2101 | fi
2102 | # EOF
2103 |
--------------------------------------------------------------------------------
/setup-kaminario-mpath.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # setup-kaminario-mpath.sh - script for configuring the multipath.conf file with Kaminario devices
3 | # Author: flashdba (http://flashdba.com)
4 | # The output can be cut and pasted into the "multipaths {}" section of /etc/multipath.conf
5 | # Alternatively the -l option can be used to print a list of devices
6 | #
7 | # For educational purposes only - no warranty is provided
8 | # Test thoroughly - use at your own risk
9 |
10 | # TODO: Currently only written for use with Red Hat 6 / Oracle Linux 6 / SLES 11
11 |
12 | # Setup variables and arrays
13 | VERBOSE=0
14 | LISTMODE=0
15 | MULTIPATH_DEVICES=()
16 |
17 | # Setup print functions
18 | echoerr() { echo "Error: $@" 1>&2; }
19 | echovrb() { [[ "$VERBOSE" = 1 ]] && echo "Info : ${@}" 1>&2; }
20 | echoout() { echo "$@"; }
21 | echolst() { echo "$@" | tr '±' '\t' | expand -t 5 1>&2; }
22 |
23 | # Function for printing usage information
24 | usage() {
25 | echo "" 1>&2
26 | if [ "$#" -gt 0 ]; then
27 | echo "Error: $@" 1>&2
28 | echo "" 1>&2
29 | fi
30 | echo "Usage: $0 [-v ]" 1>&2
31 | echo "" 1>&2
32 | echo " Script for configuring the /etc/multipath.conf file" 1>&2
33 | echo " Creates entries for the \"multipath \{\}\" section" 1>&2
34 | echo " Requires the sg3_utils package to be present" 1>&2
35 | echo " Errors and info are printed to stderr" 1>&2
36 | echo "" 1>&2
37 | echo " Options:" 1>&2
38 | echo " -h Help (print help and version information)" 1>&2
39 | echo " -l List (print a list of devices and their details)" 1>&2
40 | echo " -v Verbose (show processing details)" 1>&2
41 | echo "" 1>&2
42 | exit 1
43 | }
44 |
45 | while getopts ":hvl" opt; do
46 | case $opt in
47 | h)
48 | usage
49 | ;;
50 | v)
51 | VERBOSE=1
52 | echovrb "Running in verbose mode"
53 | ;;
54 | l)
55 | LISTMODE=1
56 | echovrb "Running in list mode"
57 | ;;
58 | \?)
59 | echo "Invalid option: -$OPTARG" >&2
60 | usage
61 | ;;
62 | esac
63 | done
64 |
65 | # Check that the s3_utils package has been installed and is in the path
66 | if hash sg_inq 2> /dev/null; then
67 | echovrb "Using sg_inq `sg_inq -V 2>&1`"
68 | else
69 | echoerr "sg3_utils package not installed - exiting..."
70 | exit 1
71 | fi
72 |
73 | # Build a list of multipath devices to scan
74 | MULTIPATH_FILELIST=$( ls -1 /dev/dm-* )
75 |
76 | # Iterate through the list
77 | for MPDEVICE in $MULTIPATH_FILELIST; do
78 |
79 | echovrb "Issuing inquiry to device $MPDEVICE"
80 |
81 | # Issue sg3 inquiry to device
82 | SG3_OUTPUT=`sg_inq -i $MPDEVICE 2> /dev/null`
83 | SG3_RETVAL=$?
84 |
85 | # If inquiry returned error code then skip
86 | if [ "$SG3_RETVAL" -ne 0 ]; then
87 | echovrb "Skipping device $MPDEVICE"
88 | continue
89 | fi
90 |
91 | # Scan output to find vendor id
92 | SG3_VENDORID=`echo "$SG3_OUTPUT" | grep "vendor id:" | cut -d':' -f2- | sed 's/^ *//g' | sed 's/ *$//g' ` 2> /dev/null
93 |
94 | # Check the vendor is KMNRIO otherwise skip
95 | if [ "$SG3_VENDORID" != "KMNRIO" ]; then
96 | echovrb "Ignoring device on $MPDEVICE with vendor id = $SG3_VENDORID"
97 | continue
98 | fi
99 |
100 | # Get the sysfs device location (required for udevinfo)
101 | MPATH_DEVBASE=`basename $MPDEVICE`
102 | MPATH_SYSFS="/block/$MPATH_DEVBASE"
103 |
104 | # Process device specific details
105 | LUN_NAME=`echo "$SG3_OUTPUT" | grep "vendor specific:" | awk '{print ($3)}'`
106 | LUN_UUID=`udevadm info --query=property --path=$MPATH_SYSFS 2> /dev/null | grep "DM_UUID=" | sed 's/^DM_UUID=mpath-*//g'`
107 | echovrb "Found Kaminario device on $MPDEVICE: LUN Name = $LUN_NAME UUID = $LUN_UUID"
108 |
109 | # Add details to an array variable of Kaminario devices
110 | MULTIPATH_DEVICES+=(`echo "$LUN_NAME:$LUN_UUID:$MPDEVICE"`)
111 | done
112 |
113 | # Sort the array into alphabetical order based on LUN name
114 | echovrb "Sorting discovered devices into alphabetical order..."
115 | MULTIPATH_DEVICES=($(for MPDEVICE in ${MULTIPATH_DEVICES[@]}; do
116 | echo $MPDEVICE
117 | done | sort))
118 | echovrb "Sort complete"
119 |
120 | if [ "$LISTMODE" = 1 ]; then
121 | echolst "Device Name±LUN Name±WWID"
122 | echolst "-----------±--------±----------------------------------"
123 | else
124 | if [ -r /etc/multipath.conf ]; then
125 | echovrb "Backup up /etc/multipath.conf to /tmp"
126 | cp /etc/multipath.conf /tmp
127 | fi
128 | fi
129 |
130 | echovrb "Printing multipath.conf configuration details..."
131 | echovrb ""
132 |
133 | # Now print the multipath.conf output for each device, converting the LUN name to lowercase
134 | for MPDEVICE in ${MULTIPATH_DEVICES[@]}; do
135 | MP_WWID=`echo $MPDEVICE | cut -d':' -f2`
136 | MP_ALIAS=`echo $MPDEVICE | cut -d':' -f1 | tr '[:upper:]' '[:lower:]'`
137 | MP_DEVNAME=`echo $MPDEVICE | cut -d':' -f3`
138 |
139 | if [ "$LISTMODE" = 1 ]; then
140 | echolst "$MP_DEVNAME ±$MP_ALIAS±$MP_WWID"
141 | else
142 | echoout " multipath {"
143 | echoout " wwid $MP_WWID"
144 | echoout " alias $MP_ALIAS"
145 | echoout " }"
146 | fi
147 | done
148 |
149 | echovrb "Successful completion"
150 | exit 0
151 |
--------------------------------------------------------------------------------
/setup-violin-mpath.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # setup-violin-mpath.sh : script for configuring the multipath.conf file with Violin devices
4 | # The output can be cut and pasted into the "multipaths {}" section
5 | # of /etc/multipath.conf or alternatively the -l option can be used
6 | # to print a list of devices
7 | #
8 | # See GitHub repository at https://github.com/flashdba/scripts
9 | #
10 | # ###########################################################################
11 | # # #
12 | # # Copyright (C) {2014,2015} Author: flashdba (http://flashdba.com) #
13 | # # #
14 | # # This program is free software; you can redistribute it and/or modify #
15 | # # it under the terms of the GNU General Public License as published by #
16 | # # the Free Software Foundation; either version 2 of the License, or #
17 | # # (at your option) any later version. #
18 | # # #
19 | # # This program is distributed in the hope that it will be useful, #
20 | # # but WITHOUT ANY WARRANTY; without even the implied warranty of #
21 | # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
22 | # # GNU General Public License for more details. #
23 | # # #
24 | # # You should have received a copy of the GNU General Public License along #
25 | # # with this program; if not, write to the Free Software Foundation, Inc., #
26 | # # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #
27 | # # #
28 | # ###########################################################################
29 |
30 | # TODO: Currently only written for use with Red Hat 6 / Oracle Linux 6 / SLES 11
31 |
32 | # Setup variables and arrays
33 | VERBOSE=0
34 | LISTMODE=0
35 | MULTIPATH_DEVICES=()
36 |
37 | # Setup print functions
38 | echoerr() { echo "Error: $@" 1>&2; }
39 | echovrb() { [[ "$VERBOSE" = 1 ]] && echo "Info : ${@}" 1>&2; }
40 | echoout() { echo "$@"; }
41 | echolst() { echo "$@" | tr '±' '\t' | expand -t 5 1>&2; }
42 |
43 | # Function for printing usage information
44 | usage() {
45 | echo "" 1>&2
46 | if [ "$#" -gt 0 ]; then
47 | echo "Error: $@" 1>&2
48 | echo "" 1>&2
49 | fi
50 | echo "Usage: $0 [-v ]" 1>&2
51 | echo "" 1>&2
52 | echo " Script for configuring the /etc/multipath.conf file" 1>&2
53 | echo " Creates entries for the \"multipath \{\}\" section" 1>&2
54 | echo " Requires the sg3_utils package to be present" 1>&2
55 | echo " Errors and info are printed to stderr" 1>&2
56 | echo "" 1>&2
57 | echo " Options:" 1>&2
58 | echo " -h Help (print help and version information)" 1>&2
59 | echo " -l List (print a list of devices and their details)" 1>&2
60 | echo " -v Verbose (show processing details)" 1>&2
61 | echo "" 1>&2
62 | exit 1
63 | }
64 |
65 | while getopts ":hvl" opt; do
66 | case $opt in
67 | h)
68 | usage
69 | ;;
70 | v)
71 | VERBOSE=1
72 | echovrb "Running in verbose mode"
73 | ;;
74 | l)
75 | LISTMODE=1
76 | echovrb "Running in list mode"
77 | ;;
78 | \?)
79 | echo "Invalid option: -$OPTARG" >&2
80 | usage
81 | ;;
82 | esac
83 | done
84 |
85 | # Check that the s3_utils package has been installed and is in the path
86 | if hash sg_inq 2> /dev/null; then
87 | echovrb "Using sg_inq `sg_inq -V 2>&1`"
88 | else
89 | echoerr "sg3_utils package not installed - exiting..."
90 | exit 1
91 | fi
92 |
93 | # Build a list of multipath devices to scan
94 | MULTIPATH_FILELIST=$( ls -1 /dev/dm-* )
95 |
96 | # Iterate through the list
97 | for MPDEVICE in $MULTIPATH_FILELIST; do
98 |
99 | echovrb "Issuing inquiry to device $MPDEVICE"
100 |
101 | # Issue sg3 inquiry to device
102 | SG3_OUTPUT=`sg_inq -i $MPDEVICE 2> /dev/null`
103 | SG3_RETVAL=$?
104 |
105 | # If inquiry returned error code then skip
106 | if [ "$SG3_RETVAL" -ne 0 ]; then
107 | echovrb "Skipping device $MPDEVICE"
108 | continue
109 | fi
110 |
111 | # Scan output to find vendor id
112 | SG3_VENDORID=`echo "$SG3_OUTPUT" | grep "vendor id:" | cut -d':' -f2- | sed 's/^ *//g' | sed 's/ *$//g' ` 2> /dev/null
113 |
114 | # Check the vendor is VIOLIN otherwise skip
115 | if [ "$SG3_VENDORID" != "VIOLIN" ]; then
116 | echovrb "Ignoring device on $MPDEVICE with vendor id = $SG3_VENDORID"
117 | continue
118 | fi
119 |
120 | # Get the sysfs device location (required for udevinfo)
121 | MPATH_DEVBASE=`basename $MPDEVICE`
122 | MPATH_SYSFS="/block/$MPATH_DEVBASE"
123 |
124 | # Process device specific details
125 | LUN_CONTAINER=`echo "$SG3_OUTPUT" | grep "vendor specific:" | cut -d':' -f2 | sed 's/^ *//g'`
126 | LUN_NAME=`echo "$SG3_OUTPUT" | grep "vendor specific:" | cut -d':' -f3`
127 | LUN_SERIAL=`echo "$SG3_OUTPUT" | grep "vendor specific:" | cut -d':' -f4`
128 | LUN_UUID=`udevadm info --query=property --path=$MPATH_SYSFS 2> /dev/null | grep "DM_UUID=" | sed 's/^DM_UUID=mpath-*//g'`
129 | echovrb "Found Violin device on $MPDEVICE: Container = $LUN_CONTAINER LUN Name = $LUN_NAME Serial = $LUN_SERIAL UUID = $LUN_UUID"
130 |
131 | # Add details to an array variable of Violin devices
132 | MULTIPATH_DEVICES+=(`echo "$LUN_NAME:$LUN_UUID:$LUN_CONTAINER:$LUN_SERIAL:$MPDEVICE"`)
133 | done
134 |
135 | # Sort the array into alphabetical order based on LUN name
136 | echovrb "Sorting discovered devices into alphabetical order..."
137 | MULTIPATH_DEVICES=($(for MPDEVICE in ${MULTIPATH_DEVICES[@]}; do
138 | echo $MPDEVICE
139 | done | sort))
140 | echovrb "Sort complete"
141 |
142 | if [ "$LISTMODE" = 1 ]; then
143 | echolst "Device Name±Container ±LUN Name±WWID"
144 | echolst "-----------±-----------±--------±----------------------------------"
145 | else
146 | if [ -r /etc/multipath.conf ]; then
147 | echovrb "Backup up /etc/multipath.conf to /tmp"
148 | cp /etc/multipath.conf /tmp
149 | fi
150 | fi
151 |
152 | echovrb "Printing multipath.conf configuration details..."
153 | echovrb ""
154 |
155 | # Now print the multipath.conf output for each device, converting the LUN name to lowercase
156 | for MPDEVICE in ${MULTIPATH_DEVICES[@]}; do
157 | MP_WWID=`echo $MPDEVICE | cut -d':' -f2`
158 | MP_ALIAS=`echo $MPDEVICE | cut -d':' -f1 | tr '[:upper:]' '[:lower:]'`
159 | MP_CONTAINER=`echo $MPDEVICE | cut -d':' -f3`
160 | MP_DEVNAME=`echo $MPDEVICE | cut -d':' -f5`
161 |
162 | if [ "$LISTMODE" = 1 ]; then
163 | echolst "$MP_DEVNAME ±$MP_CONTAINER±$MP_ALIAS±$MP_WWID"
164 | else
165 | echoout " multipath {"
166 | echoout " # Container $MP_CONTAINER"
167 | echoout " wwid $MP_WWID"
168 | echoout " alias $MP_ALIAS"
169 | echoout " }"
170 | fi
171 | done
172 |
173 | echovrb "Successful completion"
174 | exit 0
175 |
--------------------------------------------------------------------------------
/show_physical_io.sql:
--------------------------------------------------------------------------------
1 | -- show_physical_io.sql : script to display physical IO statistics from DBA_HIST_SYSSTAT
2 | -- specifically redo size, physical reads and physical writes
3 | --
4 | -- See GitHub repository at https://github.com/flashdba/scripts
5 | --
6 | -- ###########################################################################
7 | -- # #
8 | -- # Copyright (C) {2014,2015} Author: flashdba (http://flashdba.com) #
9 | -- # #
10 | -- # This program is free software; you can redistribute it and/or modify #
11 | -- # it under the terms of the GNU General Public License as published by #
12 | -- # the Free Software Foundation; either version 2 of the License, or #
13 | -- # (at your option) any later version. #
14 | -- # #
15 | -- # This program is distributed in the hope that it will be useful, #
16 | -- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
17 | -- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
18 | -- # GNU General Public License for more details. #
19 | -- # #
20 | -- # You should have received a copy of the GNU General Public License along #
21 | -- # with this program; if not, write to the Free Software Foundation, Inc., #
22 | -- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #
23 | -- # #
24 | -- ###########################################################################
25 |
26 | set lines 140 pages 45
27 | accept num_days prompt 'Enter the number of days to report on [default is 0.5]: '
28 | set verify off
29 |
30 | SELECT redo_hist.snap_id AS SnapshotID
31 | , TO_CHAR(redo_hist.snaptime, 'DD-MON HH24:MI:SS') as SnapshotTime
32 | , ROUND(redo_hist.statval/elapsed_time/1048576,2) AS Redo_MBsec
33 | , SUBSTR(RPAD('*', 20 * ROUND ((redo_hist.statval/elapsed_time) / MAX (redo_hist.statval/elapsed_time) OVER (), 2), '*'), 1, 20) AS Redo_Graph
34 | , ROUND(physical_read_hist.statval/elapsed_time/1048576,2) AS Read_MBsec
35 | , SUBSTR(RPAD('*', 20 * ROUND ((physical_read_hist.statval/elapsed_time) / MAX (physical_read_hist.statval/elapsed_time) OVER (), 2), '*'), 1, 20) AS Read_Graph
36 | , ROUND(physical_write_hist.statval/elapsed_time/1048576,2) AS Write_MBsec
37 | , SUBSTR(RPAD('*', 20 * ROUND ((physical_write_hist.statval/elapsed_time) / MAX (physical_write_hist.statval/elapsed_time) OVER (), 2), '*'), 1, 20) AS Write_Graph
38 | FROM (SELECT s.snap_id
39 | ,g.value AS stattot
40 | ,s.end_interval_time AS snaptime
41 | ,NVL(DECODE(GREATEST(VALUE, NVL(lag (VALUE) OVER (PARTITION BY s.dbid, s.instance_number, g.stat_name
42 | ORDER BY s.snap_id), 0)), VALUE, VALUE - LAG (VALUE) OVER (PARTITION BY s.dbid, s.instance_number, g.stat_name
43 | ORDER BY s.snap_id), VALUE), 0) AS statval
44 | ,(EXTRACT(day FROM s.end_interval_time)-EXTRACT(day FROM s.begin_interval_time))*86400 +
45 | (EXTRACT(hour FROM s.end_interval_time)-EXTRACT(hour FROM s.begin_interval_time))*3600 +
46 | (EXTRACT(minute FROM s.end_interval_time)-EXTRACT(minute FROM s.begin_interval_time))*60 +
47 | (EXTRACT(second FROM s.end_interval_time)-EXTRACT(second FROM s.begin_interval_time)) as elapsed_time
48 | FROM dba_hist_snapshot s,
49 | dba_hist_sysstat g,
50 | v$instance i
51 | WHERE s.snap_id = g.snap_id
52 | AND s.begin_interval_time >= sysdate-NVL('&num_days', 0.5)
53 | AND s.instance_number = i.instance_number
54 | AND s.instance_number = g.instance_number
55 | AND g.stat_name = 'redo size') redo_hist,
56 | (SELECT s.snap_id
57 | ,g.value AS stattot
58 | ,NVL(DECODE(GREATEST(VALUE, NVL(lag (VALUE) OVER (PARTITION BY s.dbid, s.instance_number, g.stat_name
59 | ORDER BY s.snap_id), 0)), VALUE, VALUE - LAG (VALUE) OVER (PARTITION BY s.dbid, s.instance_number, g.stat_name
60 | ORDER BY s.snap_id), VALUE), 0) AS statval
61 | FROM dba_hist_snapshot s,
62 | dba_hist_sysstat g,
63 | v$instance i
64 | WHERE s.snap_id = g.snap_id
65 | AND s.begin_interval_time >= sysdate-NVL('&num_days', 0.5)
66 | AND s.instance_number = i.instance_number
67 | AND s.instance_number = g.instance_number
68 | AND g.stat_name = 'physical read total bytes') physical_read_hist,
69 | (SELECT s.snap_id
70 | ,g.value AS stattot
71 | ,NVL(DECODE(GREATEST(VALUE, NVL(lag (VALUE) OVER (PARTITION BY s.dbid, s.instance_number, g.stat_name
72 | ORDER BY s.snap_id), 0)), VALUE, VALUE - LAG (VALUE) OVER (PARTITION BY s.dbid, s.instance_number, g.stat_name
73 | ORDER BY s.snap_id), VALUE), 0) AS statval
74 | FROM dba_hist_snapshot s,
75 | dba_hist_sysstat g,
76 | v$instance i
77 | WHERE s.snap_id = g.snap_id
78 | AND s.begin_interval_time >= sysdate-NVL('&num_days', 0.5)
79 | AND s.instance_number = i.instance_number
80 | AND s.instance_number = g.instance_number
81 | AND g.stat_name = 'physical write total bytes') physical_write_hist
82 | WHERE redo_hist.snap_id = physical_read_hist.snap_id
83 | AND redo_hist.snap_id = physical_write_hist.snap_id
84 | ORDER BY 1;
85 |
--------------------------------------------------------------------------------
/slob_harness.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # slob_harness.sh - Simple harness for running Oracle tests using SLOB
4 | #
5 | # Script Author: flashdba (http://flashdba.com)
6 | # For details of SLOB please see https://kevinclosson.net/slob/
7 | #
8 | # For educational purposes only - no warranty is provided
9 | # Test thoroughly - use at your own risk
10 |
11 | SLOB_LOGDIR=logs
12 | SLOB_OUTDIR=AWRs
13 | [ ! -d "$SLOB_OUTDIR" ] && mkdir -p "$SLOB_OUTDIR"
14 | [ ! -d "$SLOB_LOGDIR" ] && mkdir -p "$SLOB_LOGDIR"
15 | [ -f slob.conf ] && cp slob.conf $SLOB_OUTDIR
16 |
17 | # Controls for loop - remember that the loop counter controls the number of threads per schema, not the total number of sessions
18 | SLOB_MINCOUNT=1
19 | SLOB_MAXCOUNT=16
20 | SLOB_INCREMENT=2
21 | SLOB_SCHEMAS=4
22 |
23 | SLOB_RUNLIST=`seq -s " " $SLOB_MINCOUNT $SLOB_INCREMENT $SLOB_MAXCOUNT`
24 | [ "$1" = "-t" ] && echo "Test Plan: execute with $SLOB_SCHEMAS schemas and thread counts: $SLOB_RUNLIST" && exit 0
25 | echo "Starting $0 at `date +'%F %T'` with $SLOB_SCHEMAS schemas and thread counts: $SLOB_RUNLIST"
26 |
27 | for SLOB_THREADS in $SLOB_RUNLIST
28 | do
29 | SLOB_SESSIONS=$(( $SLOB_THREADS * $SLOB_SCHEMAS ))
30 | echo "Running SLOB with $SLOB_SESSIONS sessions ($SLOB_SCHEMAS schemas and $SLOB_THREADS threads) at `date +'%F %T'`"
31 | echo "Executing: sh ./runit.sh -s $SLOB_SCHEMAS -t $SLOB_THREADS" > $SLOB_LOGDIR/runit.$SLOB_SESSIONS.log
32 | sh ./runit.sh -s $SLOB_SCHEMAS -t $SLOB_THREADS >> $SLOB_LOGDIR/runit.$SLOB_SESSIONS.log 2>&1
33 |
34 | if [ $SLOB_SESSIONS -lt 10 ]; then
35 | [ -f awr.txt ] && mv awr.txt $SLOB_OUTDIR/awr.00$SLOB_SESSIONS.txt
36 | elif [ $SLOB_SESSIONS -lt 100 ]; then
37 | [ -f awr.txt ] && mv awr.txt $SLOB_OUTDIR/awr.0$SLOB_SESSIONS.txt
38 | else
39 | [ -f awr.txt ] && mv awr.txt $SLOB_OUTDIR/awr.$SLOB_SESSIONS.txt
40 | fi
41 | done
42 |
43 | echo "$0 completed at `date +'%F %T'`"
44 | exit 0
45 |
--------------------------------------------------------------------------------