#!/usr/bin/env perl $dist_pgmr = ""; #====================================================================== # orastat #====================================================================== # Env: # - ORACLE_HOME and ORACLE_SID must be set # - PATH must include ORACLE_HOME/bin # - You must be running an ID with gid=dba # Usage: # - Run 'orastat --' to view usage table # Author: # - Bill Border 03/2000 # Changes: # # Ver Date Programmer Desc # ==== ======= ============ ========================================= # 1.29 18Aug00 Bill Border Added -ad archive dest # 1.30 22Aug00 Dean Riggio Added -bp backup processes and # -ss tablespace storage # 1.31 08Nov00 Bill Border orastat can only be run by someone in # group 'dba'. # 1.32 10Nov00 Bill Border Added -ug # 1.33 18Nov00 Bill Border Renames -sc to -ti and added more data to # the report. # 1.34 01Feb01 Bill Border Added -au # 1.35 02Feb01 Bill Border Added -tb and -vw # 1.36 28Feb01 Bill Border Added -vs # Craig Geier Added -so # Craig Geier Added -tu # 1.37 18Apr01 Bill Border Added -in (list indexes) # 1.38 18Apr01 Bill Border Added -op (OPS v$ping table) # 1.39 19Apr01 Bill Border Added -ba (List dbamon.backup_age contents) # 1.40 02May01 Bill Border Added -rp # 1.41 18May01 Bill Border Added -tt # 1.42 22May01 Bill Border Added DBID to orastat - # 1.43 28May01 Bill Border Added -sr # 1.44 20Jun01 Bill Border Added -ar # 1.45 05Jul01 Dean Riggio Updated -se to show SPID # 1.46 31Jul01 Craig Geier Updated - Fixed erroneous uptime for # version 7 and 8.0 # 31Jul01 Craig Geier Updated - Added code to determine mount/open # status of a version 7 instance # 1.47 11Aug01 Craig Geier Added -bi # 1.48 20Aug01 Craig Geier Added -mv # 1.49 30Aug01 Dean Riggio Updated -lv to support non-standard systems # for the phoenix application. # 1.50 08Sep01 Bill Border Added TS and DF counts to -ts and -df # 1.51 13Sep01 Craig Geier Added extents to -rb and removed owner # also changed query # 1.52 08Oct01 Bill Border Added -er # 1.53 17Oct01 Bill Border Improved -ad to display dates # # 2.00 24Oct01 Bill Border MAJOR CHANGE - Added oraSQL subroutine. # Since svrmgrl is going away in 9i, if you call this routine to # do the build the oraSQLout array, it will decide whether to use # svrmgrl and connect internal, or sqlplus internal. Any new functions # should use oraSQL instead of connect internal. See orastat -ad for # and example of how to call oraSQL. # 2.01 27Oct01 Bill Border orastat -pd now dipslays libcache and # dict cache hit ratios. # 2.02 27Oct01 Bill Border New -sc - sessions sort by cpu time used # 2.02 01Nov01 Bill Border New -ex - select from plan_table # 2.03 01Nov02 Bill Border New -ma - cat alert log # 2.04 01Nov02 Bill Border New -ub - data by schema # 2.05 01Nov02 Bill Border New -ut - data by schema and ts # 2.06 01Nov08 Bill Border New -ws - v$waitstat # 2.07 19Nov08 Bill Border Changed - to use oraSQL # 2.08 19Nov08 Bill Border New -al - Archived logs # 2.09 26Nov08 Bill Border Converted -df to oraSQL # 2.10 27Nov08 Bill Border The default for -df is now NOFSCHECK # 2.11 27Nov08 Bill Border Converted -sg and fixed bug in -ts where # SYSADM.* tables were not being displayed; converted -ba; # converted -l; converted -ta; converted -pd; converted -ar # converted -st; converted -sw; converted -in; converted -ra # converted -rb; converted -us # 2.12 28Nov08 Bill Border Fixed '-' to better handle 8.0 DB's # converted -sl # 2.13 03Dec01 Bill Border New -lo - table locks; New -ls # converted -au; converted -li; converted -lk; converted -rc/-rd # converted -rh; converted -rs; converted -rr; converted -iv # converted -lf/-rl; converted -cf; converted -so; converted -rp # converted -bp; converted -sb; converted -ss; converted -ug # converted -bi; converted -de # 2.14 04Dec01 Bill Border Converted -dc; # converted -ps; converted -tz; converted -ct; converted -tc # converted -ve; converted -ud; converted -ro; converted -op # converted -vs; converted -vw; converted -tb; converted -ti # converted -sn; converted -sr - DONE!!! # 2.15 07Dec01 Bill Border Added -br # 2.16 11Dec01 Bill Border Added -ck # 2.17 19Dec01 Craig Geier Added -v # 2.18 20Dec01 Bill Border Added status column to -se # 2.19 20Dec01 Bill Border Added -sp StatsPack data # 2.20 08Jan02 Bill Border Added -pf Freelist Waits # 2.21 09Jan02 Bill Border Renamed -ti to -an # 2.22 10Jan02 Bill Border Added -az, -ph and -lh # 2.23 10Jan02 Bill Border Added -az, -ph and -lh # 2.24 24Jan02 Bill Border Added -count optional parameter to -ti # 2.25 28Jan02 Bill Border Added status column to -in # 2.26 29Jan02 Bill Border Added columns to -az # 2.27 30Jan02 Craig Geier Added script_tbls # Added script_tbs # Added script_views # 2.28 30Jan02 Bill Border Added -qs # 2.20 28Feb02 Bill Border Added -wr and enhanced -az # 2.29 07Mar02 Craig Geier Added -civ # 2.30 01Apr02 Bill Border Added -bc # 2.31 10Apr02 Bill Border Added -ob # 2.32 22Apr02 Bill Border Added -af # 2.33 01May02 Bill Border Added -nl # 2.34 01Jul02 Bill Border Added -la # 2.35 01Jul02 Bill Border Changed -az to include latch wait details # 2.36 03Jul02 Bill Border Added -mf # 2.37 03Jul02 Bill Border Added -ht # 2.38 18Jul02 Bill Border Added -ap and made enhancements to -az # 2.39 30Jul02 Bill Border Added -po and enhanced -pd and -az # 2.40 29Aug02 Bill Border Changed -l to not use archv02, if it exists # 2.41 24Sep02 Bill Border Added -tm and -tr # 2.42 24Sep02 Bill Border Added -bm # 2.43 18Nov02 Bill Border Added -ln # 2.44 20Dec02 Bill Border Added -un & -bs # 2.45 17Jan03 Bill Border Added -sh # 2.46 29Jan03 Bill Border Enhancement to -tz (buffer pool stats) # 2.47 30Jan03 Bill Border Added -tp # 2.48 08Feb03 Bill Border Added -dh . Changed name of -civ to -cv # 2.49 18Feb03 Dean Riggio Added -pc to check for insecure passwords # 2.50 26Feb03 Bill Border Changed -pd to recognize invalid stats data # 2.51 06Mar03 Bill Border Changed -pd to display 9i cache stats # 2.52 28Mar03 Bill Border Improved -tr # 2.53 10Apr03 Bill Border Added -hd # 2.54 16Apr03 Bill Border Added -du # 2.55 21Apr03 Bill Border Added -pk # 2.56 30Apr03 Bill Border Added -sy # 2.57 06Jun03 Bill Border Changed -td ... It now counts rows in tables. # 2.58 11Jun03 Bill Border New -tj # 2.59 11Jun03 Bill Border Fix an arithmetic problem with -sg # 2.60 12Aug03 Bill Border Added -nf # 2.61 02Sep03 Bill Border Added -tq # 2.62 19Sep03 Bill Border Added -cb Controlfile Backup. # 2.63 23Sep03 Bill Border Added LEARN mode. # 2.64 26Sep03 Bill Border Solved a problem where -cb didn't work in 8.0 or 7.3 # 2.65 01Oct03 Bill Border Changed -se to now display running jobs also # 2.66 15Oct03 Bill Border Added -ft # 2.67 28Oct03 Bill Border Enhanced -tq for work better with 9i # 2.68 26Nov03 Bill Border Enhanced -ta to add ALL parameter # 2.69 10Feb04 Ralf Kannenberg added -df2 to sort by filesize desc # 2.70 16Mar04 Bill Border Added support for 10g (first phase of changes) # 2.71 04May04 Bill Border Added commented code to -sw # 2.72 03Jun04 Bill Border Added -rf # 2.73 11Jun04 Bill Border Changed -cb - Coded for oracle bug for trace bkup # 2.74 11Jun04 Bill Border Changed -al - Fix so that only ARCH created logs are displayed. # 2.75 23Jun04 Bill Border Added -su # 2.76 25Jun04 Bill Border Added -dn # 2.77 29Jun04 Ralf Kannenberg Added -af9i # 2.78 29Jul04 Bill Border Fixed -af so that it works with 9i+. af91 is not # needed, but I will leave it until all calling programs are changed. # 2.79 29Jul04 Scott Patton - Fixed orastat -cb to work on 9.0.1 databases # 2.80 02Aug04 Bill Border Fixed a bug in -af # 2.81 02Sep04 Bill Border Added logic to -cb for 10g # 2.82 17Sep04 Bill Border Added -rg # 2.83 30Sep04 Bill Border HOLY COW! There was a bug in -ts where a TS that is 100% full # would indicate 0% full. Fixed some misplaced nvl function calls. # 2.84 22Oct04 Bill Border Fixed -pd - db_cache_size was displayed wrong for big numbers # 2.85 29Oct04 Bill Border Added -bo (pretty cool) # 2.86 01Nov04 Bill Border Fixed -bc so that it works with 9i+ # 2.87 12Nov04 Bill Border Added a sample of FREE BUFFERS to -az # 2.88 16Nov04 Bill Border Added diagnostics to -rh # 2.89 06Jan05 Bill Border Fixed -sg to work with >= 9i # 2.90 13Jan05 Bill Border Improved -pd to display cache hit ratio excluding RECYCLE pool # 2.91 04Feb05 Bill Border Added -mt # 2.92 28Feb05 Bill Border Fix to - for AIX # 2.93 07Mar05 Bill Border Added -cm # 2.94 15Mar05 Bill Border Change to -cb: if /var/opt/oracle/tmp exists, write bin cf there # 2.95 22Mar05 Bill Border Fixed -ln to be able to deal with null OWNER (Thanks Bob Simcock) # 2.96 29Mar05 Ralf Kannenberg Fixed - -av to work with archv02 as well # 2.97 06Apr05 Bill Border Another fix to -ln # 2.98 11Apr05 Bill Border Enhanced -pi & -pj: They now read tempfile and tempstat # 2.99 23Apr05 Bill Border New -pa to analyze I/O load by tablespace # 3.00 14Jul05 Ralf Kannenberg Fixed AGAIN(!!)- -av to work with archv02 as well # 3.01 14Jul05 Bill Border BREAKFIX -av - Rewrote to automatically figure out what the # correct destination name is. This should fix the problem where we were query multiple # destinations. New run_av function replaced old -av routine. -av has been rename to -avo. # 3.02 18Jul05 Bill Border New -lg Long Operation Progress # 3.03 28Jul05 Bill Border Enhancement to -lg; Added where time_remaining > 0 # Thanks to Henrik Lehmann for the good suggestion. # 3.04 06Aug04 Bill Border Enhancement to -cb - we now remove all old cfbackups first # 3.05 18Aug04 Bill Border Fix to -ad: only replace with arcdirnew if it is non-null # 3.06 08Sep05 Bill Border New -fm # 3.07 09Sep05 Bill Border New -df3 # 3.08 09Oct05 Bill Border New -dp # 3.09 18Oct05 Bill Border New -mr # 3.10 20Oct05 Bill Border Improved "-" ... added force logging... # 3.11 08Nov05 Bill Border Improved -us: added account status and improved format of create date # 3.12 20Oct05 Bill Border Improved "-" no more invalid column for 8.1 # 3.13 28Nov05 Bill Border Rewrote -tt - It is now ACCURATE (it used v$sort_usage) # 3.14 12Dec05 Bill Border Improved -az added sga full measures # 3.15 30Dec05 Bill Border Added resetlogs_id to "-" # 3.16 09Jan06 Bill Border Improved -tz - The largest table and index are not displayed # 3.17 20Jan06 Bill Border Improved -lv # 3.18 18Feb06 Bill Border New -cc # 3.19 10Mar06 Bill Border Improved -az - added free memory collection # 3.20 31Mar06 Bill Border Fix to -se... It now reports sessions with a null osuser # 3.21 19Jun06 Bill Border New -sz # 3.22 20Jun06 Bill Border Added 'print if ORA' logic to -bm # 3.23 27Jun06 Bill Border Fix to -bm - retry if ORA-00235 # 3.24 13Jul06 Bill Border Fix to -az for Linux # 3.25 21Oct06 Bill Border Fix to -cb - initial rm needed -f parm # 3.26 22Dec06 Bill Border Improved -av - New MAX total line # 3.27 03Feb07 Bill Border Added -pr # 3.28 29Mar07 Larry Rush Changed method for determining Oracle version due to strange problem on eprdhe1 # 3.29 03May07 Bill Border New -fba and changes to - # 3.30 11May07 Bill Border Changed -cb to not remove all /tmp/*cb* files # 3.31 27Jul07 Bill Border Changed -rh - for 9i+ is now sets workareasizepolicy to manual # 3.32 09Aug07 Bill Border New -amm and changes to -sg # 3.33 09Aug07 Bill Border Change to "-" for asm instance # 3.34 09Aug07 Bill Border New -asm # 3.35 12Aug07 Bill Border New -di # 3.36 15Aug07 Bill Border Some ASM changes to -tf # 3.37 24Sep07 Bill Border New -spf and new -rac alias for -ps # 3.38 25Sep07 Bill Border Added "alter session set optimizer_mode=rule;" to -dn # 3.39 01Oct07 Bill Border New -asm_op # 3.40 14nov07 Bill Border New -brm # 3.41 17Apr08 LR Fix to -az for multi-line default pool output (hitr_tot) # 3.42 28May08 BB DTV changes and improved -su # 3.43 12Aug08 BB New -dgl # 3.44 02Apr09 BB New -df5 (datafiles, but works on a MOUNTED DB) # 3.45 20Apr09 BB New -ser # 3.46 26Jun09 BB New -uns # 3.50 05Apr10 BB MAJOR - New "connect file" logic. # 3.51 16Apr10 BB New -unl, -emth, -emac, and -emah # 3.52 30Aug10 BB New -cdb # 3.53 01Sep10 BB New -pul #====================================================================== $version = "3.53"; use Time::Local; #------------------------------------------------------------------------------ # # Subroutines # #------------------------------------------------------------------------------ #------------------------------------------------------------------------------ sub error #------------------------------------------------------------------------------ { $emsg = $_[0]; &msg("ERROR: $emsg"); exit 1; $ENV{'ORACLE_SID'} = "$instance"; $str1="${backup_type}: ($errnum) - $msg (${webserver}/oberr.html#${errnum})"; $str2="DB: $instance"; $str3="Backup Level: $backup_type"; $str4="For more information see: ${webserver}/processes/oracle/ora_backup_errors.html#$errnum"; &msg("Sending BLT ticket $str1 $str2 $str3 $str4"); $progstring = "${P}[${errnum}]"; $ENV{'BLT_SUBJECT'} = "${host}-${instance}|${backup_type} [$errnum] - $msg"; system("$toolsdir/db_create_ticket $progstring \"$str1\" \"$str2\" \"$str3\" \"$str4\""); if ($errnum == -86 || $errnum == -88 || $errnum == -90 || $errnum == -91) { #&blt_dcit; comment this for now - the tickets aren't working anyway bb 09aug01 } &msg("============================================================="); &msg("Fatal Error: $msg"); &msg("============================================================="); &msg("Exiting rc=1"); exit 1; } #------------------------------------------------------------------------------ sub oraSQL #------------------------------------------------------------------------------ { $sql = $_[0]; if ($ENV{'LEARN'} ne "") { print "\n#===========================================================#\n"; &msg("LEARN Mode: SQL Being Executed: \n $sql"); $sqlcnt++; system("echo '$date | LEARN Mode - Command: \"$P $arg\" - SQL #$sqlcnt Being Executed: \n $sql \n' >> /tmp/orastat_learn.txt"); print "#===========================================================#\n"; } if ($sqlcmd eq "sp") { $os_scmd = "sqlplus /NOLOG"; $os_conn = "connect / as sysdba "; $os_set1 = "set linesize 9999"; $os_set2 = "set numwidth 20"; $os_set3 = "set long 2000000000"; $os_set4 = "set pagesize 50000"; $os_end = "exit"; } else { $os_scmd = "svrmgrl"; $os_conn = "connect internal "; $os_set1 = "set numwidth 20"; $os_set2 = "set echo on"; $os_end = "exit"; } #---- Possible override $os_conn = $cf_connect_string if $cf_connect_string; ##&msg("os_scmd=$os_scmd os_conn=$os_conn"); @oraSQLout = `$os_scmd < "01", "Feb" => "02", "Mar" => "03", "Apr" => "04", "May" => "05", "Jun" => "06", "Jul" => "07", "Aug" => "08", "Sep" => "09", "Oct" => "10", "Nov" => "11", "Dec" => "12" ); while() { my @words = split; if ($#words == 4 && $words[4] =~ /^2/) { $dom = $words[2]; $dom = "0" . $dom if length($dom) < 2; $alr_ts = $words[4] . "/" . $alr_month_hash{$words[1]} . "/" . $dom . "-" . $words[3]; $alr_seq = 0; next; } $alr_seq++; if ($alr_seq == 1) { $alr_line = "$alr_ts [$alr_seq] $_"; } else { $alr_line = "$alr_ts [$alr_seq] - $_"; } $alr_buffer .= $alr_line; push (@alr_array,$alr_line); } close(ALR); if (uc $alr_lines eq "A") { &msg("Displaying entire alert log ($#alr_array+1 lines)") unless $raw; print "\n" unless $raw; print $alr_buffer; print "\n" unless $raw; } if (uc $alr_lines eq "V") { &msg("vi-ing entire alert log ($#alr_array+1 lines)") unless $raw; $tmpfl = "/tmp/orastat_alr.txt"; open(OUTDATA, ">$tmpfl") || die "Cannot open output orastat_alr.txt - $!"; print OUTDATA $alr_buffer; close(OUTDATA); system("vi $tmpfl"); } elsif ($alr_lines > 0 && $alr_lines < 99999999) { &msg("Displaying the last $alr_lines lines of alert log") unless $raw; print "\n" unless $raw; for ($i = ($#alr_array - $alr_lines); $i <= $#alr_array; $i++) { ##print "i=$i cnt=$#alr_array\n"; print $alr_array[$i]; } print "\n" unless $raw; } } #------------------------------------------------------------------------------ sub msg #------------------------------------------------------------------------------ { $msgmsg = $_[0]; chop($date = `date +%Y/%m/%d-%H:%M:%S`); print "$date ${P} | $msgmsg\n"; } # ---------------------------------------------------------------------- sub formatNum # ---------------------------------------------------------------------- { my $num_in = $_[0]; $c_k = 1024; $c_meg = 1024**2; $c_gig = 1024**3; if ($num_in >= $c_gig) { $num_out = sprintf("%.1f",$num_in / $c_gig) . 'gb'; } elsif ($num_in >= $c_meg) { $num_out = sprintf("%.1f",$num_in / $c_meg) . 'mb'; } elsif ($num_in >= $c_k) { $num_out = sprintf("%.1f",$num_in / $c_k) . 'kb'; } else { $num_out = $num_in; } return $num_out; } # ---------------------------------------------------------------------- sub checkDST # ---------------------------------------------------------------------- { &msg("checkDST - DST2007 Logic"); $dst_JVM = 0; $dst_col_sys = 0; $dst_col_nonsys = 0; #---- See if there are any tablespaces with NO datafiles $sql = " select 'XA', owner, status, count(*) from all_objects where object_type like '%JAVA%' and owner in ('SYS','WMSYS') group by owner, status having count(*) > 9000; select 'XB', c.owner, count(*) from dba_tab_cols c, dba_objects o where c.data_type like '%WITH TIME ZONE' and c.owner=o.owner and c.table_name = o.object_name and o.object_type = 'TABLE' group by 'XB', c.owner order by owner; "; &oraSQL($sql); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; if ($verb eq "XA") { $dst_JVM = 1; $dst_jvm_installed = 1; &msg(" Schema SYS/WMSYS owns $words[3] JAVA objects - JVM is installed"); } if ($verb eq "XB") { &msg(" Schema $words[1] owns $words[2] Tables with TIME ZONE columns"); if ($words[1] eq 'SYS' || $words[1] eq 'WMSYS') { $dst_col_sys = 1; } else { $dst_col_nonsys = 1; } } } ##print "$P DST2007_JVM: $dst_JVM\n"; ##print "$P DST2007_TZ_COL_SYS: $dst_col_sys\n"; ##print "$P DST2007_TZ_COL_NONSYS: $dst_col_nonsys\n"; if ($dst_col_sys) { &msg("This DB does have DST columns (SYS schemas)"); } else { &msg("This DB does NOT have DST columns (SYS schemas)"); } if ($dst_col_nonsys) { &msg("This DB does have DST columns (non-SYS schemas)"); } else { &msg("This DB does NOT have DST columns (non-SYS schemas)"); } } # -------------------------------------------------------------------- sub run_emth # -------------------------------------------------------------------- { &msg("-emth: (EM) Alert Thresholds"); $sql = " column object_name format a30 column object_type format a20 column metrics_name format a40 column w_oper format a28 column c_oper format a28 column w_value format a28 column c_value format a28 select 'Flag_X:', translate(metrics_name,' ','_'), nvl(object_type,'?'), nvl(object_name,'?'), translate(nvl(warning_operator, '?'),' ','_') as w_oper, translate(nvl(warning_value, '?'),' ','_') as w_value, translate(nvl(critical_operator, '?'),' ','_') as c_oper, translate(nvl(critical_value, '?'),' ','_') as c_value, status from dba_thresholds order by 2,3,4; "; &oraSQL($sql); print "\n"; print "Metric Name Object Type Object Name MetricStatus Warning / Critical Thresholds\n"; print "---------------------------------------- ------------------ -------------------- ------------ ----------------------------------------\n"; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = shift(@words); if ($verb eq "Flag_X:") { ##print; $metric = shift(@words); $obj_type = shift(@words); $obj_name = shift(@words); $w_oper = shift(@words); $w_val = shift(@words); $c_oper = shift(@words); $c_val = shift(@words); $status = shift(@words); $t_all = "Warning=$w_oper/$w_val Critical=$c_oper/$c_val"; $thisline = sprintf("%-40s %-18s %-20s %-12s %-40s\n", $metric,$obj_type,$obj_name,$status,$t_all); print $thisline; $cnt++; } } print "\n"; &msg("Total Metrics: $cnt"); } # -------------------------------------------------------------------- sub run_cdb # -------------------------------------------------------------------- { &msg("-cdb: List all running DBs on all nodes in this SG cluster"); foreach (`cmviewcl -f line | grep ^node | grep id= | sort`) { ##print; $string = $_; $s1 = (split(/\:/,$string)) [1]; $cdb_node = (split(/\|/,$s1)) [0]; &msg("DBs Running on node: $cdb_node"); system("ssh $cdb_node 'ps -ef | grep -v 'grep' | grep 'pmon_'"); } } # -------------------------------------------------------------------- sub run_emac # -------------------------------------------------------------------- { &msg("-emac: (EM) Alerts - Currently Outstanding DB Alerts"); $sql = " column reason format a80 column ts format a19 select 'Flag_X:', sequence_id, to_char(creation_time,'YYYY/MM/DD-HH24:MI:SS') ts, message_type, translate(metric_value,' ','#'), translate(object_type,' ','#'), translate(message_group,' ','#'), translate(reason,' ','#') from dba_outstanding_alerts order by 2; "; &oraSQL($sql); print "\n"; print "Seq# Timestamp Severity Metric Value Alert Reason\n"; print "------ ------------------- ---------- ------------------------ --------------------------------------------------------------------------------\n"; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = shift(@words); if ($verb eq "Flag_X:") { ##print; $seq = shift(@words); $ts = shift(@words); $type = shift(@words); $val = shift(@words); $obj_type= shift(@words); $msg_grp = shift(@words); $reason = shift(@words); $reason_out = "$obj_type $msg_grp - $reason"; $reason_out =~ s/\#/ /g; $thisline = sprintf("%6s %-19s %-10s %-24s %-80s\n", $seq,$ts,$type,$val,$reason_out); print $thisline; $cnt++; } } print "\n"; &msg("Total Outstanding Alerts: $cnt"); } # -------------------------------------------------------------------- sub run_emah # -------------------------------------------------------------------- { &msg("-emah: (EM) Alerts - Historical DB Alerts"); $sql = " column reason format a80 column ts format a19 select 'Flag_X:', sequence_id, to_char(creation_time,'YYYY/MM/DD-HH24:MI:SS') ts, message_type, translate(metric_value,' ','#'), translate(object_type,' ','#'), translate(message_group,' ','#'), translate(reason,' ','#') from dba_outstanding_alerts order by 2; "; &oraSQL($sql); print "\n"; print "Seq# Timestamp Severity Metric Value Alert Reason\n"; print "------ ------------------- ---------- ------------------------ --------------------------------------------------------------------------------\n"; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = shift(@words); if ($verb eq "Flag_X:") { ##print; $seq = shift(@words); $ts = shift(@words); $type = shift(@words); $val = shift(@words); $obj_type= shift(@words); $msg_grp = shift(@words); $reason = shift(@words); $reason_out = "$obj_type $msg_grp - $reason"; $reason_out =~ s/\#/ /g; $thisline = sprintf("%6s %-19s %-10s %-24s %-80s\n", $seq,$ts,$type,$val,$reason_out); print $thisline; $cnt++; } } print "\n"; &msg("Total Outstanding Alerts: $cnt"); } # -------------------------------------------------------------------- sub run_pul # -------------------------------------------------------------------- { $linelimit = 30; &msg("-pul: Purge - Display last $linelimit lines of DTVPURGE.P_JOB_LOGGING "); $sql = " column reason format a80 column ts format a19 select 'Flag_X:', job_num, to_char(job_start,\'YYYY/MM/DD-HH24:MI:SS\'), to_char(job_end,\'YYYY/MM/DD-HH24:MI:SS\'), nvl( p_job_type , '?'), nvl( p_job_table , '?'), translate(p_job_criteria,\' \',\'!\'), nvl( p_job_batch , -1), nvl( p_job_commit , -1), nvl( p_job_threads , -1), translate(desc_text,\' \',\'!\') from dtvpurge.p_job_logging --where job_start > sysdate - 1/24 order by job_start; "; &oraSQL($sql); print "\n"; print "JOB_NUM JOB_START JOB_END JOB_TYPE JOB_TABLE JOB_CRITERIA JOB_BATCH/COMMIT/THREADS DESC_TEXT\n"; print "------- ------------------- ------------------- -------- --------------- -------------------- ------------------------ -----------------------------\n"; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = shift(@words); if ($verb eq "Flag_X:") { ##print; $job_num = shift(@words); $job_start = shift(@words); $job_end = shift(@words); $job_type = shift(@words); $job_table = shift(@words); $job_crit = shift(@words); $job_batch = shift(@words); $job_commit = shift(@words); $job_threads = shift(@words); $desc_text = shift(@words); $desc_text =~ s/\!/ /g; $job_crit =~ s/\!/ /g; $job_bct = "$job_batch / $job_commit / $job_threads"; $thisline = sprintf("%7s %-19s %-19s %-8s %-15s %-20s %-24s %-40s\n", $job_num,$job_start,$job_end,$job_type,$job_table, $job_crit, $job_bct, $desc_text); push (@all_lines, $thisline); } } $num_lines = $#all_lines; $start_line = $num_lines - $linelimit + 2; foreach $this_line (@all_lines) { $cnt++; print $this_line if $cnt >= $start_line; } print "\n"; } # -------------------------------------------------------------------- sub run_sed # -------------------------------------------------------------------- { &msg("-sed: Session Details"); &msg("Only lines matching (caseless) '$arg2' will be displayed") if $arg2; print "\n"; $matchcnt = 0; $sesscnt = 0; print "Session Ses Ses Wait Wait DB OS Session Last Last +---Commit----+ Program\n"; print "SID-Ser# Type Status Class / Seq Userid-Userid-PID-SPID-Term\@Server Start Time Call ET SQL SQL_ID Count /Sec Identifier\n"; print "------------ ------ -------- ------------------ -------------------------------------- ------------------- --------- ------ ------------- -------- ------ ------------------------\n"; $sqlstmt = ' select distinct \'Y\', sid from v\$mystat; select distinct \'X\', s.sid, s.serial#, nvl(p.spid,-1), s.type, translate(nvl(s.osuser,\'?\'),\' \',\'-\'), to_char(logon_time,\'YYYY/MM/DD-HH24:MI:SS\') logon_time, nvl(s.status,\'?\'), nvl(s.process,\'?\'), nvl(s.machine,\'?\'), nvl(s.username,\'?\'), substr(translate(nvl(sql.sql_text,\'?\'),\' \',\'_\'),1,20), translate(nvl(s.program,\'?\'),\' \',\'_\'), translate(nvl(p.program,\'\_\'),\' \',\'_\'), s.last_call_et, s.seq#, translate(s.wait_class,\' \',\'_\'), s.command, nvl(s.terminal,\'?\'), nvl(sta1.value,-1) commits, s.sql_id from v\$session s, v\$process p, v\$sql sql, (select vss.sid, vss.value from v\$sesstat vss, v\$statname vsn where vss.statistic#=vsn.statistic# and vsn.name = \'user commits\') sta1 where p.addr = s.paddr and sql.address(+) = s.sql_address and sta1.sid(+) = s.sid order by 2; ---- '; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Y") { $mysid = $words[1]; } if ($verb eq "X") { ##print; $sid = $words[1]; $ser = $words[2]; $shadow = $words[3]; $type = $words[4]; $user = $words[5]; $logtime = $words[6]; $status = $words[7]; $process = $words[8]; $machine = $words[9]; $dbuser = $words[10]; $sqltext = uc $words[11]; $s_prog = $words[12]; $p_prog = $words[13]; $lastet = $words[14]; $waitct = $words[15]; $waitcls = $words[16]; #$command = $words[17]; $terminal= $words[18]; $commits = $words[19]; $sqlid = $words[20]; if ($s_prog eq $p_prog) { $progstring = $s_prog; } else { $progstring = "$s_prog $p_prog"; } $s_prog = substr($s_prog,0,24) if length($s_prog) > 24; $comb = "$dbuser-$user-$process-${shadow}-$terminal\@$machine"; $comb = substr($comb,0,38) if length($comb) > 38; $sidser = "$sid,$ser"; $sesscnt++; $sescount{$status}++ if $type =~ /USER/; $type = "BG" if $type eq "BACKGROUND"; $waitboth = "$waitcls/$waitct"; ($sqlout = $sqltext) =~ s/\_/ /g; $sqlout =~ s/^\s+//; $sqlout = substr($sqlout,0,6); if ($user eq "") { $user = "."; } if ($sid == $mysid) { $type = "USER*"; } if ($sid == $mysid && $arg2) { next; } if ($lastet + 0 == $lastet) { if ($lastet < 60) { $lastet_out = $lastet . "_Sec"; } elsif ($lastet < 3600) { $lastet_out = sprintf("%.1f",$lastet / 60) . "_Min"; } elsif ($lastet < 86400) { $lastet_out = sprintf("%.1f",$lastet / 3600) . "_Hrs"; } else { $lastet_out = sprintf("%.1f",$lastet / 86400) . "_Day"; } } $commitrt = "?"; if ($lastet > 0 && $commits > 0) { $commitrt = int($commits / $lastet); } $thisline = sprintf("%-12s %-6s %-8s %-18s %-38s %-19s %9s %-6s %13s %8s %6s %-24s\n", $sidser,$type,$status,$waitboth,$comb,$logtime,$lastet_out,$sqlout,$sqlid,$commits,$commitrt,$s_prog); if ($arg2) { if ($arg2 ne "" && $thisline =~ /$arg2/i) { print $thisline; $matchcnt++; $commits_total += $commits; $commitrt_total += $commitrt; $lastet_total += $lastet; } } else { print $thisline; } } } print "\n"; @sorted = sort keys %sescount; foreach (@sorted) { &msg("Count of USER session(s) in $_ status: $sescount{$_}"); } &msg("There are $sesscnt total sessions (mysid=$mysid - denoted by *)"); &msg("Sessions matching match string: $matchcnt") if $arg2; if ($commits_total > 0) { $rows_per_commit = 1; $z1 = int($commits_total / $lastet_total); $z2 = $commitrt_total; &msg("Matching Sessions - Total Commits=$commits_total AverageCommitRate=$z1 TotalCommitRate=$z2"); $rows = ($commits_total * $rows_per_commit); $rate = ($z2 * $rows_per_commit * 3600); &msg("PURGE - RowsProcessed=$rows RowsPerHour=$rate ($rows_per_commit rows/commit)"); } } # -------------------------------------------------------------------- sub run_ser # -------------------------------------------------------------------- { &msg("-ser: Session Details"); &msg("Only lines matching (caseless) '$arg2' will be displayed") if $arg2; print "\n"; $matchcnt = 0; $sesscnt = 0; print "Session Ses Ses Wait Wait DB OS Session Last Last +-UserCommits-+ Rollback Program\n"; print "SID-Ser# Type Status Class / Seq Userid-Userid-PID-SPID-Term\@Server Start Time Call ET SQL SQL_ID Count /Sec Count Identifier\n"; print "------------ ------ -------- ------------------ -------------------------------------- ------------------- --------- ------ ------------- -------- ------ -------- ------------------------\n"; $sqlstmt = ' select distinct \'Y\', sid from v\$mystat; select distinct \'X\', s.sid, s.serial#, nvl(p.spid,-1), s.type, translate(nvl(s.osuser,\'?\'),\' \',\'-\'), to_char(logon_time,\'YYYY/MM/DD-HH24:MI:SS\') logon_time, nvl(s.status,\'?\'), nvl(s.process,\'?\'), nvl(s.machine,\'?\'), nvl(s.username,\'?\'), substr(translate(nvl(sql.sql_text,\'?\'),\' \',\'_\'),1,20), translate(nvl(s.program,\'?\'),\' \',\'_\'), translate(nvl(p.program,\'\_\'),\' \',\'_\'), s.last_call_et, s.seq#, translate(s.wait_class,\' \',\'_\'), s.command, nvl(s.terminal,\'?\'), nvl(sta1.value,-1) commits, s.sql_id, nvl(sta2.value,-1) rollbacks from v\$session s, v\$process p, v\$sql sql, (select vss.sid, vss.value from v\$sesstat vss, v\$statname vsn where vss.statistic#=vsn.statistic# and vsn.name = \'user commits\') sta1, (select vss.sid, vss.value from v\$sesstat vss, v\$statname vsn where vss.statistic#=vsn.statistic# and vsn.name = \'transaction rollbacks\') sta2 where p.addr = s.paddr and sql.address(+) = s.sql_address and sta1.sid(+) = s.sid and sta2.sid(+) = s.sid order by 2; ---- '; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Y") { $mysid = $words[1]; } if ($verb eq "X") { ##print; $sid = $words[1]; $ser = $words[2]; $shadow = $words[3]; $type = $words[4]; $user = $words[5]; $logtime = $words[6]; $status = $words[7]; $process = $words[8]; $machine = $words[9]; $dbuser = $words[10]; $sqltext = uc $words[11]; $s_prog = $words[12]; $p_prog = $words[13]; $lastet = $words[14]; $waitct = $words[15]; $waitcls = $words[16]; #$command = $words[17]; $terminal= $words[18]; $commits = $words[19]; $sqlid = $words[20]; $rollbacks = $words[21]; if ($s_prog eq $p_prog) { $progstring = $s_prog; } else { $progstring = "$s_prog $p_prog"; } $s_prog = substr($s_prog,0,24) if length($s_prog) > 24; $comb = "$dbuser-$user-$process-${shadow}-$terminal\@$machine"; $comb = substr($comb,0,38) if length($comb) > 38; $sidser = "$sid,$ser"; $sesscnt++; $sescount{$status}++ if $type =~ /USER/; $type = "BG" if $type eq "BACKGROUND"; $waitboth = "$waitcls/$waitct"; ($sqlout = $sqltext) =~ s/\_/ /g; $sqlout =~ s/^\s+//; $sqlout = substr($sqlout,0,6); if ($user eq "") { $user = "."; } if ($sid == $mysid) { $type = "USER*"; } if ($sid == $mysid && $arg2) { next; } if ($lastet + 0 == $lastet) { if ($lastet < 60) { $lastet_out = $lastet . "_Sec"; } elsif ($lastet < 3600) { $lastet_out = sprintf("%.1f",$lastet / 60) . "_Min"; } elsif ($lastet < 86400) { $lastet_out = sprintf("%.1f",$lastet / 3600) . "_Hrs"; } else { $lastet_out = sprintf("%.1f",$lastet / 86400) . "_Day"; } } $commitrt = "?"; if ($lastet > 0 && $commits > 0) { $commitrt = int($commits / $lastet); } $rollbacks = 0 if $rollbacks eq ""; $thisline = sprintf("%-12s %-6s %-8s %-18s %-38s %-19s %9s %-6s %13s %8s %6s %8s %-24s\n", $sidser,$type,$status,$waitboth,$comb,$logtime,$lastet_out,$sqlout,$sqlid,$commits,$commitrt,$rollbacks,$s_prog); if ($arg2) { if ($arg2 ne "" && $thisline =~ /$arg2/i) { print $thisline; $matchcnt++; $commits_total += $commits; $commitrt_total += $commitrt; $lastet_total += $lastet; } } else { print $thisline; } } } print "\n"; @sorted = sort keys %sescount; foreach (@sorted) { &msg("Count of USER session(s) in $_ status: $sescount{$_}"); } &msg("There are $sesscnt total sessions (mysid=$mysid - denoted by *)"); &msg("Sessions matching match string: $matchcnt") if $arg2; if ($commits_total > 0) { $rows_per_commit = 1; $z1 = int($commits_total / $lastet_total); $z2 = $commitrt_total; &msg("Matching Sessions - Total Commits=$commits_total AverageCommitRate=$z1 TotalCommitRate=$z2"); $rows = ($commits_total * $rows_per_commit); $rate = ($z2 * $rows_per_commit * 3600); &msg("PURGE - RowsProcessed=$rows RowsPerHour=$rate ($rows_per_commit rows/commit)"); } } #------------------------------------------------------------------------------ sub run_dst #------------------------------------------------------------------------------ { &msg("-dst: Check for 2007 DST Patch"); &checkDST; &msg("Test #1: Is DST patch for TZ columns applied:"); $sql = " select case to_number(to_char(to_timestamp_tz ('20070311 00:00:00 US/EASTERN','YYYYMMDD HH24:MI:SS TZR') + to_dsinterval('0 08:00:00'),'HH24')) when 8 then 'DST Patch has not been applied to this ORACLE_HOME' when 9 then 'DST Patch has been applied correctly to this ORACLE_HOME' else 'Error' end \"TZTEST (RUN FROM DB HOME)\" from dual; "; &oraSQL($sql); $dst_col_patch_applied = 0; foreach (@oraSQLout) { print if /DST/; $dst_col_patch_applied = 1 if /DST Patch has been applied/; } ##&msg("dst_col_patch_applied=$dst_col_patch_applied"); #---- Is JAVA VM installed if ($dst_JVM == 0) { &msg("Querying whether JVM is installed in this DB"); $sql = " select comp_name from dba_registry where comp_name like '%JAVA Virtual Machine%' and status != 'REMOVED';"; &oraSQL($sql); $dst_jvm_installed = 0; $dst_jvm_not_installed = 1; foreach (@oraSQLout) { next if /select/; if (/JAVA Virtual Machine/) { print; $dst_jvm_installed = 1; $dst_jvm_not_installed = 0; } } &msg("dst_jvm_installed=$dst_jvm_installed"); } #---- Test JVM (If it is installed) if ($dst_jvm_installed) { &msg("Test #2: Is DST patch for JVM applied:"); $sql = " create or replace java source named \"DBAmonOffsetFromStandard\" as import java.util.Calendar; import java.util.GregorianCalendar; import java.util.TimeZone; public class DBAmonOffsetFromStandard { public static int getDSTDBAmonOffset( String timezone, int year, int month, int mday, int hour, int min, int sec) { int RetVal = -360000000; String[] TZs = TimeZone.getAvailableIDs(); for (int i = 0; i < TZs.length; i++) { if (timezone.equals(TZs[i])) { TimeZone tz = TimeZone.getTimeZone(timezone); GregorianCalendar c = new GregorianCalendar(tz); c.set(year, month-1, mday, hour, min, sec); RetVal = c.get(Calendar.DST_OFFSET); }; } return RetVal; } } / alter java class \"DBAmonOffsetFromStandard\" resolve / CREATE OR REPLACE function get_dst_offset (timezone VARCHAR2, year NUMBER, month NUMBER, mday NUMBER, hour NUMBER, min NUMBER, sec NUMBER) RETURN NUMBER AS LANGUAGE JAVA NAME 'DBAmonOffsetFromStandard.getDSTDBAmonOffset (java.lang.String, int, int, int, int, int, int) return int'; / select 'DST_CHECK', get_dst_offset('America/Los_Angeles', 2007, 3, 11, 10, 0, 0)/(60*60*1000) as OFFSET_FROM_STANDARD_TIME from dual; "; ##&msg("sql=$sql"); &oraSQL($sql); foreach (@oraSQLout) { ##print; $jvm_output .= $_; @words = split; $verb = $words[0]; if ($verb eq "DST_CHECK") { $dst_jvm_installed = 1; $dst_jvm_result = $words[1]; &msg("dst_jvm_result=$dst_jvm_result"); } } if ($jvm_output =~ /ORA-29547/ || $jvm_output =~ /ORA-29538/) { &msg("JVM Not installed"); $dst_jvm_not_installed = 1; $dst_jvm_installed = 0; } if ($dst_jvm_result == 1) { $dst_jvm_patch_applied = 1; } ##print $jvm_output; } #---- Conclusion Logic START print "\n"; &msg("Conclusion:"); #---- DST Column Problem if (! $dst_col_nonsys && ! $dst_col_sys) { &msg("DST Column Patch NOT NEEDED since this instance does NOT have any DST columns (SYS or Non-SYS)"); } elsif (($dst_col_nonsys || $dst_col_sys) && $dst_col_patch_applied) { &msg("DST Column Patch IS NEEDED AND ALREADY APPLIED"); } elsif (($dst_col_nonsys || $dst_col_sys) && ! $dst_col_patch_applied) { &msg("DST Column Patching IS NEEDED since this instance does have DST columns (SYS or Non-SYS) and the patch is NOT applied"); $dst_col_required = 1; } if ($dst_jvm_not_installed) { &msg("DST JVM Patch NOT NEEDED since this instance does NOT have JVM installed"); } elsif ($dst_jvm_installed && $dst_jvm_patch_applied) { &msg("DST JVM Patch IS NEEDED AND ALREADY APPLIED"); } elsif ($dst_jvm_installed && ! $dst_jvm_patch_applied) { &msg("DST JVM Patching IS NEEDED since this instance does have JVM enabled and the patch is NOT applied"); $dst_jvm_required = 1; } #---- if ($dst_col_required) { &msg("DST Patch Missing and Required (DSTCOL)"); } elsif ($dst_jvm_required) { &msg("DST Patch Missing and Required (JVM)"); } print "\n"; #---- Conclusion Logic END &msg("Done"); } #------------------------------------------------------------------------------ sub run_spf #------------------------------------------------------------------------------ { &msg("-spf: SPFILE Contents"); #---- See if this instance has SPFILE specified chop($spfile = `orastat -cp | grep '^spfile ' | head -1 | awk '{ print \$2 }'`); &msg("Derived spfile=$spfile"); if ($spfile eq "" || $spfile eq "()") { &msg("This instance does not have SPFILE specified - Exiting"); exit; } chop($dbname = `orastat - | grep 'DBName:' | head -1 | awk '{ print \$NF }'`); &msg("Derived dbname=$dbname"); if (-e "/opt/oracle/admin/$dbname") { $dir = "/opt/oracle/admin/$dbname"; } else { $dir = "/opt/oracle/admin/$os"; } $pfile = "$dir/pfile/pfile_${os}_bkup.txt"; &msg("Copy of SPFILE will be written to $pfile"); $sql = "create pfile='$pfile' from spfile;"; &oraSQL($sql); foreach (@oraSQLout) { print; } &msg("SPFILE=$spfile contents"); print "\n"; print "=======================================================================\n"; system("sort $pfile"); print "=======================================================================\n"; print "\n"; } #------------------------------------------------------------------------------ sub run_srt #------------------------------------------------------------------------------ { &msg("-srt: SQL Response Time (From v\$sqlstats)"); $sql = " select 'Flag_RT', sum(executions) executions_total, sum(elapsed_time)/1000 elapsed_time_total_secs, (sum(elapsed_time)/sum(executions))/1000 average_exec_time_secs, (sum(cpu_time)/sum(executions))/1000 average_cpu_time_secs, count(*) from v\\\$sql where executions > 0; "; $srt_execs = "?"; $srt_total_time = "?"; $srt_avg_time = "?"; $srt_avg_cpu = "?"; # 'FLAG_R EXECUTIONS_TOTAL ELAPSED_TIME_TOTAL_SECS AVERAGE_EXEC_TIME_SECS AVERAGE_CPU_TIME_SECS # ------- ---------------- ----------------------- ---------------------- --------------------- # Flag_RT 73745426 77619125.7 1.052528 .939600318 &oraSQL($sql); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Flag_RT") { $dfcount++; $srt_execs = sprintf("%.0f",$words[1]); $srt_total_time = sprintf("%.0f",$words[2]); $srt_avg_time = sprintf("%.8f",$words[3]); $srt_avg_cpu = sprintf("%.8f",$words[4]); $stmt_cnt = sprintf("%.0f",$words[5]); } } print "\n"; &msg("Total_SQL_Execs: $srt_execs"); &msg("Total_SQL_Time: $srt_total_time"); &msg("SQL_Stmt_Count: $stmt_cnt"); &msg("SQL_Avg_CPU_Secs: $srt_avg_cpu"); &msg("SQL_Avg_Time_Secs: $srt_avg_time"); print "\n"; &msg("Done"); } #------------------------------------------------------------------------------ sub run_uns #------------------------------------------------------------------------------ { &msg("-uns: Undo Summary"); $sql = " column gb format 999,999.9 SELECT DISTINCT 'Flag_M', STATUS, (SUM(BYTES) / (1024*1024*1024)) GB, COUNT(*) FROM DBA_UNDO_EXTENTS GROUP BY 'Flag_M', STATUS; "; print "\n"; print "Undo Extent Total Size\n"; print "Status (GB)\n"; print "------------ ----------\n"; &oraSQL($sql); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Flag_M") { $dfcount++; $cat = $words[1]; $gb = sprintf("%.1f",$words[2]); printf("%-12s %10s\n",$cat,$gb); $total_gb += $gb; } } print "============ ==========\n"; printf("%-12s %10s\n","Total:",$total_gb); print "\n"; &msg("Run 'orastat -un' to view the current V\$UNDOSTATS values"); &msg("Done"); } #------------------------------------------------------------------------------ sub run_ses #------------------------------------------------------------------------------ { &msg("-ses: DB Session Summary"); $sql = " select 'Flag_S1', status, count(*) from v\\\$session group by 'Flag_S1', status order by 2; "; &oraSQL($sql); print "\n"; print "Session Session\n"; print "Status Count\n"; print "-------- --------\n"; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Flag_S1") { $status = $words[1]; $ses_count = $words[2]; printf("%-8s %8d\n",$status,$ses_count); $total_ses += $ses_count; } } print "======== ========\n"; printf("%-8s %8d\n","Total:",$total_ses); $sql = " select 'Flag_S1', nvl(username,\'(Null)\'), count(*) from v\\\$session group by 'Flag_S1', nvl(username,\'(Null)\') order by 3, 2; "; &oraSQL($sql); print "\n"; print "Database Session\n"; print "Username Count\n"; print "---------------------------------------- --------\n"; $total_ses = 0; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Flag_S1") { $user = $words[1]; $ses_count = $words[2]; $total_ses += $ses_count; $id = "$user" ; printf("%-40s %8d\n",$id,$ses_count); } } print "======================================== ========\n"; printf("%-40s %8d\n","Total:",$total_ses); print "\n"; &msg("Done"); } #------------------------------------------------------------------------------ sub run_df5 #------------------------------------------------------------------------------ { &msg("-df5 Datafiles"); print "\n"; print "Tablespace DF Datafile Datafile Datafile \n"; print "Name Num Path Status Size(MB) \n"; print "---------------------------- ---- ---------------------------------------------------------------------- --------- ---------\n"; #---- Old SQL #$sqlstmt = ' #column file_name format a70 # #select \'X\', #tablespace_name, #file_name, #nvl(bytes,0), #file_id, #nvl(status,\'?\') #from dba_data_files order by 4 desc, 3; #'; #---- New SQL $sqlstmt = ' column file_name format a70 select \'X\', ts.name, df.name, nvl(df.bytes,0), df.file#, nvl(df.status,\'?\') from v\$datafile df, v\$tablespace ts where df.ts# = ts.ts# order by 4 desc, 3; '; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $dfcount++; $status = ""; $ts = $words[1]; $df = $words[2]; $size = $words[3]/1048576; $num = $words[4]; $status = $words[5]; printf("%-28s %4d %-70s %-8s %9d\n",$ts,$num,$df,$status,$size); } } print "\n"; &msg("Found $dfcount datafile(s)"); } #------------------------------------------------------------------------------ sub run_da #------------------------------------------------------------------------------ { &msg("-da: Datafile Autoextend Details"); print "\n"; print "Tablespace DF Datafile Datafile Datafile Max Incr \n"; print "Name Num Path Status Size(MB) AutoExt? Size(MB) By(MB)\n"; print "---------------- ---- ------------------------------------------------------- --------- --------- -------- --------- ---------\n"; $sqlstmt = 'select \'X\', tablespace_name, file_name, nvl(bytes,0), file_id, nvl(status,\'?\'), autoextensible, maxbytes, increment_by from dba_data_files order by 2,4 desc;'; $df_maxsize = 0; $autoext_count = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $dfcount++; $status = ""; $ts = $words[1]; $df = $words[2]; $size = $words[3]/1048576; $num = $words[4]; $status = $words[5]; $autoext= $words[6]; $maxsize= $words[7]/1048576; $incrby = $words[8]/1048576; ##print "num=$num \n"; printf("%-16s %4d %-55s %-8s %9d %-8s %9d %9d\n",$ts,$num,$df,$status,$size,$autoext,$maxsize,$incrby); $autoext_count++ if $autoext eq "YES"; $df_maxsize = $size if $size > $df_maxsize; } } print "\n"; &msg("DatafileCount: $dfcount"); &msg("DatafilesWithAutoextend: $autoext_count"); &msg("DatafileMaxSize: $df_maxsize"); } #------------------------------------------------------------------------------ sub run_pit #------------------------------------------------------------------------------ { if ($arg2 ne "") { $where = "and t.name like '${arg2}%' "; $timestamp = "$date TS="; } else { $where = ""; $timestamp = ""; } &msg("-pit: Performance I/O - By Tablespace - where=$where"); print "\n"; print "Tablespace Average I/O\n"; print "Name RT (MS)\n"; print "-------------------- ------------\n"; $sqlstmt = " set linesize 150 set pagesize 200 set tab off select 'X', t.name, avg(f.lstiotim*10) from v\\\$filestat f, v\\\$datafile d, v\\\$tablespace t where f.file# = d.file# and d.ts# = t.ts# and lstiotim != 65535 $where group by 'X', t.name order by 2;"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $tscount++; $ts = $words[1]; $avgiort = $words[2]; printf("${timestamp}%-20s %12.2f\n",$ts,$avgiort); } } print "\n"; } #------------------------------------------------------------------------------ sub run_dgl #------------------------------------------------------------------------------ { &msg("-dgl: DataGuard Log Apply Lag - Last 2 Days"); print "\n"; print "LogSeq Switch Timestamp Applied Delta vs. Now (Hrs)\n"; print "-------- ------------------- -------- -------------------\n"; $sqlstmt = "select 'X', sequence#, to_char(next_time,'MM/DD/YYYY-HH24:MI:SS') next_time, applied, round((sysdate-next_time) * 24,2) delta from v\\\$archived_log where dest_id = 2 and next_time > (sysdate - 2) order by 2;"; $min_delta = 999999; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = shift @words; if ($verb eq "X") { $seq = shift @words; $next_time = shift @words; $applied = shift @words; $delta = sprintf("%.2f",shift(@words)); printf("%8d %s %-8s %19.2f\n",$seq,$next_time,$applied,$delta); $min_delta = $delta if $applied eq "YES" && $delta < $min_delta; } } print "\n"; &msg("AppliedLogMinDelta: $min_delta"); } #------------------------------------------------------------------------------ sub run_brm #------------------------------------------------------------------------------ { $days = $arg2; $days = 90 if ! $arg2; &msg("-brm: Backup Media List - Last $days days"); print "\n"; # 2007/11/14-01:24:02 19 44266/1 bk_45859_1_638586079 TAG20071114T010115 /vol/cs05_ora_41_2/bigdogb_1195027460_C1_F1 print "Completion Time Elap-Min Recid/Pc Handle Tag Media\n"; print "-------------------- -------- ---------- -------------------------------- ------------------------ ------------------------------\n"; $sqlstmt = "select \'X\', recid, piece#, handle, media, tag, to_char(completion_time,\'YYYY/MM/DD-HH24:MI:SS\'), elapsed_seconds from v\\\$backup_piece where completion_time >= (sysdate - $days) order by 6;"; $rowcount = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $rowcount++; $recid = $words[1]; $piece = $words[2]; $handle = $words[3]; $media = $words[4]; $tag = $words[5]; $comp_time = $words[6]; $elapsed_min = $words[7]/60; $recid_piece = "$recid/$piece"; printf("%-20s %8d %-10s %-32s %-24s %-50s\n", $comp_time, $elapsed_min, $recid_piece, $handle, $tag, $media ); #---- Decide media type if (length($media) > 12) { $media_type = "D"; } #---- Disk (nearstore) elsif (length($media) == 6 && $media =~ /^V/) { $media_type = "V"; } #---- VTL (virtual tape library) else { $media_type = "T"; } #---- Tape } } print "\n"; &msg("Retrieved $rowcount rows"); &msg("LastMediaType: $media_type"); } # -------------------------------------------------------------------- sub run_di # -------------------------------------------------------------------- { &msg("-di: Datafile Contents - DF#=$arg2 - Ordered by File#,Block_ID"); if ($arg2 eq "") { &msg("Usage: $P -di datafile-number"); exit; } $sql = "select /*+rule*/ 'X-Flag', file_id , BLOCK_ID , BLOCKS , SEGMENT_TYPE , OWNER , SEGMENT_NAME from dba_extents where file_id = $arg2 order by 2,3 ;"; print "\n"; print "FIleNum BlockID BlockCnt SegType SegmentName\n"; print "----------- -------- -------- ------------ --------------------------------------------\n"; $extents = 0; oraSQL($sql); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift(@words); if ($verb eq 'X-Flag') { $file_id = shift(@words); $block_id = shift(@words); $blocks = shift(@words); $segtype = shift(@words); $segowner = shift(@words); $segname = shift(@words); $zobj = $segowner . "." . $segname; $zfile = "File=$file_id"; printf "%-12s %8s %8s %-12s %-40s\n", $zfile, $block_id, $blocks, $segtype, $zobj ; $extents++; } } print "\n"; &msg("Found $extents extents"); } # -------------------------------------------------------------------- sub run_asm # -------------------------------------------------------------------- { &msg("-asm: ASM Details & Status"); $sql = "select \'X-Flag\', count(*) from v\\\$asm_diskgroup; "; &oraSQL($sql); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift(@words); if ($verb eq 'X-Flag') { $dg_count = shift(@words); } } if ($dg_count == 0) { &msg("ASM Not running for this instance (V\$ASM_DISKGROUP is empty)"); exit; } print "\n"; &run_asm_dg; print "\n"; &run_asm_dk; print "\n"; &run_asm_op; } # -------------------------------------------------------------------- sub run_asm_dg # -------------------------------------------------------------------- { &msg("-asm_dg: ASM Diskgroups"); $onegig = "(1024*1024*1024)"; $sql = "select \'X-Flag\', group_number, translate(name,\' \',\'_\'), sector_size, block_size, ALLOCATION_UNIT_SIZE, STATE, TYPE, TOTAL_MB / 1024, FREE_MB / 1024, USABLE_FILE_MB / 1024, OFFLINE_DISKS, UNBALANCED from \\\$asm_diskgroup ; order by 3; "; print "\n"; print " Diskgroup Grp# State RedunType Alloc Sec/Blk/Unit OfflDisks Unbal? Size-GB Free-GB Used-GB %Full \n"; print " ---------------- ---- ---------- ---------- ------------------ ---------- ------ -------- --------- -------- ------\n"; &oraSQL($sql); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift(@words); if ($verb eq 'X-Flag') { $group_number = shift(@words); $name = shift(@words); $sector_size = shift(@words); $block_size = shift(@words); $alloc_size = shift(@words); $state = shift(@words); $type = shift(@words); $total_gb = sprintf("%.2f",shift(@words)); $free_gb = sprintf("%.2f",shift(@words)); $usable_gb = sprintf("%.2f",shift(@words)); $offline_disks= shift(@words); $unbalanced = shift(@words); $usable_gb += 0; #---- No more compile warnings $used_gb = sprintf("%.2f",$total_gb - $free_gb); $pct_full = sprintf("%.2f", ($used_gb / $total_gb) * 100) if $total_gb > 0; $alloc = "$sector_size/$block_size/$alloc_size"; printf "DG: %-16s %4s %-10s %-10s %18s %10s %-6s %8s %8s %8s %6s%%\n", $name, $group_number, $state, $type, $alloc, $offline_disks, $unbalanced, $total_gb, $free_gb, $used_gb, $pct_full; $t_total_gb += $total_gb; $t_free_gb += $free_gb; $t_used_gb += $used_gb; } } $t_pct_full = sprintf("%.2f", ($t_used_gb / $t_total_gb) * 100); print " ================ ==== ========== ========== ================== ========== ====== ======== ========= ======== ======\n"; printf " %-16s %4s %-10s %-10s %18s %10s %-6s %8s %8s %8s %6s%%\n", "DGTotals:", "", "", "", "", "", "", $t_total_gb, $t_free_gb, $t_used_gb, $t_pct_full; } # -------------------------------------------------------------------- sub run_asm_dk # -------------------------------------------------------------------- { &msg("-asm_dk: ASM Disks"); $onegig = "(1024*1024*1024)"; $sql = "select \'X-Flag\', group_number, disk_number, translate(name,\' \',\'_\'), state, path, TOTAL_MB / 1024, FREE_MB / 1024, reads / (1024*1024), writes / (1024*1024), bytes_read / (1024*1024), bytes_written / (1024*1024), read_time*10, write_time*10 from v\\\$asm_disk where group_number > 0 order by name; "; print "\n"; print "Disk Grp# Dsk# State Path Size-GB Free-GB Used-GB M-Reads M-Writes MB-R MB-W Avg-R-Ms Avg-W-Ms\n"; print "---------------- ---- ---- ---------- ------------------------------------ -------- -------- -------- -------- -------- -------- -------- -------- --------\n"; &oraSQL($sql); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift(@words); if ($verb eq 'X-Flag') { $group_number = shift(@words); $disk_number = shift(@words); $name = shift(@words); $state = shift(@words); $path = shift(@words); $total_gb = sprintf("%.2f",shift(@words)); $free_gb = sprintf("%.2f",shift(@words)); $reads = sprintf("%.2f",shift(@words)); $writes = sprintf("%.2f",shift(@words)); $bytes_read = sprintf("%.0f",shift(@words)); $bytes_written = sprintf("%.0f",shift(@words)); $read_time = shift(@words); $write_time = shift(@words); $used_gb = sprintf("%.2f",$total_gb - $free_gb); $avg_read_time = sprintf("%.2f",$read_time / ($reads * (1024*1024))) if $reads > 0; $avg_write_time = sprintf("%.2f",$write_time / ($writes * (1024*1024))) if $writes > 0; printf "%-16s %4s %4s %-10s %-36s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n", $name, $group_number, $disk_number, $state, $path, $total_gb, $free_gb, $used_gb, $reads, $writes, $bytes_read, $bytes_written, #$read_time, #$write_time $avg_read_time, $avg_write_time ; $t_total_gb += $total_gb; $t_free_gb += $free_gb; $t_used_gb += $used_gb; } } } # -------------------------------------------------------------------- sub run_asm_op # -------------------------------------------------------------------- { &msg("-asm_op: ASM Ongoing Rebalance Operations"); # GROUP_NUMBER NUMBER # OPERATION VARCHAR2(5) # STATE VARCHAR2(4) # POWER NUMBER # ACTUAL NUMBER # SOFAR NUMBER # EST_WORK NUMBER # EST_RATE NUMBER # EST_MINUTES NUMBER $sql = "select \'X-Flag\', group_number, operation, translate(state,\' \',\'?\'), power, actual, sofar, est_work, est_rate, est_minutes from v\\\$asm_operation order by 2, 3; "; print "\n"; print "Diskgrp# Operation State Power Actual SoFar EstWork EstRate EstMin \n"; print "---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n"; &oraSQL($sql); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift(@words); if ($verb eq 'X-Flag') { $group_num = shift(@words); $oper = shift(@words); $state = shift(@words); $power = shift(@words); $actual = shift(@words); $sofar = shift(@words); $est_work = shift(@words); $est_rate = shift(@words); $est_min = shift(@words); printf "%10s %-10s %-10s %10s %10s %10s %10s %10s %10s\n", $group_num, $oper, $state, $power, $actual, $sofar, $est_work, $est_rate, $est_min ; } } } # -------------------------------------------------------------------- sub run_asm_fi # -------------------------------------------------------------------- { &msg("asm_fi: ASM Files"); $sql = 'select distinct \'Flag-InASM\', instance_name from v\$asm_client;'; &oraSQL($sql); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift(@words); if ($verb eq 'Flag-InASM') { $asm_instance = shift(@words); last; } } if (! $asm_instance) { &msg("Error: Cannot determine ASM instance name from V\$ASM_CLIENT:instance_name"); exit 1; } &msg("Querying ASM instance $asm_instance for list of files"); print "\n"; system("ssh $host '. $toolsdir/envora +ASM1; echo \"find \* \*\" | asmcmd | grep -v \'^ASMCMD\' | sort'"); print "\n"; &msg("Done"); } # -------------------------------------------------------------------- sub run_amm # -------------------------------------------------------------------- { &msg("-amm: Automatic Memory Management Status (pool sizes in MB)"); $onegig = "(1024*1024*1024)"; $onemeg = "(1024*1024)"; $sql = "select \'X-Flag\', translate(component,\' \',\'_\'), CURRENT_SIZE / $onemeg , MIN_SIZE / $onemeg , MAX_SIZE / $onemeg , USER_SPECIFIED_SIZE / $onemeg , OPER_COUNT , LAST_OPER_TYPE , LAST_OPER_MODE , to_char(last_oper_time,\'YYYY/MM/DD-HH24:MI:SS\') from v\\\$sga_dynamic_components where current_size > 0;"; print "\n"; print "SGA Component Current Size Min Size Max Size Spec'd Size Resize Count Resize Type Resize Mode Resize Date\n"; print "------------------- ------------- ------------ ------------ ------------ ------------ ------------ ------------ --------------------\n"; &oraSQL($sql); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift(@words); if ($verb eq 'X-Flag') { $component = shift(@words); $current_size = sprintf("%.2f",shift(@words)); $min_size = sprintf("%.2f",shift(@words)); $max_size = sprintf("%.2f",shift(@words)); $user_size = sprintf("%.2f",shift(@words)); $oper_count = shift(@words); $oper_type = shift(@words); $oper_mode = shift(@words); $oper_time = shift(@words); printf "%-20s %12s %12s %12s %12s %12s %-12s %-12s %-12s\n", $component, $current_size, $min_size, $max_size, $user_size, $oper_count, $oper_type, $oper_mode, $oper_time } } } # -------------------------------------------------------------------- sub run_up # -------------------------------------------------------------------- { &msg("-up: DB User Password Info"); $sql = " select 'X-Flag', du.username, du.profile, du.account_status, nvl(to_char(du.lock_date,'YYYY/MM/DD-HH24:MI:SS'),'?') , nvl(to_char(du.created,'YYYY/MM/DD-HH24:MI:SS') ,'?'), nvl(to_char(du.expiry_date,'YYYY/MM/DD-HH24:MI:SS') ,'?'), --nvl(du.expiry_date - sysdate, '?') du.expiry_date - sysdate from dba_users du order by 2; "; print "\n"; print "User Profile Status Create Date PW Expiry Date Days Until PW Expires\n"; print "-------------------- -------------------- -------------------------------- ------------------- ------------------- ---------------------\n"; $sys_locked = 0; $sys_past = 0; $sys_min_days = 99999999999; &oraSQL($sql); foreach (@oraSQLout) { print if /ORA-/; @words = split(); $verb = shift(@words); if ($verb eq 'X-Flag') { $user = shift(@words); $profile = shift(@words); $status = shift(@words); $lock_date = shift(@words); $create_date = shift(@words); $expiry_date = shift(@words); $days_until_expiry = shift(@words); $status .= "(Locked $lock_date)" if $status =~ /LOCKED/; $days_until_expiry = sprintf("%.2f",$days_until_expiry); if ($days_until_expiry eq "") { $days_out = "?"; } elsif ($days_until_expiry >= 0) { $days_out = $days_until_expiry; } else { $days_out = "(Past)"; } if ( $user eq "SYS" || $user eq "SYSTEM" || $user eq "PERFSTAT" || $user eq "DBSNMP" || $user eq "DBAMON" ) { if ($status =~ /EXPIRED/ || $status =~ /LOCKED/) { $sys_locked++; } if ($days_out > 0 && $days_out < $sys_min_days) { $sys_min_days =$days_out; } if ($days_out =~ /Past/) { $sys_past++; } } printf "%-20s %-20s %-32s %-19s %-19s %-16s\n", $user, $profile, $status, $create_date, $expiry_date, $days_out; $rows++; } } print "\n"; &msg("Users Found: $rows"); &msg("SYSUsers_Locked: $sys_locked"); &msg("SYSUsers_Past: $sys_past"); &msg("SYSUsers_Min_Days_Until: $sys_min_days"); } # -------------------------------------------------------------------- sub run_fra # -------------------------------------------------------------------- { &msg("-fra: Flash Recovery Area Status"); $onegig = "(1024*1024*1024)"; $sql = "select \'X-Flag\', name, space_limit / $onegig, space_used / $onegig, space_reclaimable / $onegig, number_of_files from v\\\$recovery_file_dest; "; print "\n"; print " Limit(gB) Used(gB) Reclaimable(gb) Net Used(gB) File Count\n"; print "---------------- ---------------- ---------------- ---------------- ----------------\n"; &oraSQL($sql); foreach (@oraSQLout) { @words = split(); $verb = shift(@words); if ($verb eq 'X-Flag') { $franame = shift(@words); $limit = sprintf("%.2f",shift(@words)); $used = sprintf("%.2f",shift(@words)); $reclaimable = sprintf("%.2f",shift(@words)); $nofiles = shift(@words); $netused = sprintf("%.2f", $used - $reclaimable); printf "%16s %16s %16s %16s %16s\n", $limit, $used, $reclaimable, $netused, $nofiles; } } $sql = "select \'X-Flag\', FILE_TYPE, PERCENT_SPACE_USED, PERCENT_SPACE_RECLAIMABLE, NUMBER_OF_FILES from v\\\$flash_recovery_area_usage; order by 1"; print "\n"; print "File Type % Used % Reclaimable File Count\n"; print "---------------- ---------------- ---------------- ----------------\n"; &oraSQL($sql); foreach (@oraSQLout) { @words = split(); $verb = shift(@words); if ($verb eq 'X-Flag') { $filetype = shift(@words); $pctused = sprintf("%.2f",shift(@words)); $pctrec = sprintf("%.2f",shift(@words)); $nofiles = shift(@words); ## &msg("DEBUG pctrec=$pctrec"); printf "%-16s %16s %16s %16s\n", $filetype, $pctused, $pctrec, $nofiles; } } if ($franame) { $pctfull = sprintf("%.2f",( ($used - $reclaimable) / $limit) * 100 ); print "\n"; print "Flash db_recovery_file_dest File (FRAFILE): $franame\n"; print "Flash Recovery Area Percent Full (FRAFULL): ${pctfull}%\n"; } else { print "\n"; &msg("Flash Recovery Area (db_recovery_file_dest) not configured"); } } # -------------------------------------------------------------------- sub run_sz # -------------------------------------------------------------------- { $sid = $arg2; if (! $arg2) { &msg("Usage: orastat -sz SID"); return; } &msg("-sa: Session Statistics for session $sid"); $sqlstmt = "select \'X\', vss.value, vsn.name from v\\\$sesstat vss, v\\\$statname vsn where (vss.statistic#=vsn.statistic#) AND vss.value <> 0 and vss.sid = $arg2 order by 3;"; print "Session Statistic Value\n"; print "------------------------------------------------------------ ---------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; if ($verb eq 'X') { $value = $words[1]; $text = ""; for ($i = 2; $i <= $#words; $i++) { $text .= $words[$i]; $text .= " "; } printf "%-60s %15s\n",$text,$value; } } } # -------------------------------------------------------------------- sub run_cc # -------------------------------------------------------------------- { &msg("-cc: Client Connections - From other servers"); $sqlstmt = " select \'Z\', machine, count(*) from v\\\$session where machine is not null and machine != '$host' group by \'Z\', machine; "; print "\n"; print "Client Hostname Client IP Address Connection Count\n"; print "---------------------------------------- ----------------- ----------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = shift @words; if ($verb eq "Z") { $client = shift @words; $count = shift @words; chop($ipaddr = `nslookup $client 2>/dev/null | grep 'Address:' | head -1 | awk '{ print \$2 }'`); $client_string = "Client: $client"; printf("%-40s %-17s %16d\n",$client_string,$ipaddr,$count); $network = (split(/\./,$ipaddr)) [0] ; $network_count{$network} += $count if $network ne ""; } } close(RO); print "\n"; print "Network Connection Count\n"; print "--------------- ----------------\n"; foreach $network (sort keys %network_count) { $netstring = "Network: $network"; printf("%-15s %16d\n",$netstring,$network_count{$network}); } print "\n"; } # -------------------------------------------------------------------- sub run_tt # -------------------------------------------------------------------- { $tot_size = 0; $tot_free = 0; $tot_used = 0; $tot_df = 0; $sql = " select \'Y\', value from v\\\$parameter where name in (\'db_block_size\'); select \'X\', a.tablespace_name as tablespace_name, a.size_blocks, nvl(a.max_id,0), nvl(c.used_blocks,0), d.status, d.extent_management, d.allocation_type from ( select tablespace_name, sum(blocks) as size_blocks, count(1) max_id from dba_temp_files group by tablespace_name ) a, ( select tablespace_name, sum(used_blocks) as used_blocks from v\\\$sort_segment group by tablespace_name ) c, dba_tablespaces d where a.tablespace_name = c.tablespace_name (+) and a.tablespace_name = d.tablespace_name (+); "; print "\n"; print "TemporaryTablespace Type Status ExtentMgmt AllocTyp NumDF Size(MB) Free(MB) Used(MB) Pct\n"; print "------------------------ ---- -------- ---------- -------- ----- --------- --------- --------- ------\n"; &oraSQL($sql); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split; $verb = $words[0]; if ($verb eq "Y") { $block_size = $words[1]; } if ($verb eq "X") { &error("Something is wrong - block_size is NULL") if ! $block_size; $found = 1; $ts = $words[1]; $size_blocks = $words[2]; $num_df = $words[3]; $used_blocks = $words[4]; $status = $words[5]; $extmgmt = $words[6]; $alloctyp = $words[7]; $size = ($size_blocks * $block_size) / 1048576; $used = ($used_blocks * $block_size) / 1048576; $free = $size - $used; if ($size == 0) { $pct = 0; } else { $pct = ($used / $size) * 100; } $type = "TEMP"; printf("%-24s %-4s %-8s %-10s %-8s %5d %9d %9d %9d %6.2f \n",$ts,$type,$status,$extmgmt,$alloctyp,$num_df,$size,$free,$used,$pct); $tot_size += $size; $tot_free += $free; $tot_used += $used; $tot_df += $num_df; } } if (!$found) { print "$P | Something is wrong - query returned no rows\n"; exit 1; } print "======================== ==== ======== ========== ======== ===== ========= ========= ========= ======\n"; $ts = "Total:"; $pct = ($tot_used / $tot_size) * 100; printf("%-24s %5d %9d %9d %9d %6.2f\n",$ts,$tot_df,$tot_size,$tot_free,$tot_used,$pct); print "\n"; &msg("NOTE: These numbers are COMPLETELY ACCURATE. They show"); &msg(" v\$sort_usage and dba_temp_file data."); } # -------------------------------------------------------------------- sub run_mr # -------------------------------------------------------------------- { $howmuch = $arg2; $raw = $arg3; $sqlstmt = ' select \'Z\', value from v\$parameter where name =\'background_dump_dest\';'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Z") { $fname = $words[1]; } } close(RO); $fname =~ s/\?/$oh/g; &msg("Alert Log: $fname Reformatted") unless $raw; &msg("================================================================") unless $raw; if ($fname eq "") { &msg("ERROR: bdump Directory is BLANK - Something is Wrong - Assuming default filename") unless $raw; $fname = "/opt/oracle/admin/$os/bdump"; &msg("Trying $fname") unless $raw; } $howmuch = 20 if ! $howmuch; &alertLogReformat("$fname/alert_$os.log",$howmuch); &msg("================================================================") unless $raw; } # -------------------------------------------------------------------- sub run_lg # -------------------------------------------------------------------- { &msg("-lg: Long Operations Progress - Where time_remaining > 0"); $sqlstmt = ' select \'Z\', sid, serial#, context, sofar, totalwork, last_update_time - start_time, --round(sofar/totalwork*100,2) "PctComplete", to_char(start_time,\'YYYY/MM/DD-HH24:MI:SS\') , to_char(last_update_time,\'YYYY/MM/DD-HH24:MI:SS\') , opname from v\$session_longops where time_remaining > 0 order by 8, 4;'; print "SID-Ser# Start Last Updated El. Mins Work Sofar Work Total Pct. Done Desc.\n"; print "------------ ------------------- ------------------- -------- ---------- ---------- ---------- ------------------------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; $sid = $words[1]; $ser = $words[2]; #$context = $words[3]; $sofar = $words[4]; $totalwk = $words[5]; $etime = sprintf("%5.1f",$words[6] * (24*60)); $stime = $words[7]; $utime = $words[8]; $opname = $words[9] . $words[10] . $words[11] . $words[12]; if ($totalwk > 0) { $pctcomp = sprintf("%7.3f",($sofar/$totalwk)*100); } else { $pctcomp = "*"; } $totalsize = $blocksize * $sofar; $gbrate = "?"; $sidser = "$sid-$ser"; if ($verb eq "Z") { printf "%-12s %-19s %-19s %8s %10s %10s %10s %-10s \n",$sidser,$stime,$utime,$etime, $sofar,$totalwk,$pctcomp,$opname; } } exit; } # -------------------------------------------------------------------- sub run_df4 # -------------------------------------------------------------------- { &msg("-df4 Datafiles which house S* tables with >= \$arg2 ($arg2) columns"); $arg2 = 250 if ! $arg2; if ($arg2 < 0 || $arg2 > 1000) { &msg("Usage: $P -df4 "); exit; } &msg("Column Count (arg2): $arg2"); print "\n"; print "Tablespace DF Datafile Datafile Datafile \n"; print "Name Num Path Status Size(MB) \n"; print "------------------------ ---- ---------------------------------------------------------------------- --------- ---------\n"; $sqlstmt = " column nbytes format 999999999999 column file_name format a60 select 'Flag_X', tablespace_name, file_name, nvl(bytes,0) nbytes, file_id, nvl(status,'?') dfstatus from dba_data_files where file_id in ( select distinct file_id from dba_extents where segment_name in ( select table_name from dba_tab_columns where table_name like 'S%' -- and owner = 'SIEBEL' having count(*) >= $arg2 group by table_name) ) order by 4 desc, 3; "; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Flag_X") { $dfcount++; $status = ""; $ts = $words[1]; $df = $words[2]; $size = $words[3]/1048576; $num = $words[4]; $status = $words[5]; ##print "num=$num \n"; printf("%-24s %4d %-70s %-8s %9d\n",$ts,$num,$df,$status,$size); } } print "\n"; &msg("Found $dfcount datafile(s)"); exit; } # -------------------------------------------------------------------- sub run_df3 # -------------------------------------------------------------------- { &msg("-df3: Datafile list from v\$datafile"); $sqlstmt = ' select \'Z\', name from v\$datafile order by 2;'; print "\nDatafile\n"; print "-------------------------------------------------\n"; $dfcount = 0; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; $df = $words[1]; if ($verb eq "Z") { printf "%-50s\n",$df; $dfcount++; } } print "\n"; &msg("Found $dfcount datafiles"); exit; } # -------------------------------------------------------------------- sub run_dp # -------------------------------------------------------------------- { &msg("-dp: Datafile Properties from database_properties"); $sqlstmt = ' select \'Z\', property_name, property_value from database_properties order by 2;'; print "\n"; print "Name Value\n"; print "------------------------------ ------------------\n"; $dfcount = 0; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Z") { $name = $words[1]; $val = $words[2]; printf "%-30s %-20s\n",$name, $val; } } exit; } # -------------------------------------------------------------------- sub run_pr # -------------------------------------------------------------------- { &msg("-pr: Profiles"); $sqlstmt = ' select \'Z\', profile, resource_type, resource_name, limit from dba_profiles order by 2,3,4;'; print "\n"; print "Profile ResourceType ResourceName Limit\n"; print "---------------- -------------- ---------------------------- ---------------------\n"; $dfcount = 0; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Z") { $prof = $words[1]; $rt = $words[2]; $rn = $words[3]; $li = $words[4]; printf "%-16s %-14s %-28s %-16s %-16s\n",$prof, $rt, $rn, $li; } } exit; } # -------------------------------------------------------------------- sub run_cd # -------------------------------------------------------------------- { &msg("-cd: Controlfile Details (Sections)"); $sqlstmt = ' set linesize 999 select \'Z\', translate(type,\' \',\'_\'), RECORD_SIZE, RECORDS_TOTAL, RECORDS_USED, FIRST_INDEX, LAST_INDEX, LAST_RECID from v\$controlfile_record_section order by 2; '; print "\n"; print "Record Type RecSize RecsTot RecsUsed FirstNdx LastNdx LstRecid\n"; print "------------------------ -------- -------- -------- -------- -------- --------\n"; $dfcount = 0; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Z") { $type = $words[1]; $recsiz = $words[2]; $rectot = $words[3]; $recuse = $words[4]; $indxfi = $words[5]; $indxla = $words[6]; $recila = $words[7]; printf "%-24s %8s %8s %8s %8s %8s %8s\n",$type, $recsiz, $rectot, $recuse, $indxfi, $indxla, $recila; } } exit; } # -------------------------------------------------------------------- sub run_bb # -------------------------------------------------------------------- { &msg("-bb: RMAN Backup Piece Summary - From v\$backup_piece"); $sqlstmt = ' select \'Z\', handle, max(to_char(completion_time,\'YYYY/MM/DD-HH24:MI:SS\')), max(elapsed_seconds), count(distinct media) from v\$backup_piece group by handle order by 3 ; '; print "\n"; print "Completion Timestamp Piece Handle Elapsed-Min. Media Cnt.\n"; print "-------------------- ------------------------- ------------ ----------\n"; $bkcount = 0; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Z") { $handle = $words[1]; $comptime = $words[2]; $mins = int($words[3] / 60); $mediacnt = $words[4]; printf "%-20s %-25s %12s %12s\n",$comptime, $handle, $mins, $mediacnt; $date = substr($comptime,0,10); $datetotal{$date} += $mins; $bkcount++; } } print "\n"; &msg("Found $bkcount distinct backup pieces"); print "\n"; print "Date Total Bkup Mins.\n"; print "---------- ----------------\n"; foreach (sort keys %datetotal) { $z = int($datetotal{$_} / 50); $banner = "*" x $z; printf "%-10s %16s %-50s\n",$_, $datetotal{$_}, $banner; } exit; } # -------------------------------------------------------------------- sub run_fm # -------------------------------------------------------------------- { $file = $arg2; &msg("-fm: File status $file"); if (! -e "$file") { &msg("File $file does not exist"); exit; } $fileage_secs = time - ( stat "$file" ) [9]; $fileage_hours = sprintf("%.2f",($fileage_secs / 3600)); &msg("Hours_Since_Update: $fileage_hours"); exit; } # -------------------------------------------------------------------- sub run_av # -------------------------------------------------------------------- { $days = $arg2; $days = 30 if $days eq ""; if ($arg3 eq "H") { $timestring = "YYYY/MM/DD-HH24"; $num = 60; } else { $arg3 = "D"; $timestring = "YYYY/MM/DD"; $num = 1440; } if ($oraver_num < 8.1) { &msg("orastat -av Does not work on Oracle < 8.1"); exit; } $days = $arg2; $days = 30 if $days eq ""; $rows = 0; #---- 3.01 Determine "match string" $av_match = "%archv0%"; # default $sqlstmt = " select \'X\', destination from v\\\$archive_dest where destination is not null order by dest_id;"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $dest = shift @words; $av_match = "%$dest%"; last; } } if ($dest =~ /^USE/) { $where = "dest_id = 10" } elsif ($oraver_num >= 10) { $where = "dest_id = 1" } else { $where = "name like '$av_match'"; } &msg("-av: Archivelog Volume - For the last $days days - Mode=$arg3"); &msg(" Destination where clause: $where"); $sqlstmt = " select \'X\', to_char(completion_time,\'$timestring\'), sum(blocks * block_size), count(*) from v\\\$archived_log where completion_time > sysdate - $days and $where group by to_char(completion_time,\'$timestring\') order by 2;"; print "\n"; print " Archive Archive REDO Rate \n"; print "Timestamp Data (MB) Log Count (MB/Min)* \n"; print "------------- ---------- ---------- ----------\n"; $max_size = -1; $max_count = -1; $max_mbmin = -1; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $ts = shift @words; $size = int((shift @words) / 1000000); $count = shift @words; $mbmin = int($size / $num); printf "%-13s %10s %10s %10s\n",$ts,$size,$count,$mbmin; $rows++; $total_size += $size; $total_count += $count; $total_mbmin += $mbmin; $max_size = $size if $size > $max_size; $max_count = $count if $count > $max_count; $max_mbmin = $mbmin if $mbmin > $max_mbmin; } } # Average line $ts = "(Average)"; $avg_size = int($total_size / $rows) if $rows > 0; $avg_count = int($total_count / $rows) if $rows > 0; $avg_mbmin = int($total_mbmin / $rows) if $rows > 0; print "------------- ---------- ---------- ----------\n"; printf "%-13s %10s %10s %10s\n",$ts,$avg_size,$avg_count,$avg_mbmin; # Max line $ts = "(Max)"; printf "%-13s %10s %10s %10s\n",$ts,$max_size,$max_count,$max_mbmin; # Total line $ts = "(Total)"; $tot_size = $total_size ; $tot_count = $total_count ; $tot_mbmin = $total_mbmin ; printf "%-13s %10s %10s %10s\n",$ts,$tot_size,$tot_count,$tot_mbmin; print "\n"; &msg("$rows Row(s) found - *: Average of a 24 hour period"); exit; } # -------------------------------------------------------------------- sub run_cs # -------------------------------------------------------------------- { &msg("-cs: Non-Default Active Parameters (from v\$parameter)"); print "Parm Value\n"; print "---------------------------------------- ---------------------------------------\n"; $sqlstmt = 'select \'X\', name, translate(value,\' \',\'_\') from v\$parameter where isdefault != \'TRUE\' order by 2;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = shift @words; if ($verb eq "X") { $name = shift @words; foreach (@words) { $value .= "$_ "; } printf "%-40s %-s\n", $name, $value; $value = ""; } } } # -------------------------------------------------------------------- sub run_cm # -------------------------------------------------------------------- { &msg("-cm: Active Parameters And Modifiable Settings (from v\$parameter)"); print "Parm IsDefault IsSesMod IsSysMod IsMod IsAdj Value\n"; print "---------------------------------------- --------- --------- --------- --------- --------- ------------------------------\n"; $sqlstmt = 'select \'X\', name, translate(value,\' \',\'_\'), isdefault, isses_modifiable, issys_modifiable, ismodified, isadjusted from v\$parameter order by 2;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; $name = $words[1]; $value = $words[2]; $isdef = $words[3]; $isses = $words[4]; $issys = $words[5]; $ismod = $words[6]; $isadj = $words[7]; if ($verb eq "X") { printf "%-40s %-9s %-9s %-9s %-9s %-9s %-30s\n", $name, $isdef, $isses, $issys, $ismod, $isadj, $value; } } } # -------------------------------------------------------------------- sub run_su # -------------------------------------------------------------------- { &msg("-su: System Utilization"); &msg("Collecting CPU busy sample"); #---- Old way #chop($cpuidle = `timex -s sleep 2 2>&1 | grep ":" | tail -1 | awk '{ print \$5 }'`); #---- New way chop($cpuidle = `vmstat 1 5 | tail -4 | awk '{total +=\$NF};END {print (total/4) }'`); $cpubusy = 100-$cpuidle; &msg("CPU(s) Busy: $cpubusy%"); } # -------------------------------------------------------------------- sub run_dd # -------------------------------------------------------------------- { &msg("-dd: Create DDL - Object=$arg3.$arg4 Type=$arg2"); if ($oraver < 9) { &msg("orastat -dd Will only work with Oracle 9i"); exit; } $arg2_uc = uc $arg2; $arg3_uc = uc $arg3; $arg4_uc = uc $arg4; $rows = 0; print "\n"; $sqlstmt = " SELECT \'X\', dbms_metadata.get_ddl ('$arg2_uc','$arg4_uc','$arg3_uc') FROM dual;"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; print if $printflag && /^ /; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $printflag = 1; $rows++; } } print "\n"; &msg("Object $arg3.$arg4 type=$arg2 Not Found") if !$rows; exit; } #------------------------------------------------------------------------------ sub run_cfbl #------------------------------------------------------------------------------ { &msg("-cfbl: List Controlfile Backups - arg2=$arg2"); $cfdir = "/var/opt/oracle/bkup01/$os/ctrltrace"; opendir(CFDIR,"$cfdir"); @filenames = readdir(CFDIR); @filenamessorted = sort @filenames; closedir(CFDIR); print "\n"; print "Archive Log File Name CF Backup Create Time Age(Secs) FileSize\n"; print "------------------------------------------------------ ------------------------------ --------- ---------\n"; $numlogs = 0; $totsize = 0; $age = -1; foreach $file (@filenamessorted) { next if ($file !~ /^2/); if (system("grep '$os' $cfdir/$file > /dev/null") != 0) { next; } $cfmtime = ( stat "$cfdir/$file" ) [9]; $cfsize = ( stat "$cfdir/$file" ) [7]; $cfctime = ( stat "$cfdir/$file" ) [10]; $cfctime_fmt = &timeToText("$cfctime"); $flag = "*Hit*" if $cfctime > $arg2 && $arg2; $age = time - $cfmtime; $oldest = $age if $age > $oldest; printf "%-54s %10s %19s %9s %9s %-5s\n","$cfdir/$file",$cfctime,$cfctime_fmt,$age,$cfsize,$flag; $numlogs++; } print "\n"; &msg("Found $numlogs backups"); } #------------------------------------------------------------------------------ # # Main # #------------------------------------------------------------------------------ $arg = $ARGV[0]; $arg2 = $ARGV[1]; $arg3 = $ARGV[2]; $arg4 = $ARGV[3]; #$arg5 = $ARGV[4]; $P = "orastat"; chop($PBASE = `basename $0`); chop($toolsdir = `dirname $0`); $| = 1; $oh = $ENV{"ORACLE_HOME"}; $os = $ENV{"ORACLE_SID"}; chop($srvinfo = `uname -a`); $dist_pgmr = qw(bill.border@hp.com); chop($host = `hostname`); $savedir = ""; if (-e "/opt/oracle/adm/cronlog") { $savedir = "/opt/oracle/adm/cronlog"; } elsif (-e "/opt/oracle/admin/tools/logs") { $savedir = "/opt/oracle/admin/tools/logs"; } ##&error("Cannot find log dir") if ! $savedir; $ENV{"ENV"} = ""; $ENV{"UNIX95"} = 1; $ENV{"PATH"} = "$ENV{'PATH'}:/usr/sbin"; # To find nslookup if ($oh eq "" || $os eq "") { print "orastat | Env vars ORACLE_HOME and ORACLE_SID must be set\n"; exit 1; } #---- Validate user/group @z = getgrgid($)); $gname = $z[0]; chop($uname = `whoami`); if ($gname ne "dba" && $uname ne "oracle") { $homedir = (getpwuid($<))[7]; $connect_file = "$homedir/.orastat_connect.txt"; &msg("Effective user/group $uname/$gname Is not user=oracle or group=dba - Looking for orastat connect file: $connect_file"); &msg("The connect file must contain 1 line with SQLPlus 'connect' syntax. Example: connect dbuserid/dbpw"); &msg("This DB userid specified in the connect string must have the 'select any dictionary' system privilege."); ##system("echo ' ' | mailx -s '$P - $host/$os Non oracle/dba user' $dist_pgmr"); #---- Look for homedir/.orastat_connect.txt &error("orastat Connect file ($connect_file) does not exist") if ! -e "$connect_file"; #---- connect_file Does exist - check permission chop($cf_perm = `ll $connect_file | awk '{ print \$1 }'`); if ($cf_perm ne "-rw-------") { &msg("------------------------ Error -------------------------"); &msg("orastat Connect file ($connect_file) has incorrect file permissions ($cf_perm)"); &msg("File must be: you-writable, group-inaccessible and others-inaccessible (500)"); &msg("To correct: chmod 600 $connect_file"); &error("Exiting"); } &msg("Connect file exists and permissions are OK - Reading file contents"); foreach (`cat $connect_file | grep -v ^#`) { @words = split; if (uc $words[0] ne "CONNECT" || $#words > 1) { &error("The connect file can only contain non-comment lines with format: connect user/pw"); } chop($cf_connect_string = $_); } ##&msg("DEBUG cf_connect_string=$cf_connect_string"); &msg("NOTE: Although you can connect to the DB, files that are only accessible by the oracle OS ID or dba OS Group will still be inaccessible"); ##system("echo ' ' | mailx -s '$P - $host/$os Non oracle/dba user - CF Found and read' $dist_pgmr"); ##exit; } #---- Get company name if ($srvinfo =~ /^Linux/) { $compwork = `nslookup -sil $host | grep 'Name:' | awk '{ print \$2 }'`; } else { $compwork = `nslookup $host | grep 'Name:' | awk '{ print \$2 }'`; } chop $compwork; @words = split(/\./,$compwork); $nexttolast = $#words - 1; $company = $words[$nexttolast]; #$basetime = 1001607400; #$nowtime = time; #@banner = `$oh/bin/sqlplus -?`; ### Old Method @banner = `echo exit | $oh/bin/sqlplus /NOLOG`; foreach $line (@banner) { if ($line =~ /SQL/) { @words = split(' ',$line); $oraver = substr(${words[2]},0,5); $oraver_short = $words[2]; #---- Chop the last 4 chars off (8.1.7.4.0 -> 8.1.7) $oraver_short =~ s/......$//g; $oraver_num = $oraver_short + 0; last; } } if (substr($oraver,0,2) eq "3.") { $_ = $oraver; s/3/7/; $oraver = $_; } #if (substr($oraver,0,2) lt "7.") #{ # $oraver = ""; #} if ($oraver_num >= 8.1) { $sqlcmd = "sp"; $os_scmd = "sqlplus /NOLOG"; $os_conn = "connect / as sysdba "; } else { $sqlcmd = "sv"; $os_scmd = "svrmgrl"; $os_conn = "connect internal "; } #---- Possible override $os_conn = $cf_connect_string if $cf_connect_string; &msg("oraver=$oraver oraver_short=$oraver_short oraver_num=$oraver_num sqlcmd=$sqlcmd arg=$arg arg2=$arg2"); if ($srvinfo =~ /^Sun/) { $bdfcmd = "df -k"; } elsif ($srvinfo =~ /^HP-UX/) { $bdfcmd = "bdf"; } else { $bdfcmd = "df -kP"; } chop($date = `date +%Y/%m/%d-%H:%M:%S`); print "$date $P | ORACLE_SID=$os ORACLE_HOME=$oh - $srvinfo \n"; print "$date $P | Version=$version Host=$host Company=$company\n"; ##print "$date $P | pid=$$\n"; # See if it was invoked for usage if (!$arg || $arg eq "\-\?") { goto USAGE; } # See if this command is a subroutine $subname = substr($arg,1); $evalcmd = "\&run_$subname"; ##print "evalcmd=$evalcmd\n"; eval "$evalcmd" ; ##print "at=$@\n"; if ($@ eq "") { exit; } # -------------------------------------------------------------------- # - # -------------------------------------------------------------------- if ($arg eq "-") { &msg("- Instance Status (Primarily from v\$database)"); #---- Old way - doesn't work on AIX # $numpmon = `ps -ef | grep 'ora_pmon_$os\$' | grep -v grep | grep -v '^\$' | wc -l`; #---- New way - don't care if you don't match on EOL # $numpmon = `ps -ef | grep 'ora_pmon_$os' | grep -v grep | grep -v '^\$' | wc -l`; #---- New logic for ASM if ($os =~ /^\+ASM/) { $numpmon = `ps -ef | grep 'asm_pmon_$os' | grep -v grep | grep -v '^\$' | wc -l`; &msg("This is an ASM instance - DB status of STARTED is normal"); } else { $numpmon = `ps -ef | grep 'ora_pmon_$os' | grep -v grep | grep -v '^\$' | wc -l`; } # Clean up numpmon chomp ($numpmon); $numpmon =~ s/ //g; if ($numpmon < 1) { &msg("UX Process [ora/asm]_pmon_$os is Not Running (numpmon=$numpmon)"); exit 1; } $shu = "?"; $sta = "?"; $ver = "?"; $sts = "?"; $ins = "?"; $par = "?"; $log = "?"; $cha = "?"; $scn = "?"; $asc = "?"; $cfm = "?"; $dbid = "?"; $dbnm = "?"; # Determine Oracle version $sqlstmt = 'select \'V\', banner from v\$version;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @lines = split("\n"); @words = split; $verb = $words[0]; if ($verb eq "ORA-01034:") { $sta = "(Oracle Not Available)"; } elsif ($verb =~ "ORA-01012") { print ""; } elsif ($verb =~ "ORA-") { print "\nERROR: ${lines[0]}\n\n"; } if ($verb eq "V") { if (/10g/) { $ver = $words[7]; if ($_ =~ /64b/) { $ver = $ver . " (64-bit)"; } } if (/11g/) { $ver = $words[7]; if ($_ =~ /64b/) { $ver = $ver . " (64-bit)"; } } if (substr($words[1],0,7) eq "Oracle8") { $ver = $words[5]; $z = substr($ver,length($ver)-1,1); if ($z eq "," || $_ =~ /64bit/) { chop($ver) if $z eq ","; $ver = $ver . " (64-bit)"; } } if (substr($words[1],0,7) eq "Oracle9") { $ver = $words[5]; $z = substr($ver,length($ver)-1,1); if ($z eq "," || $_ =~ /64bit/) { chop($ver) if $z eq ","; $ver = $ver . " (64-bit)"; } } elsif (substr($words[1],0,7) eq "Oracle8" && $words[5] eq "Production") { $ver = $words[3]; } elsif (substr($words[1],0,7) eq "Oracle7") { $ver = $words[4]; } } } if (substr($ver,0,1) eq "7") { $sqlstmt = 'select \'X\', name, checkpoint_change#, archive_change# from v\$database; select \'A\', value from v\$instance where key = \'RESTRICTED MODE\'; select \'B\', value from v\$instance where key = \'SHUTDOWN PENDING\'; select \'Z\', value from v\$nls_parameters where parameter = \'NLS_CHARACTERSET\'; select \'C\', to_char(to_date(value,\'J\'),\'YYYY/MM/DD\'), sysdate - to_date(value,\'J\') from v\$instance where key = \'STARTUP TIME - JULIAN\';'; } elsif ($ver =~ /^8.0/) { $sqlstmt = 'select \'X\', instance_name, to_char(startup_time,\'YYYY/MM/DD-HH24:MI:SS\') startup_time, version, status, shutdown_pending, nvl(parallel,\'?\'), logins, sysdate - startup_time from v\$instance; select \'W\', CHECKPOINT_CHANGE#, ARCHIVE_CHANGE#, CONTROLFILE_TYPE, dbid, name from v\$database; select \'Z\', value from v\$nls_parameters where parameter = \'NLS_CHARACTERSET\';'; } else { $sqlstmt = 'select \'X\', instance_name, to_char(startup_time,\'YYYY/MM/DD-HH24:MI:SS\') startup_time, version, status, shutdown_pending, nvl(parallel,\'?\'), logins, sysdate - startup_time, thread# from v\$instance; select \'J\', force_logging from v\$database; select \'V\', to_char(created,\'YYYY/MM/DD-HH24:MI:SS\'), log_mode from v\$database; select \'W\', CHECKPOINT_CHANGE#, ARCHIVE_CHANGE#, CONTROLFILE_TYPE, dbid, name, open_mode from v\$database; select \'Q\', database_role, flashback_on, translate(platform_name,\' \',\'_\') from v\$database; select \'Z\', value from v\$nls_parameters where parameter = \'NLS_CHARACTERSET\'; select \'ArcLogCnt\', count(*) from v\$archived_log where completion_time > (sysdate - 1/24) and name like \'/%\'; select \'RLID\', resetlogs_id from v\$database_incarnation where status = \'CURRENT\'; select \'Flag-ASM\', count(*) from v\$datafile where name like \'+%\'; select distinct \'Flag-InASM\', instance_name from v\$asm_client; '; } ##print "sqlstmt=$sqlstmt\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/ && $_ !~ /ORA-00904/ && $_ !~ /ORA-00942/; @words = split; $verb = $words[0]; if ($verb eq "ORA-01034:") { $sta = "(Oracle Not Available)"; } if ($verb eq "ArcLogCnt") { $arclog_cnt = $words[1]; } if ($verb eq "Flag-InASM") { $asm_instance = $words[1]; } if ($verb eq "Flag-ASM") { $asmcount = $words[1]; if ($asmcount > 0) { $asm_on = "YES"; } else { $asm_on = "NO"; } } if ($verb eq "J") { $forclog = $words[1]; } if ($verb eq "RLID") { $rlid = $words[1]; } if ($verb eq "V") { $created = $words[1]; $logmode = $words[2]; } if ($verb eq "Q") { $dbrole = $words[1]; $flashback = $words[2]; $dbplatform = $words[3]; } if ($verb eq "W") { $scn = $words[1]; $asc = $words[2]; $cfm = $words[3]; $dbid= $words[4]; $dbnm= $words[5]; $open= $words[6] . $words[7]; } if ($verb eq "X") { if (substr($ver,0,1) eq "7") { $ins = $words[1]; $scn = $words[2]; $asc = $words[3]; $dbid= $words[4]; $sta = "(PMON Running)"; } else { $ins = $words[1]; $sts = $words[2]; $sta = $words[4]; $shu = $words[5]; $par = $words[6]; $log = $words[7]; $upt = $words[8]; $upt = $upt * 24; $thread = $words[9]; } } if ($verb eq "A") { if ($words[1] eq "0") { $log = "ALLOWED"; } else { $log = "RESTRICTED"; } } if ($verb eq "B") { if ($words[1] eq "0") { $shu = "NO"; } else { $shu = "YES"; } } if ($verb eq "C") { $sts = $words[1]; $upt = $words[2]; if ($sta eq "?" && $upt ne "?") { $sta="NOMOUNT"; } elsif ($sta eq "(PMON Running)" && $upt ne "?") { $sta = "MOUNTED"; $sqlstmt = "select \'P\',user_id from dba_users;"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split; $verb = $words[0]; if ($verb =~ "ORA-") { print "$verb\n"; } if ($verb eq "P") { $sta = "OPEN"; } } } #$cur_time=`date +%H:%M:%S`; open(PS, "ps -ef -oetime,comm |grep ora_pmon|") || die "can't run ps - $!"; while() { ##print; @words = split; $etime = $words[0]; $comm = $words[1]; if ($comm eq "ora_pmon_$os") { @words = split ("-",$etime); $etime_0 = $words[0]; $etime_1 = $words[1]; if ($etime_1 eq "") { @words = split (":",$etime_0); if (${words[2]} eq "") { $hours = 0; $mins = $words[0]; $secs = $words[1]; $upt = $hours + ($mins/60) + ($secs/60/60); } elsif (${words[1]} eq "" && ${words[2]} eq "") { $hours = 0; $mins = 0; $secs = $words[0]; $upt = $hours + ($mins/60) + ($secs/60/60); } else { $hours = $words[0]; $mins = $words[1]; $secs = $words[2]; $upt = $hours + ($mins/60) + ($secs/60/60); } } else { $days = $etime_0; @words = split (":",$etime_1); $hours = $words[0]; $mins = $words[1]; $secs = $words[2]; $upt = ($days * 24) + $hours + ($mins/60) + ($secs/60/60); } } } close(PS); } if ($verb eq "Z") { $cha = $words[1]; } } #---- See if password function is on in DEFAULT profile #DEFAULT PASSWORD PASSWORD_VERIFY_FUNCTION VERIFY_FUNCTION chop($dbpw_work = `$PBASE -pr | grep '^DEFAULT' | grep 'PASSWORD_VERIFY_FUNCTION' | awk '{ print \$NF}'`); if ($dbpw_work eq "NULL") { $dbpw = "OFF"; } elsif ($dbpw_work =~ /\_/) { $dbpw = "ON"; } else { $dbpw = "?"; } if ($upt > 0) { $daysup = sprintf("%.2f",($upt / 24)); } print "orastat | Status: $sta\n"; print "orastat | OpenMode: $open\n" if $open ne ""; print "orastat | Started: $sts\n"; print "orastat | HoursUp: $upt\n"; print "orastat | DaysUp: $daysup\n"; print "orastat | Instance: $ins\n"; print "orastat | OracleVer: $ver\n"; print "orastat | ShutdownMode: $shu\n"; print "orastat | Parallel: $par\n"; print "orastat | Thread#: $thread\n" if $thread; print "orastat | Logins: $log\n"; print "orastat | Characterset: $cha\n"; print "orastat | CkptSCN: $scn\n"; print "orastat | ArcSCN: $asc\n"; print "orastat | CF Mode: $cfm\n"; print "orastat | DBID: $dbid\n"; print "orastat | DBName: $dbnm\n"; print "orastat | Created: $created\n" if $created; print "orastat | LogMode: $logmode\n" if $logmode; print "orastat | ForceLogging: $forclog\n" if $forclog; print "orastat | ResetlogsID: $rlid\n" if $rlid; print "orastat | DBRole: $dbrole\n" if $dbrole; print "orastat | FlashbackOn: $flashback\n" if $flashback; print "orastat | DBPlatform: $dbplatform\n" if $dbplatform; print "orastat | ComplexDBPW: $dbpw (Function: $dbpw_work)\n" if $dbpw; print "orastat | ASM: $asm_on\n" if $asm_on; print "orastat | ASMInstance: $asm_instance\n" if $asm_instance; print "orastat | ArcLogRate: $arclog_cnt (Local Arclogs Per Hour)\n" if $arclog_cnt ne ""; exit; } # -------------------------------------------------------------------- # -ht # -------------------------------------------------------------------- if ($arg eq "-ht") { $rows = 0; if ($arg2 ne "") { $touches_threshold = $arg2; } else { $touches_threshold = 1000; } &msg("-ht: Hot Tables - Having Block Touches > $touches_threshold"); $sqlstmt = " select \'Y\', name, value from v\\\$parameter where name in (\'db_block_size\'); SELECT \'X\', bh.obj, ob.owner, ob.object_name, ob.object_type, COUNT(2) buffers, sum(bh.tch) sum FROM x\\\$bh bh, dba_objects ob where bh.obj = ob.object_id GROUP BY bh.obj, ob.owner, ob.object_name, ob.object_type HAVING sum(tch) > $touches_threshold order by 7 desc;"; print "\n"; print "Name Type Buffers Size(MB) Touches\n"; print "---------------------------------------- ---------- ---------- ---------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift @words; if ($verb eq "Y") { $blocksize = $words[1]; ##print "blocksize=$blocksize\n"; next; } if ($verb eq "X") { $objid = ""; $objid = shift @words; $owner = shift @words; $obj = shift @words; $type = shift @words; $buffers = shift @words; $touches = shift @words; $objname = "$owner.$obj"; $objsize = int(($buffers * $blocksize) / 1000000); printf "%-40s %-10s %10s %10s %10s\n",$objname,$type,$buffers,$objsize,$touches; $rows++; } } print "\n"; &msg("$rows Row(s) found"); exit; } # -------------------------------------------------------------------- # -hd # -------------------------------------------------------------------- if ($arg eq "-hd") { $rows = 0; if ($arg2 ne "") { $touches_threshold = $arg2; } else { $touches_threshold = 1000; } &msg("-hd: Hot Tables - Having Block Touches > $touches_threshold"); $sqlstmt = " select \'Y\', name, value from v\\\$parameter where name in (\'db_block_size\'); SELECT \'X\', bh.obj, ob.owner, ob.object_name, ob.object_type, df.name, COUNT(2) buffers, sum(bh.tch) sum FROM x\\\$bh bh, dba_objects ob, v\\\$datafile df where bh.obj = ob.object_id and bh.file# = df.file# GROUP BY bh.obj, ob.owner, ob.object_name, ob.object_type, df.name HAVING sum(tch) > $touches_threshold order by 8 desc;"; print "\n"; print "Name Type Datafile Buffers Size(MB) Touches\n"; print "-------------------------------------------------- ---------- -------------------------------------------------- ---------- ---------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "Y") { $blocksize = $words[1]; ##print "blocksize=$blocksize\n"; next; } if ($verb eq "X") { $objid = ""; $objid = shift @words; $owner = shift @words; $obj = shift @words; $type = shift @words; $dfname = shift @words; $buffers = shift @words; $touches = shift @words; $objname = "$owner.$obj"; $objsize = int(($buffers * $blocksize) / 1000000); printf "%-50s %-10s %-50s %10s %10s %10s\n",$objname,$type,$dfname,$buffers,$objsize,$touches; $rows++; } } print "\n"; &msg("$rows Row(s) found"); exit; } # -------------------------------------------------------------------- # -nf # -------------------------------------------------------------------- if ($arg eq "-nf") { # # Look for tables where the next extent will not fit in the largest # freespace hole for their tablespace # &msg("Looking for tables whose next extent will not fit"); $sqlstmt = ' select \'X\', segment_owner, segment_name, segment_type, ts1, max_chunk, chunk_needed from (select tablespace_name ts1, max(bytes) as max_chunk from dba_free_space group by tablespace_name), (select owner segment_owner, segment_name, segment_type, tablespace_name ts2, next_extent chunk_needed from dba_segments) where ts1=ts2 and chunk_needed> max_chunk; order by 2,3 '; &oraSQL($sqlstmt); $foundtbls = 0; $titleflag = 0; foreach (@oraSQLout) { ##print; @words = split; $verb = $words[0]; if ($verb eq "X") { $owner = $words[1]; $sname = $words[2]; $stype = $words[3]; $ts = $words[4]; $ts_max_free = $words[5]; $s_next_size = $words[6]; $foundtbls++; $tbl = $owner . "." . $sname; if (!$titleflag) { print "\n"; print " Object(s) Whose Next_Extent Will Not Fit\n"; print "\n"; print "Segment Segment Tablespace Object Next TS Max Contig.\n"; print "Name Type Name Extent Size Free Space\n"; print "---------------------------------------- ------- -------------------- --------------- ---------------\n"; $titleflag = 1; } printf "%-40s %-7s %-20s %15i %15i\n",$tbl,$stype,$ts,$s_next_size,$ts_max_free; ##$newnext = int ( $ts_max_free / 1000000 ); ##$newnext-- if $newnext > 2; $newnext = $ts_max_free - 1024; $newnext = 1024 if $newnext <= 0; $ddl .= "ALTER $stype $tbl STORAGE ( NEXT ${newnext} PCTINCREASE 0 );\n"; } } print "\n"; if ($foundtbls == 0) { &msg("No objects found whose NEXT EXTENT will not fit"); } else { &msg("Found $foundtbls object(s) whose NEXT EXTENT will not fit"); &msg("DDL to correct:\n"); print "$ddl \n"; } exit; } # -------------------------------------------------------------------- sub run_rg # -------------------------------------------------------------------- { &msg("-rg: Contents of DBA_REGISTRY - DB Component Status"); $sqlstmt = " SELECT 'X', nvl(version,\'?\'), nvl(status,\'?\'), comp_name FROM dba_registry; order by 1, 3 "; print "\n"; print "DB Component Version Status\n"; print "---------------------------------------- ------------ ------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $rg_component = ""; $rg_version = shift @words; $rg_status = shift @words; foreach (@words) { $rg_component .= "$_ "; } printf "%-40s %-12s %-12s\n",$rg_component,$rg_version,$rg_status; } } exit; } # -------------------------------------------------------------------- sub run_mt # -------------------------------------------------------------------- { &msg("-mt: MTS Overview"); $sqlstmt = ' SELECT \'X\', type, paddr, queued, decode(totalq,0,0,wait / totalq) avg_wait FROM v\$queue; order by 2, 3 '; print "\n"; &msg("MTS Statistics"); print "\n"; print "Queue PAddr Ses Q'd Avg Wait\n"; print "------------ ---------------- -------- --------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $mt_ptype = shift @words; $mt_paddr = shift @words; $mt_queued = shift @words; $mt_avgwait = sprintf("%.2f",shift @words); $mt_paddr = "" if $mt_paddr eq "00"; printf "%-12s %-16s %8s %8s\n",$mt_ptype, $mt_paddr, $mt_queued, $mt_avgwait; } } $sqlstmt = ' SELECT \'X\', d.name, s.username, c.status, c.queue, s.sid, s.serial# from v\$circuit c, v\$dispatcher d, v\$session s where c.dispatcher = d.paddr and c.saddr = s.saddr order by d.name, s.username; '; print "\n"; &msg("Connected MTS Users"); print "\n"; print "Disp User Session# Serial# Status Queue\n"; print "-------- ---------------- -------- -------- ------------ -----------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $mt_dname = shift @words; $mt_user = shift @words; $mt_status = shift @words; $mt_queue = shift @words; $mt_sid = shift @words; $mt_ser = shift @words; printf "%-8s %-16s %8s %8s %-12s %-12s\n",$mt_dname, $mt_user, $mt_sid, $mt_ser, $mt_status, $mt_queue; } } $sqlstmt = ' SELECT \'X\', name, busy / (busy + idle) * 100 from v\$shared_server order by 2; '; print "\n"; &msg("Shared Server Process Utilization"); print "\n"; print "Server Busy\n"; print "-------- --------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $mt_sname = shift @words; $mt_busy = sprintf("%.2f",shift @words); printf "%-8s %8s%%\n",$mt_sname, $mt_busy; } } $sqlstmt = ' SELECT \'X\', name, busy / (busy + idle) * 100 from v\$dispatcher order by 2; '; print "\n"; &msg("Dispatcher Process Utilization"); print "\n"; print "Server Busy\n"; print "-------- --------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $mt_sname = shift @words; $mt_busy = sprintf("%.2f",shift @words); printf "%-8s %8s%%\n",$mt_sname, $mt_busy; } } exit; } # -------------------------------------------------------------------- sub run_zr # -------------------------------------------------------------------- { &msg("-zr: Contents of DBA_REGISTRY - DB Component Status"); $sqlstmt = " SELECT 'X', ts, prihost, prisid, sbyhost, sbysid, tool FROM dbamon.standby_rebuild order by 1, 2, 3; "; print "\n"; print "DB Component Version Status\n"; print "---------------------------------------- ------------ ------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $ts = shift @words; $prihost = shift @words; $prisid = shift @words; $sbyhost = shift @words; $sbysid = shift @words; $tool = shift @words; printf "%s %-12s %-12s %-12s %-12s %s\n",$ts, $prihost, $prisid, $sbyhost, $sbysid, $tool; } } } # -------------------------------------------------------------------- sub run_bo # -------------------------------------------------------------------- { &msg("-bo: Buffer Cache Overview (From v\$bh) - Note that this command will run for awhile (arg2=$arg2)"); #---- #1 get blocksize $sqlstmt = 'select \'X\', value from v\$parameter where name = \'db_block_size\';'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $db_block_size = shift @words; } } #---- #2 get blocksize $sqlstmt = 'select \'X\', count(*) from v\$bh;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $buffer_total_size = shift @words; } } ##print "bts=$buffer_total_size\n"; #---- #1 group by status $sqlstmt = " SELECT 'X', status, count(*) FROM v\\\$bh group by 'X', status order by 3 desc; "; print "\n"; &msg("-bo: Block Status"); print "\n"; print "Block Status Block Count Size (mB) % of Total\n"; print "--------------- --------------- --------------- ---------------\n"; &oraSQL($sqlstmt); $total_count = 0; foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $bh_status = shift @words; $bh_count = shift @words; $bh_mb = ($db_block_size * $bh_count) / 1000000; $bh_pct = ($bh_count / $buffer_total_size) * 100 if $buffer_total_size > 0; printf "%-15s %15s %15.2f %15.2f%%\n","Status=$bh_status",$bh_count,$bh_mb,$bh_pct; $total_count += $bh_count; } } print "=============== =============== ===============\n"; $total_mb = ($db_block_size * $total_count) / 1000000; printf "%-15s %15s %15.2f\n","Total:",$total_count, $total_mb; return if $arg2 eq "1"; #---- #2 group by dirty $sqlstmt = " SELECT 'X', dirty, count(*) FROM v\\\$bh group by 'X', dirty order by 3 desc; "; print "\n"; &msg("-bo: Dirty Blocks"); print "\n"; print "Buffer Dirty Block Count Size (mB) % of Total\n"; print "--------------- --------------- --------------- ---------------\n"; &oraSQL($sqlstmt); $total_count = 0; foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $bh_status = shift @words; $bh_count = shift @words; $bh_mb = ($db_block_size * $bh_count) / 1000000; $bh_pct = ($bh_count / $buffer_total_size) * 100 if $buffer_total_size > 0; printf "%-15s %15s %15.2f %15.2f%%\n","Dirty=$bh_status",$bh_count,$bh_mb,$bh_pct; $total_count += $bh_count; } } print "=============== =============== ===============\n"; $total_mb = ($db_block_size * $total_count) / 1000000; printf "%-15s %15s %15.2f\n","Total:",$total_count, $total_mb; #---- #3 group by temp $sqlstmt = " SELECT 'X', temp, count(*) FROM v\\\$bh group by 'X', temp order by 3 desc; "; print "\n"; &msg("-bo: Temp Blocks"); print "\n"; print "Buffer TEMP Block Count Size (mB) % of Total\n"; print "--------------- --------------- --------------- ---------------\n"; &oraSQL($sqlstmt); $total_count = 0; foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $bh_status = shift @words; $bh_count = shift @words; $bh_mb = ($db_block_size * $bh_count) / 1000000; $bh_pct = ($bh_count / $buffer_total_size) * 100 if $buffer_total_size > 0; printf "%-15s %15s %15.2f %15.2f%%\n","Temp=$bh_status",$bh_count,$bh_mb,$bh_pct; $total_count += $bh_count; } } print "=============== =============== ===============\n"; $total_mb = ($db_block_size * $total_count) / 1000000; printf "%-15s %15s %15.2f\n","Total:",$total_count, $total_mb; #---- #4 group by TS $sqlstmt = " SELECT 'X', ts.name, count(*) FROM v\\\$bh bh, v\\\$tablespace ts where bh.ts# = ts.ts# group by 'X', ts.name order by 3 desc; "; print "\n"; &msg("-bo: Blocks By Tablespace - Top 10"); print "\n"; print "Tablespace Block Count Size (mB) % of Total\n"; print "--------------- --------------- --------------- ---------------\n"; &oraSQL($sqlstmt); $total_count = 0; $rows = 0; foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $bh_ts = shift @words; $bh_count = shift @words; $bh_mb = ($db_block_size * $bh_count) / 1000000; $bh_pct = ($bh_count / $buffer_total_size) * 100 if $buffer_total_size > 0; printf "%-15s %15s %15.2f %15.2f%%\n",$bh_ts,$bh_count,$bh_mb,$bh_pct; $total_count += $bh_count; last if $rows >= 10; } } print "=============== =============== ===============\n"; $total_mb = ($db_block_size * $total_count) / 1000000; printf "%-15s %15s %15.2f\n","Total:",$total_count, $total_mb; #---- #5 group by DF $sqlstmt = " SELECT 'X', df.name, count(*) FROM v\\\$bh bh, v\\\$datafile df where bh.file# = df.file# group by 'X', df.name order by 3 desc; "; print "\n"; &msg("-bo: Blocks By Datafile - Top 10"); print "\n"; print "Datafile Block Count Size (mB) % of Total\n"; print "------------------------------------------------------- --------------- --------------- ---------------\n"; &oraSQL($sqlstmt); $total_count = 0; $rows = 0; foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $bh_df = shift @words; $bh_count = shift @words; $bh_mb = ($db_block_size * $bh_count) / 1000000; $bh_pct = ($bh_count / $buffer_total_size) * 100 if $buffer_total_size > 0; printf "%-55s %15s %15.2f %15.2f%%\n",$bh_df,$bh_count,$bh_mb,$bh_pct; $total_count += $bh_count; last if $rows >= 10; } } print "======================================================= =============== ===============\n"; $total_mb = ($db_block_size * $total_count) / 1000000; printf "%-55s %15s %15.2f\n","Total:",$total_count, $total_mb; #---- #6 group by object $sqlstmt = " SELECT 'X', ob.owner, ob.object_name, translate(ob.object_type,\' \',\'_\'), count(*) FROM v\\\$bh bh, dba_objects ob where bh.objd = ob.object_id group by 'X', ob.owner, ob.object_name, ob.object_type order by 5 desc; "; print "\n"; &msg("-bo: Blocks By Object - Top 25"); print "\n"; print "Object Block Count Size (mB) % of Total\n"; print "------------------------------------------------------- --------------- --------------- ---------------\n"; &oraSQL($sqlstmt); $total_count = 0; $rows = 0; foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $rows++; $bh_owner = shift @words; $bh_name = shift @words; $bh_type = shift @words; $bh_count = shift @words; $this_object = "$bh_owner.$bh_name ($bh_type)"; $bh_mb = ($db_block_size * $bh_count) / 1000000; $bh_pct = ($bh_count / $buffer_total_size) * 100 if $buffer_total_size > 0; printf "%-55s %15s %15.2f %15.2f%%\n",$this_object,$bh_count,$bh_mb,$bh_pct; $total_count += $bh_count; last if $rows >= 25; } } print "======================================================= =============== ===============\n"; $total_mb = ($db_block_size * $total_count) / 1000000; printf "%-55s %15s %15.2f\n","Total:",$total_count, $total_mb; exit; } # -------------------------------------------------------------------- sub run_rf # -------------------------------------------------------------------- { &msg("-rf: Contents of V\$RECOVER_FILE - DB Recovery Required Start Time"); &msg("Querying V\$RECOVER_FILE"); $rows = 0; $min_time_c = "?"; $min_time_n = "?"; $sqlstmt = " SELECT \'X\', min(to_char(time,'YYYY/MM/DD-HH24:MI:SS')) FROM v\\\$recover_file; "; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $min_time_c = shift @words; $min_time_n = &timeToNum($min_time_c); $rows++; } } &msg("Minimum TIME Value From V\$RECOVER_FILE (Character): $min_time_c"); &msg("Minimum TIME Value From V\$RECOVER_FILE (Numeric): $min_time_n"); exit; } # -------------------------------------------------------------------- # -sy # -------------------------------------------------------------------- if ($arg eq "-sy") { &msg("-sy: All Granted System Privileges"); $rows = 0; $sqlstmt = " SELECT \'X\', grantee, translate(privilege,\' \',\'_\'), admin_option FROM dba_sys_privs order by 2, 3;"; print "\n"; print "Grantee System Privilege Adm\n"; print "------------------------ ---------------------------------------- ---\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $grantee = shift @words; $priv = shift @words; $adm = shift @words; printf "%-24s %-40s %-3s\n",$grantee,$priv,$adm; $rows++; } } print "\n"; &msg("$rows Rows found"); exit; } # -------------------------------------------------------------------- # -dd # -------------------------------------------------------------------- if ($arg eq "-dd") { &msg("-dd: Create DDL - Object=$arg3.$arg4 Type=$arg2"); if ($oraver_num >= 9) { &msg("orastat -dd Will only work with Oracle 9i"); exit; } $arg2_uc = uc $arg2; $arg3_uc = uc $arg3; $arg4_uc = uc $arg4; $rows = 0; print "\n"; $sqlstmt = " SELECT \'X\', dbms_metadata.get_ddl ('$arg2_uc','$arg4_uc','$arg3_uc') FROM dual;"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; print if $printflag && /^ /; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $printflag = 1; $rows++; } } print "\n"; &msg("Object $arg3.$arg4 type=$arg2 Not Found") if !$rows; exit; } # -------------------------------------------------------------------- # -du # -------------------------------------------------------------------- if ($arg eq "-du") { &msg("-du: Datafile With Unrecoverable Changes"); $rows = 0; $sqlstmt = " SELECT \'X\', df.name, df.unrecoverable_change#, to_char(unrecoverable_time,\'YYYY/MM/DD-HH24:MI:SS\') FROM v\\\$datafile df where df.unrecoverable_change# > 0 order by 2;"; print "\n"; print "Name Unrec. Change# Unrec. Date\n"; print "-------------------------------------------------- --------------- -------------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $objid = ""; $dfname = shift @words; $chgnum = shift @words; $chgdat = shift @words; printf "%-50s %-15s %-19s\n",$dfname,$chgnum,$chgdat; $rows++; $maxdat = $chgdat if $chgdat gt $maxdat; } } print "\n"; &msg("$rows Datafile(s) with unrecoverable changes found"); &msg("Most recent UNRECOVERABLE_TIME value found: $maxdat"); exit; } # -------------------------------------------------------------------- # -cb # -------------------------------------------------------------------- if ($arg eq "-cb") { &msg("-cb: Controlfile Backup"); if (-w "/var/opt/oracle/tmp/") { $cb_binary = "/var/opt/oracle/tmp/orastat_cfbinary_${os}_${$}.dbf"; ##system("rm -f /var/opt/oracle/tmp/orastat_cfbinary_${os}_*.dbf 2>/dev/null"); } else { $cb_binary = "/tmp/orastat_cfbinary_${os}_${$}.dbf"; ##system("rm -f /tmp/orastat_cfbinary_${os}_*.dbf 2>/dev/null"); } &msg("Binary CF backup filename cb_binary=$cb_binary"); $sqlstmt = " SELECT \'X\', spid FROM v\\\$process a, v\\\$session b WHERE a.addr=b.paddr AND b.sid = (select min(sid) from v\\\$mystat) ; alter system checkpoint; alter database backup controlfile to trace; alter database backup controlfile to \'$cb_binary\'; select \'Z\', value from v\\\$parameter where name = \'user_dump_dest\'; "; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $spid = shift @words; } if ($verb eq "Z") { $udd = shift @words; } } $lcos = lc $os; $bug_cb_trace = "$oh/rdbms/log/ora_${spid}.trc"; $bug2_cb_trace = "$oh/rdbms/log/${lcos}_ora_${spid}.trc"; # See if we are running 9i chop($oraver = `orastat - | grep OracleVer | awk '{ print \$4 }'`); if ($srvinfo =~ /^Sun/) { $cb_trace = "$udd/${lcos}_ora_${spid}.trc"; } elsif ($srvinfo =~ /^Linux/ && $oraver =~ /^8/) { $cb_trace = "$udd/ora_${spid}.trc"; } elsif ($srvinfo =~ /^Linux/ && $oraver =~ /^9/) { $cb_trace = "$udd/${lcos}_ora_${spid}.trc"; } elsif ($oraver =~ /^9.0.1/) { $cb_trace = "$udd/ora_${spid}_${lcos}.trc"; } elsif ($oraver =~ /^9/) { $cb_trace = "$udd/${lcos}_ora_${spid}.trc"; } elsif ($oraver =~ /^11/) { $cb_trace = "$udd/${os}_ora_${spid}.trc"; } elsif ($oraver =~ /^1/) { $cb_trace = "$udd/${lcos}_ora_${spid}.trc"; } elsif ($oraver =~ /^8.1.5/) { $cb_trace = "$udd/ora_${spid}.trc"; } elsif ($oraver =~ /^8.1/) { $cb_trace = "$udd/ora_${spid}_$lcos.trc"; } else { $cb_trace = "$udd/ora_${spid}.trc"; } ##&msg("spid=$spid udd=$udd cb_trace=$cb_trace"); print "\n"; if (-e $cb_trace) { print "Controlfile_Trace_Backup was successful to: $cb_trace\n"; system("ls -l $cb_trace 2>&1"); } elsif (-e $bug_cb_trace) { $cb_trace = $bug_cb_trace; &msg("ORACLE Bug Encountered - Trace file written to rdbms/log"); print "Controlfile_Trace_Backup was successful to: $cb_trace\n"; system("ls -l $cb_trace 2>&1"); } elsif (-e $bug2_cb_trace) { $cb_trace = $bug2_cb_trace; &msg("ORACLE Bug Encountered - Trace file written to rdbms/log"); print "Controlfile_Trace_Backup was successful to: $cb_trace\n"; system("ls -l $cb_trace 2>&1"); } else { &msg("ERROR: I could not find the trace backup file - cb_trace=$cb_trace"); system("echo ' ' | mailx -s '$P - $host/$os Could not find trace CF backup' EMAIL_DUMMY "); } print "\n"; if (-e $cb_binary) { print "Controlfile_Binary_Backup was successful to: $cb_binary\n"; system("ls -l $cb_binary 2>&1"); } else { &msg("ERROR: I could not find the binary backup file: $cb_binary"); system("echo ' ' | mailx -s '$P - $host/$os Could not find binary CF backup' EMAIL_DUMMY "); } &msg("Done"); exit; } # -------------------------------------------------------------------- # -un # -------------------------------------------------------------------- if ($arg eq "-un") { $rows = 0; &msg("-un: UNDO Statistics"); $sqlstmt = ' SELECT \'X\', to_char(begin_time,\'YYYY/MM/DD-HH24:MI:SS\') , to_char(end_time,\'YYYY/MM/DD-HH24:MI:SS\') , undotsn, undoblks, txncount, maxconcurrency, ssolderrcnt, nospaceerrcnt, tuned_undoretention FROM v\$undostat where begin_time >= sysdate - 1 order by 2, 4;'; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "Start End Blks Trans. Max. Conc. SS Old No Spc Tuned Undo\n"; print "Time Time TS# Used Count Trans. Errors Errors Retention\n"; print "------------------- ------------------- --- ---------- ---------- ---------- ---------- ---------- ----------\n"; $spaceflag = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $begin_time = shift @words; $end_time = shift @words; $undotsn = shift @words; $undoblks = shift @words; $txncount = shift @words; $maxcon = shift @words; $ssolerr = shift @words; $nospaceerr = shift @words; $undoret = shift @words; ##print "sf=$spaceflag\n"; $spaceflag = 1 if $nospaceerr gt "0"; printf "%19s %19s %3s %10s %10s %10s %10s %10s %10s \n", $begin_time , $end_time , $undotsn , $undoblks , $txncount , $maxcon , $ssolerr , $nospaceerr , $undoret; $rows++; $total += $count; } } print "\n"; if ($spaceflag == 1) { &msg("Since there were >=1 'SPACE ERROR' events, you need to add space to the UNDO TS"); } else { &msg("Since there were no 'SPACE ERROR' events, you do not need to add space to the UNDO TS"); } exit; } # -------------------------------------------------------------------- # -unl # -------------------------------------------------------------------- if ($arg eq "-unl") { $rows = 0; $onegig = 1024*1024*1024; #SQL> desc v$undostat # Name Null? Type # ----------------------------------------- -------- ---------------------------- # BEGIN_TIME DATE # END_TIME DATE # UNDOTSN NUMBER # UNDOBLKS NUMBER # TXNCOUNT NUMBER # MAXQUERYLEN NUMBER # MAXQUERYID VARCHAR2(13) # MAXCONCURRENCY NUMBER # - UNXPSTEALCNT NUMBER # - UNXPBLKRELCNT NUMBER # - UNXPBLKREUCNT NUMBER # - EXPSTEALCNT NUMBER # - EXPBLKRELCNT NUMBER # - EXPBLKREUCNT NUMBER # SSOLDERRCNT NUMBER # NOSPACEERRCNT NUMBER # ACTIVEBLKS NUMBER # UNEXPIREDBLKS NUMBER # EXPIREDBLKS NUMBER # TUNED_UNDORETENTION NUMBER &msg("-un: UNDO Statistics (Long)"); $sqlstmt = ' select \'Y\', value from v\$parameter where name in (\'db_block_size\'); SELECT \'X\', to_char(begin_time,\'YYYY/MM/DD-HH24:MI:SS\') , to_char(end_time,\'YYYY/MM/DD-HH24:MI:SS\') , undotsn, undoblks, txncount, maxconcurrency, ssolderrcnt, nospaceerrcnt, tuned_undoretention, maxquerylen, nvl(maxqueryid,\'?\'), nvl(activeblks, -1), nvl(expiredblks,-1), nvl(unexpiredblks,-1), nvl(EXPSTEALCNT, -1) , nvl(EXPBLKRELCNT, -1), nvl(EXPBLKREUCNT, -1), nvl(UNXPSTEALCNT, -1) , nvl(UNXPBLKRELCNT, -1), nvl(UNXPBLKREUCNT, -1) FROM v\$undostat where begin_time >= sysdate - 1 order by 2, 4;'; ##print "sqlstmt=$sqlstmt\n"; $spaceflag = 0; $c = 9999; $mr_nonzero_ts = "(None)"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; print if /^ORA/; @words = split(); $verb = shift @words; if ($verb eq "Y") { $block_size = shift @words; ## &msg("block_size=$block_size"); } if ($verb eq "X") { $begin_time = shift @words; $end_time = shift @words; $undotsn = shift @words; $undoblks = shift @words; $txncount = shift @words; $maxcon = shift @words; $ssolerr = shift @words; $nospaceerr = shift @words; $undoret = shift @words; $maxquerylen = shift @words; $maxqueryid = shift @words; $activeblks = shift @words; $expblks = shift @words; $unexpblks = shift @words; $expstealcnt = shift @words; $expblkrelcnt = shift @words; $expblkreucnt = shift @words; $unexpstealcnt = shift @words; $unexpblkrelcnt = shift @words; $unexpblkreucnt = shift @words; ##print "sf=$spaceflag\n"; $endts = substr($end_time,11,8); $maxqlenhrs = $maxquerylen / 3600; $spaceflag = 1 if $nospaceerr gt "0"; $activeblks_gb = ($activeblks * $block_size) / $onegig; $expblks_gb = ($expblks * $block_size) / $onegig; $unexpblks_gb = ($unexpblks * $block_size) / $onegig; $undoblks_gb = ($undoblks * $block_size) / $onegig; $undoret_hrs = $undoret / 3600; if ( $expstealcnt > 0 || $expblkrelcnt > 0 || $expblkreucnt > 0 || $unexpstealcnt > 0 || $unexpblkrelcnt > 0 || $unexpblkreucnt > 0) { $mr_nonzero_ts = $begin_time; } if (++$c >= 28) { print "\n"; print "UNDOSTAT UNDOSTAT +------------Undo (GB)------------+ Total Max Tuned +------MaxQuery----+ +-Expired Stealing-+ +-UnExp. Stealing--+\n"; print "Start End Total Total Total Consumed Trans. Conc +-Errors--+ Undo Length Attmpt Blocks Blocks Attmpt Blocks Blocks\n"; print "TS Time TS# Active Expired UnExp. ThisSamp Count Tran SSold NoSpc Ret Hrs. Hours SQLID Count Stolen Reused Count Stolen Reused\n"; print "------------------- -------- --- -------- -------- -------- -------- -------- ---- ----- ----- -------- ------ ------------- ------ ------ ------ ------ ------ ------\n"; $c = 0; } printf "%19s %8s %3s %8.2f %8.2f %8.2f %8.2f %8s %4s %5s %5s %8.2f %6.2f %-13s %6s %6s %6s %6s %6s %6s\n", $begin_time , $endts , $undotsn , $activeblks_gb , $expblks_gb, $unexpblks_gb, $undoblks_gb , $txncount , $maxcon , $ssolerr , $nospaceerr , $undoret_hrs, $maxqlenhrs, $maxqueryid, $expstealcnt, $expblkrelcnt, $expblkreucnt, $unexpstealcnt, $unexpblkrelcnt, $unexpblkreucnt ; $rows++; $total += $count; } } print "\n"; &msg("Most recent sample with non-zero value for any of the rightmost 6 'steal' columns: $mr_nonzero_ts"); exit; } # BEGIN_TIME DATE # END_TIME DATE # UNDOTSN NUMBER # UNDOBLKS NUMBER # TXNCOUNT NUMBER # MAXQUERYLEN NUMBER # MAXQUERYID VARCHAR2(13) # MAXCONCURRENCY NUMBER # UNXPSTEALCNT NUMBER # UNXPBLKRELCNT NUMBER # UNXPBLKREUCNT NUMBER # EXPSTEALCNT NUMBER # EXPBLKRELCNT NUMBER # EXPBLKREUCNT NUMBER # SSOLDERRCNT NUMBER # NOSPACEERRCNT NUMBER # ACTIVEBLKS NUMBER # UNEXPIREDBLKS NUMBER # EXPIREDBLKS NUMBER # TUNED_UNDORETENTION NUMBER # -------------------------------------------------------------------- # -dh # -------------------------------------------------------------------- if ($arg eq "-dh") { $rows = 0; &msg("NOTE: !!! orastat -dn Runs MUCH FASTER"); &msg("-dh: Datafile 'USED' High-Water-Mark"); &msg("(This command will run for awhile on databases with many datafiles)"); $sqlstmt = ' SELECT \'X\', a.tablespace_name, a.file_name, a.bytes, (b.maximum+c.blocks-1)*d.db_block_size highwater from dba_data_files a, (select file_id, max(block_id) maximum from dba_extents group by file_id) b, dba_extents c, (select value db_block_size from v\$parameter where name=\'db_block_size\') d where a.file_id = b.file_id and c.file_id = b.file_id and c.block_id = b.maximum order by a.tablespace_name,a.file_name; '; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "Tablespace Datafile Size Used HWM Savings Resize\n"; print "---------------- ------------------------------------------------------------ ------------ ------------ ------------ ------\n"; $spaceflag = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = shift @words; if ($verb eq "X") { $ts = shift @words; $dfname = shift @words; $bytes = shift @words; $hwm = shift @words; $safe = int(($hwm + 1000000)/1000000) . "M"; $savings = $bytes - $hwm; $t_savings += $savings; $resize_cmds .= "ALTER DATABASE DATAFILE '$dfname' RESIZE $safe ;\n"; printf "%-16s %-60s %12s %12s %12s %6s\n", $ts , $dfname , $bytes , $hwm , $savings , $safe ; $rows++; $total += $count; } } print "================ ============================================================ ============ ============ ============ ======\n"; printf "%-16s %-60s %12s %12s %12s %6s\n", 'Total:' , '' , '' , '' , $t_savings , '' ; print "\n"; &msg("Resize Commands:"); print "$resize_cmds\n"; exit; } # -------------------------------------------------------------------- # -dn # -------------------------------------------------------------------- if ($arg eq "-dn") { $rows = 0; $resize_cmd_count = 0; $min_mb = $arg2; $min_mb = 10 if ! $arg2; $min_bytes = $min_mb * 1000000; &msg("-dn: Datafile 'USED' High-Water-Mark"); &msg("(This command will run for awhile on databases with many datafiles)"); $sqlstmt = ' alter session set optimizer_mode=rule; select \'W\', value from v\$parameter where name = \'db_block_size\'; drop table DBSNMP.ORASTAT_DH_1; create global temporary table DBSNMP.ORASTAT_DH_1 as select file_id, max(block_id + blocks) highwater_blocks from dba_extents group by file_id; insert into DBSNMP.ORASTAT_DH_1 select file_id, max(block_id + blocks) highwater_blocks from dba_extents group by file_id; -- select * from DBSNMP.ORASTAT_DH_1; SELECT \'X\', a.tablespace_name, a.file_name, a.bytes, b.highwater_blocks from dba_data_files a, DBSNMP.ORASTAT_DH_1 b where a.file_id = b.file_id order by a.tablespace_name, a.file_name; drop table DBSNMP.ORASTAT_DH_1; '; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "Tablespace Datafile Size Used HWM Savings Resize\n"; print "-------------------- ------------------------------------------------------------ ------------ ------------ ------------ ------\n"; $spaceflag = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/ && !/^ORA-00942/; @words = split(); $verb = shift @words; if ($verb eq "W") { $block_size = shift @words; } if ($verb eq "X") { $ts = shift @words; $dfname = shift @words; $bytes = shift @words; $hwm_blocks = shift @words; $hwm = $hwm_blocks * $block_size; $hwm_mb = int($hwm / 1000000); $bytes_mb = int($bytes / 1000000); $safe = int(($hwm + 1000000)/1000000) . "M"; $savings = $bytes - $hwm; $savings_mb = int($savings / 1000000); $t_savings += $savings; if ($savings > $min_bytes) { $resize_cmds .= "ALTER DATABASE DATAFILE '$dfname' RESIZE $safe -- Datafile_Size=${bytes_mb}M Data HWM=${hwm_mb}M Savings=${savings_mb}M ; \n"; $resize_cmd_count++; $t_savings_cmd += $savings; } printf "%-20s %-60s %12s %12s %12s %6s\n", $ts , $dfname , $bytes , $hwm , $savings , $safe ; $rows++; $total += $count; } } print "==================== ============================================================ ============ ============ ============ ======\n"; printf "%-20s %-60s %12s %12s %12s %6s\n", 'Total:' , '' , '' , '' , $t_savings , '' ; print "\n"; &msg("Now, you will see syntactically correct ALTER DATAFILE commands for all"); &msg(" datafiles which can be resized to save at least 10M per datafile.\n"); &msg("Resize Commands:"); print "$resize_cmds\n"; $t_savings_mb = int($t_savings_cmd / 1000000); $t_savings_gb = int($t_savings_cmd / 1000000000); &msg("If all $resize_cmd_count ALTER DATAFILE RESIZE commands are run:"); &msg(" Total Savings (mB): $t_savings_mb"); &msg(" Total Savings (gB): $t_savings_gb"); exit; } # -------------------------------------------------------------------- # -tm # -------------------------------------------------------------------- if ($arg eq "-tm") { $rows = 0; &msg("-tm: Temporary Segments"); $sqlstmt = ' SELECT \'X\', owner, segment_name, count(*) FROM dba_extents where segment_type = \'TEMPORARY\' GROUP BY owner, segment_name;'; print "sqlstmt=$sqlstmt\n"; print "\n"; print "Segment Name Count\n"; print "---------------------------------------- ----------\n"; $total = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $owner = shift @words; $segment = shift @words; $count = shift @words; $objname = "$owner.$segment"; printf "%-40s %10s \n",$objname,$count; $rows++; $total += $count; } } print "======================================== ==========\n"; printf "%-40s %10s \n","Total:",$total; exit; } # -------------------------------------------------------------------- # -bs # -------------------------------------------------------------------- if ($arg eq "-bs") { &msg("-bs: Create DDL To Take All Datafiles Out Of Backup Mode"); $sqlstmt = ' alter session set sort_area_size = 100000000; alter session set sort_area_retained_size = 100000000; SELECT \'X\', df.name from v\$datafile df, v\$backup bk where bk.file# = df.file# and bk.status = \'ACTIVE\'; '; print "\n"; $total = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $dfname = shift @words; $cmd = "ALTER DATABASE DATAFILE '$dfname' END BACKUP;"; print "$cmd\n"; $total++; } } print "\n"; &msg("Created $total ALTER DATABASE statements"); exit; } # -------------------------------------------------------------------- # -ln # -------------------------------------------------------------------- if ($arg eq "-ln") { $rows = 0; &msg("-ln: DB Links"); $sqlstmt = ' SELECT \'X\', nvl(owner,\'(Null)\'), db_link, created, nvl(username,\'(Null)\'), host FROM dba_db_links order by 2, 3 ;'; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "Owner DB Link Name Created User Name Host \n"; print "------------ -------------------- ------------ ------------ ------------------------------------------\n"; $total = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $owner = shift @words; $dblink = shift @words; $created = shift @words; $username = shift @words; $host = shift @words; printf "%-12s %-20s %-12s %-12s %s\n",$owner,$dblink,$created,$username,$host; $rows++; } } print "\n"; &msg("Found $rows DB Links"); exit; } # -------------------------------------------------------------------- # -bm_old # -------------------------------------------------------------------- if ($arg eq "-bm_old") { $rows = 0; &msg("-bm: Tablespaces/Datafiles in Backup Mode"); &msg("NOTE: Tablespaces displayed here have AT LEAST ONE datafile in Backup Mode, but"); &msg(" not neccessarily all datafiles are in Backup Mode"); $sqlstmt = ' alter session set sort_area_size = 100000000; alter session set sort_area_retained_size = 100000000; select \'X\', ts.name, df.name from v\$backup ba, v\$datafile df, v\$tablespace ts where ba.status = \'ACTIVE\' and ba.file# = df.file# and df.ts# = ts.ts# order by 2, 3;'; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print " Tablespace Datafile \n"; print " -------------------- ----------------------------------------\n"; $total = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /ORA-/; @words = split(); $verb = shift @words; if ($verb eq "X") { $ts = shift @words; $df = shift @words; printf "TS: %-20s %40s \n",$ts,$df; $total++; } } print "\n"; &msg("Total of $total Datafiles in Backup Mode"); exit; } # -------------------------------------------------------------------- # -bm # -------------------------------------------------------------------- if ($arg eq "-bm") { $rows = 0; &msg("-bm: Tablespaces/Datafiles in Backup Mode"); &msg("NOTE: Tablespaces displayed here have AT LEAST ONE 1 datafile in Backup Mode, but"); &msg(" not neccessarily all datafiles are in Backup Mode"); $sqlstmt = ' alter session set sort_area_size = 100000000; alter session set sort_area_retained_size = 100000000; select \'X\', ts.name, df.name from v\$backup ba, v\$datafile df, v\$tablespace ts where ba.status = \'ACTIVE\' and ba.file# = df.file# and df.ts# = ts.ts# order by 2, 3;'; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print " Tablespace Datafile \n"; print " -------------------- ----------------------------------------\n"; BM_WHILE: while (1 == 1) { $total = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; if (/ORA-00235/) { &msg("Controlfile is busy (00235) - Sleeping 30 then retrying"); sleep 30; next BM_WHILE; } print if /ORA-/; @words = split(); $verb = shift @words; if ($verb eq "X") { $ts = shift @words; $df = shift @words; printf "TS: %-20s %40s \n",$ts,$df; $total++; } } last; #---- If we are here then leave while forever } print "\n"; &msg("Total of $total Datafiles in Backup Mode"); exit; } # -------------------------------------------------------------------- # -tr # -------------------------------------------------------------------- if ($arg eq "-tr") { $rows = 0; &msg("-tr: Active Transactions"); $sqlstmt = ' select \'Y\', value from v\$parameter where name in (\'db_block_size\'); SELECT \'X\', tr.addr, tr.start_time, tr.status, tr.used_ublk, tr.used_urec, se.sid, se.serial#, rn.name, se.username FROM v\$transaction tr, v\$session se, v\$rollname rn WHERE tr.xidusn = rn.usn and tr.ses_addr = se.saddr ORDER BY 6;'; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "Session,Serial# Start Timestamp Status UndoBlks UndoRecs UndoMB RBS Name DB User\n"; print "---------------- ----------------- -------- -------- -------- -------- ------------ ------------\n"; $total = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = shift @words; if ($verb eq "Y") { $blksize = shift @words; } if ($verb eq "X") { $addr = shift @words; $start = shift @words; $start .= "-" . shift @words; $status = shift @words; $ublk = shift @words; $urec = shift @words; $sid = shift @words; $ser = shift @words; $rbs = shift @words; $user = shift @words; $undo_mb = ($ublk * $blksize) / 1000000; $undo_mb = sprintf("%.2f",$undo_mb); $sidser = "$sid,$ser"; $addr = ""; printf "%-16s %-17s %-8s %8s %8s %8s %-12s %-12s\n",$sidser, $start, $status, $ublk, $urec, $undo_mb, $rbs, $user; $rows++; $totalrecs += $urec; $totalblks += $ublk; $totalmb += $undo_mb; } } print "================ ================= ======== ======== ======== ======== ============ ============\n"; $totalmb = sprintf("%.2f",$totalmb); printf "%-16s %-17s %-8s %8s %8s %8s \n\n","Total:", "", "", $totalblks, $totalrecs, $totalmb; &msg("Found $rows transactions"); exit; } # -------------------------------------------------------------------- # -avo # -------------------------------------------------------------------- if ($arg eq "-avo") { $days = $arg2; $days = 30 if $days eq ""; if ($arg3 eq "H") { $timestring = "YYYY/MM/DD-HH24"; $num = 60; } else { $arg3 = "D"; $timestring = "YYYY/MM/DD"; $num = 1440; } $days = $arg2; $days = 30 if $days eq ""; $rows = 0; &msg("-av: Archivelog Volume - For the last $days days - Mode=$arg3"); # 2.96 and 3.00 changed line: and name like '%archv01%' $sqlstmt = " select \'X\', to_char(completion_time,\'$timestring\'), sum(blocks * block_size), count(*) from v\\\$archived_log where completion_time > sysdate - $days and name like '%archv0%' group by to_char(completion_time,\'$timestring\');"; print "\n"; print " Archive Archive REDO Rate \n"; print "Timestamp Data (MB) Log Count (MB/Min)* \n"; print "------------- ---------- ---------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $ts = shift @words; $size = int((shift @words) / 1000000); $count = shift @words; $mbmin = int($size / $num); printf "%-13s %10s %10s %10s\n",$ts,$size,$count,$mbmin; $rows++; $total_size += $size; $total_count += $count; $total_mbmin += $mbmin; } } # Average line $ts = "(Average)"; $avg_size = int($total_size / $rows); $avg_count = int($total_count / $rows); $avg_mbmin = int($total_mbmin / $rows); print "------------- ---------- ---------- ----------\n"; printf "%-13s %10s %10s %10s\n",$ts,$avg_size,$avg_count,$avg_mbmin; # Total line $ts = "(Total)"; $tot_size = $total_size ; $tot_count = $total_count ; $tot_mbmin = $total_mbmin ; printf "%-13s %10s %10s %10s\n",$ts,$tot_size,$tot_count,$tot_mbmin; print "\n"; &msg("$rows Row(s) found - *: Average of a 24 hour period"); exit; } # -------------------------------------------------------------------- # -la # -------------------------------------------------------------------- if ($arg eq "-la") { &msg("-la: Latch Details - Where GETS>1000000 And MISSES>100"); $sqlstmt = ' select \'X\', GETS, MISSES, round(((GETS-MISSES)*100) / GETS , 2), IMMEDIATE_GETS, IMMEDIATE_MISSES, sleeps, spin_gets, addr, latch#, name from v\$latch where MISSES > 0 and gets > 0 --where GETS > 1000000 --and MISSES > 100 order by ((GETS-MISSES) / GETS) desc;'; print "Latch Name Gets Misses Immed. Gets Immed. Misses Sleeps Spin Gets Get Hit%\n"; print "---------------------------------------------------------- -------------- -------------- -------------- -------------- -------------- -------------- --------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; print if /^ORA/; @words = split(); $verb = shift @words; if ($verb eq "X") { $gets = shift @words; $misses = shift @words; $hitrat = shift @words; $immgets = shift @words; $immmiss = shift @words; $sleeps = shift @words; $spingets= shift @words; $latchnum= shift @words; $addr = shift @words; $name = ""; foreach (@words) { $name .= "$_ "; } $nameaddr = "$name / $latchnum / $addr"; printf "%-58s %14s %14s %14s %14s %14s %14s %7.2f%%\n",$nameaddr,$gets,$misses,$immgets,$immmiss,$sleeps,$spingets,$hitrat; } } exit; } # -------------------------------------------------------------------- # -ap # -------------------------------------------------------------------- if ($arg eq "-ap") { &msg("-ap: Archiver Processes"); $sqlstmt = ' select \'X\', process, status, log_sequence, state from v\$archive_processes order by 2;'; print "Process Status Log Seq. State\n"; print "-------- -------- -------- --------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; @words = split(); $verb = shift @words; if ($verb eq "X") { $process = shift @words; $status = shift @words; $logseq = shift @words; $state = shift @words; printf "%-8s %-8s %8s %-8s\n",$process,$status,$logseq,$state; } } exit; } # -------------------------------------------------------------------- # -ua # -------------------------------------------------------------------- if ($arg eq "-ua") { &msg("-ua: Users that need to be altered - Default TS=SYSTEM or Temp TS=SYSTEM"); $sqlstmt = ' select \'X\', username, default_tablespace, temporary_tablespace from dba_users where temporary_tablespace = \'SYSTEM\' or default_tablespace = \'SYSTEM\' and username not in ( \'SYSTEM\', \'SYS\', \'DBSNMP \', \'OUTLN \') order by 2;'; print "\n"; print "Userid Dflt. TS Temp TS \n"; print "------------ -------- --------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; @words = split(); $verb = shift @words; if ($verb eq "X") { $user = shift @words; $dflt = shift @words; $temp = shift @words; next if $user eq "DBSNMP"; next if $user eq "OUTLN"; if ($dflt eq "SYSTEM") { $sqltorun .= "ALTER USER $user DEFAULT TABLESPACE USERS;\n"; } if ($temp eq "SYSTEM") { $sqltorun .= "ALTER USER $user TEMPORARY TABLESPACE TEMP;\n"; } printf "%-12s %-8s %-8s \n",$user,$dflt,$temp; } } print "\n"; &msg("SQL To alter these users:"); print "\n"; print "$sqltorun\n"; exit; } # -------------------------------------------------------------------- # -pb # -------------------------------------------------------------------- if ($arg eq "-pb") { &msg("-pb: Performance: db_block_buffer Hit Ratio RIGHT NOW"); #---- Create uniq string chop($thread = `orastat - | grep 'Thread#:' | head -1 | awk '{ print \$NF }'`); $uniq = "_${os}_T$thread"; &msg("DEBUG uniq=$uniq"); #---- Erase old spool file system("rm /tmp/orastat_pb$uniq.lst 2>/dev/null"); &msg("A 20 second sample will be taken now"); $sqlstmt = " spool /tmp/orastat_pb$uniq.lst set echo on drop table bhm_t$uniq; create table bhm_t$uniq (sample_date date, pr1 number, pr2 number, delta_pr number, cg1 number, cg2 number, delta_cg number, bg1 number, bg2 number, delta_bg number, cum_ratio number, delta_ratio number); CREATE OR REPLACE procedure bhm_p (sample_rate number, iterations number) as pr1 number; pr2 number; delta_pr number; cg1 number; cg2 number; delta_cg number; bg1 number; bg2 number; delta_bg number; procedure wait (sample_rate number) is now date; end_time date; begin end_time := sysdate + sample_rate/(24*60*60); loop now := sysdate; if now > end_time then return; end if; end loop; end; begin select pr.value, cg.value, bg.value into pr1, cg1, bg1 from v\\\$sysstat pr, v\\\$sysstat bg, v\\\$sysstat cg where pr.name = \'physical reads\' and bg.name = \'db block gets\' and cg.name = \'consistent gets\'; insert into bhm_t$uniq (sample_date,pr1,cg1,bg2,cum_ratio) values (sysdate,pr1,cg1,bg1,round((1-(pr1/(bg1+cg1)))*100,2)); wait (sample_rate); for i in 1 .. iterations loop pr2 := pr1; cg2 := cg1; bg2 := bg1; select pr.value, cg.value, bg.value into pr1, cg1, bg1 from v\\\$sysstat pr, v\\\$sysstat bg, v\\\$sysstat cg where pr.name = \'physical reads\' and bg.name = \'db block gets\' and cg.name = \'consistent gets\'; delta_pr := pr1-pr2; delta_cg := cg1-cg2; delta_bg := bg1-bg2; insert into bhm_t$uniq values (sysdate, pr1, pr2, delta_pr, cg1, cg2, delta_cg, bg1, bg2, delta_bg, round((1-(pr1/(bg1+cg1)))*100,2), round((1-(delta_pr/(delta_bg+delta_cg)))*100,2)); commit; wait (sample_rate); end loop; end; / -- Execute samples - 10 samples of 2 seconds execute bhm_p (5, 4); -- Run query of results alter session set nls_date_format=\'mm/dd/yy:hh24:mi:ss\'; set linesize 5000; select \'X\', pr1 , pr2 , delta_pr , cg1 , cg2 , delta_cg , bg1 , bg2 , delta_bg , cum_ratio , delta_ratio from bhm_t$uniq order by sample_date; -- Drop objects drop table bhm_t$uniq; drop procedure bhm_p; "; &oraSQL($sqlstmt); $ratio = "?"; foreach (@oraSQLout) { ##print; @words = split(); $verb = shift @words; if ($verb eq "X") { $ratio = $words[10]; } } printf "\nCurrent_db_block_buffer_Hit_Ratio: %-8s\n",$ratio; exit; } # -------------------------------------------------------------------- # -au # -------------------------------------------------------------------- if ($arg eq "-au") { &msg("-au: Audit Parameters"); $sqlstmt = 'select \'X\', name, value, \'()\', description from v\$parameter where name like \'%aud%\' order by 2;'; print "Parm Value Desc.\n"; print "---------------------------------------- ----------------------------------- ------------------------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { @words = split(); $verb = $words[0]; $name = $words[1]; $value = $words[2]; $verb2 = $words[3]; $ndx = index($_,"()"); $desc = substr($_,$ndx+3,40); if ($verb eq "X") { printf "%-40s %-35s %-20s\n",$name,$value,$desc; } } &msg("Audit - What is being audited:"); $sql = " prompt DBA_STMT_AUDIT_OPTS - SQL Statements being audited select * from SYS.DBA_STMT_AUDIT_OPTS order by audit_option; prompt DBA_PRIV_AUDIT_OPTS - Privileges Statements being audited select * from SYS.DBA_PRIV_AUDIT_OPTS order by privilege; prompt DBA_OBJ_AUDIT_OPTS - Objects being audited select * from SYS.DBA_OBJ_AUDIT_OPTS order by owner, object_name, object_type; "; &oraSQL($sql); foreach (@oraSQLout) { print; } exit; } # -------------------------------------------------------------------- # -ab # -------------------------------------------------------------------- if ($arg eq "-ab") { &msg("-ab: Archive Log RMAN Backups - Listed Chronologically"); if ($arg2 ne "") { $where = "and r.sequence# = $arg2"; &msg("For Archive Log #$arg2"); } else { $where = ""; } $sqlstmt = " select \'X\', r.thread#, r.sequence#, r.blocks*r.block_size archive_size, to_char(r.first_time,\'YYYY/MM/DD-HH24:MI:SS\') first_time, to_char(r.next_time,\'YYYY/MM/DD-HH24:MI:SS\') next_time, (sysdate - r.next_time)*24 archive_age_hrs, s.backup_type, to_char(s.completion_time,\'YYYY/MM/DD-HH24:MI:SS\'), (sysdate - s.completion_time)*24 backup_age_hrs, s.elapsed_seconds from v\\\$backup_redolog r, v\\\$backup_set s where r.set_stamp = s.set_stamp and r.set_count = s.set_count $where order by 5; "; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "Arc Thread \n"; print " Sequence Size Redo Start Time Redo End Time ArcAge Backup End Time BckAge BckTim\n"; print "---------- ---------- ------------------- ------------------- ------ ------------------- ------ ------ \n"; &oraSQL($sqlstmt); $arccount = 0; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $thread = $words[1]; $seq = $words[2]; $size = $words[3]; $redostart = $words[4]; $redoend = $words[5]; $arcage = $words[6]; #$bcktype = $words[7]; $bckend = $words[8]; $bckage = $words[9]; $bckelapsed = $words[10]; printf "%-1s %8s %10s %19s %19s %6.2f %19s %6.2f %6.0f \n",$thread,$seq,$size,$redostart,$redoend,$arcage,$bckend,$bckage,$bckelapsed; $arccount++; } } print "\n"; &msg("$arccount Archive Log Backup(s) Listed"); exit; } # -------------------------------------------------------------------- # -cp # -------------------------------------------------------------------- if ($arg eq "-cp") { &msg("-cp: Active Parameters (from v\$parameter)"); print "Parm Value Desc.\n"; print "---------------------------------------- ----------------------------------- ------------------------------\n"; $sqlstmt = 'select \'X\', name, value, \'()\', description from v\$parameter order by 2;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; $name = $words[1]; $value = $words[2]; $verb2 = $words[3]; $ndx = index($_,"()"); $desc = substr($_,$ndx+3,40); if ($verb eq "X") { printf "%-40s %-35s %-20s\n",$name,$value,$desc; } } exit; } # -------------------------------------------------------------------- # -bd # -------------------------------------------------------------------- sub run_bd { $rows = 0; &msg("-bd: Datafiles Backup Mode Status"); $sqlstmt = ' alter session set sort_area_size = 100000000; alter session set sort_area_retained_size = 100000000; select \'X\', ts.name, df.name, translate(ba.status,\' \',\'_\') from v\$backup ba, v\$datafile df, v\$tablespace ts where ba.file# = df.file# and df.ts# = ts.ts# order by 2, 3;'; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print " Tablespace Datafile \n"; print " -------------------- ----------------------------------------\n"; $total = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = shift @words; if ($verb eq "X") { $ts = shift @words; $df = shift @words; $st = shift @words; printf "BackupStatus: %-15s TS: %-20s DF: %-40s %-15s\n",$st,$ts,$df; $total++; } } print "\n"; &msg("Total of $total Datafiles found in v\$backup "); } # -------------------------------------------------------------------- # -bc # -------------------------------------------------------------------- sub run_bc { &msg("-bc: Buffer Contents"); chop($blocksize = `orastat -cp | grep block_size | awk '{ print \$2 }'`); &msg("blocksize=$blocksize"); &msg("Only objects with >= 1.0 Meg in a pool will be displayed"); &bcRun9; sub bcRun9 { $tot = 0; #---- New way $bc_query = "select decode(pd.bp_id, 1,'KEEP', 2,'RECYCLE', 3,'DEFAULT', 4,'2K-SUBCACHE', 5,'4K-SUBCACHE', 6,'8K-SUBCACHE', 7,'16K-SUBCACHE', 8,'32K-SUBCACHE', 'UNKNOWN') subcache, bh.owner#, bh.object_name, bh.blocks from x\\\$kcbwds ds, x\\\$kcbwbpd pd, (select /*+ use_hash(x) */ set_ds, o.name object_name, o.owner#, count(*) BLOCKS from obj\\\$ o, x\\\$bh x where o.dataobj# = x.obj and x.state !=0 --and x.state !=0 and o.owner# !=0 group by set_ds,o.name, o.owner#) bh where ds.set_id >= pd.bp_lo_sid and ds.set_id <= pd.bp_hi_sid and pd.bp_size != 0 and ds.addr=bh.set_ds"; $sqlstmt = " drop table orastat_bc; create global temporary table orastat_bc as $bc_query; insert into orastat_bc $bc_query; -- select count(*) from orastat_bc; select * from orastat_bc; select 'X', bc.subcache, us.username, bc.object_name, sum(bc.blocks) from orastat_bc bc, dba_users us where bc.owner# = us.user_id group by bc.subcache, us.username, bc.object_name order by 2, 5 desc; "; print "\n"; print "Pool Object Tot-Blocks Tot-Meg\n"; print "-------- ---------------------------------------- ------------ ------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; #print if /^ORA/; @words = split(); $verb = $words[0]; $pool = $words[1]; $owner = $words[2]; $table = $words[3]; $blocks = $words[4]; $tbl = "$owner.$table"; $meg = sprintf("%.2f",($blocks * $blocksize) / (1024*1024)); next if $meg < 1.0; if ($verb eq "X") { printf "%-8s %-40s %12s %12s\n",$pool,,$tbl,$blocks,$meg; $tot += $blocks; $totmeg += $meg; } } print "======== ======================================== ============ ============\n"; printf "%-8s %-40s %12s %12s\n","Total:","(These Objects)",$tot,$totmeg; } } # -------------------------------------------------------------------- # -bc # -------------------------------------------------------------------- if ($arg eq "-bcold") { &msg("-bc: Buffer Contents (only works in Oracle 8i+)"); $gtot = 0; $bp = "DEFAULT"; &bcRun; $bp = "KEEP"; &bcRun; $bp = "RECYCLE"; &bcRun; print "\n"; &msg("Total Blocks (All Buffers): $gtot"); sub bcRun { print "\n"; &msg("Buffer Pool: $bp"); $tot = 0; $sqlstmt = " create or replace view v\\\$buffer_pool_lo_hi_bnum as select name , min(START_BUF#) lo_bnum, max(END_BUF#) hi_bnum, max(END_BUF#)-min(START_BUF#) buffers from v\\\$buffer_pool v, x\\\$kcbwds s where (LO_SETID=SET_ID or HI_SETID=SET_ID) and buffers > 0 group by name; select \'X\', d.owner, o.name, COUNT(buf#) BLOCKS from obj\\\$ o, x\\\$bh x, dba_objects d where o.dataobj# = x.obj and x.state != 0 and o.owner# !=0 and buf# >= (select lo_bnum from v\\\$buffer_pool_lo_hi_bnum where name = \'$bp\' and buffers > 0) and buf# <= (select hi_bnum from v\\\$buffer_pool_lo_hi_bnum where name = \'$bp\' and buffers > 0) and o.obj# = d.object_id group by d.owner, o.name order by 4; "; print "Buffer Object Blocks\n"; print "-------- ---------------------------------------- ------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; $owner = $words[1]; $table = $words[2]; $blocks = $words[3]; $tbl = "$owner.$table"; if ($verb eq "X") { printf "%-8s %-40s %12s\n",$bp,$tbl,$blocks; $tot += $blocks; $gtot += $blocks; } } print "======== ======================================== ============\n"; printf "%-8s %-40s %12s\n","$bp","Total:",$tot; } exit; } # -------------------------------------------------------------------- # -li # -------------------------------------------------------------------- if ($arg eq "-li") { $sqlstmt = 'select \'X\', resource_name, INITIAL_ALLOCATION , CURRENT_UTILIZATION , MAX_UTILIZATION , LIMIT_VALUE from v\$resource_limit order by 2;'; &msg("Resource Limits (from v\$resource_limit)"); print "Resource Initial Current Maximum Limit\n"; print "Name Value Value Value Value\n"; print "------------------------------ ---------- ---------- ---------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { @words = split(); $verb = $words[0]; $name = $words[1]; $init = $words[2]; $curr = $words[3]; $max = $words[4]; $limit = $words[5]; if ($verb eq "X") { printf "%-30s %10s %10s %10s %10s\n",$name,$init,$curr,$max,$limit; } } exit; } # -------------------------------------------------------------------- # -ob # -------------------------------------------------------------------- if ($arg eq "-ob") { &msg("-ob: DB Objects"); if ($arg2 ne "") { $z = uc $arg2; $where = "and owner = '$z'"; &msg("For OWNER=$z"); } $sqlstmt = " select \'X\', owner, object_name, object_id, status, to_char(created,\'YYYY/MM/DD-HH24:MI:SS\'), to_char(last_ddl_time,\'YYYY/MM/DD-HH24:MI:SS\'), translate(object_type,\' \',\'_\') from dba_objects where owner not like \'SYS%\' and owner != \'PUBLIC\' $where order by 2,3;"; print "\n"; print "Object Status ObjId-Dec Objid-Hex Created LastDDL ObjectType\n"; print "---------------------------------------- ------- --------- --------- ------------------- ------------------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $owner = $words[1]; $name = $words[2]; $id = $words[3]; $status = $words[4]; $credate = $words[5]; $ddldate = $words[6]; $type = $words[7]; $obj = "$owner.$name"; printf "%-40s %-7s %-9s %-9X %s %s %s\n",$obj,$status,$id,$id,$credate,$ddldate,$type; } } exit; } # -------------------------------------------------------------------- # -ad # -------------------------------------------------------------------- if ($arg eq "-ad") { $sqlstmt = ' select \'X\', DEST_ID , STATUS , BINDING , NAME_SPACE , REOPEN_SECS , TARGET , DESTINATION , to_char(FAIL_DATE,\'YYYY/MM/DD-HH24:MI:SS\') FAIL_DATE, sysdate - fail_date FAIL_AGO, FAIL_SEQUENCE, ERROR from v\$archive_dest order by 2;'; #&msg("sqlstmt=$sqlstmt"); &msg("Archive Destinations (from v\$archive_dest)\n"); print "Num Status Binding NameSpc Reopen Target Destination/Errors\n"; print "==== ======== ========== ======== ======= ======== ====================================\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; print if (/^ORA/); @words = split(); $verb = $words[0]; $dest = $words[1]; $status = $words[2]; $binding = $words[3]; $name = $words[4]; $reopen = $words[5]; $target = $words[6]; $dest2 = $words[7]; $faildt = $words[8]; $failago = $words[9] * (24); #$failsq = $words[10]; $error1 = $words[11]; $error2 = $words[12]; $error3 = $words[13]; $error4 = $words[14]; $error5 = $words[15]; $dest2 .= " " . $error1 . " " . $error2 . " " . $error3 . " " . $error4 . " " . $error5; $dest2 .= "\n Failed At: $faildt" if $faildt ne "0" && $faildt ne ""; $dest2 .= "\n Failed $failago Hours Ago" if $failago ne "0" && $failago ne ""; if ($verb eq "X") { printf "%-4s %-8s %-10s %-8s %-7s %-8s %-30s\n", $dest,$status,$binding,$name,$reopen,$target,$dest2; } } exit; } # -------------------------------------------------------------------- # -ws # -------------------------------------------------------------------- if ($arg eq "-ws") { &msg("-ws: Wait Statistics From v\$waitstat)"); $sqlstmt = ' select \'X\', count, time, class from v\$waitstat order by 2;'; #&msg("sqlstmt=$sqlstmt"); &msg("Wait Stats (from v\$waitstat)\n"); print "Wait Wait Time Class\n"; print "Count 1/100 Sec. Name\n"; print "---------- ---------- --------------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if (/^ORA/); @words = split(); $verb = $words[0]; if ($verb eq "X") { $count = $words[1]; $time = $words[2]; $z = index($_,"$words[3]"); $class = substr($_,$z); chop $class; printf "%10d %10d %-s\n",$count,$time,$class; $tot_count += $count; $tot_time += $time; } } print "========== ==========\n"; printf "%10d %10d %-s\n",$tot_count,$tot_time; exit; } # -------------------------------------------------------------------- # -ev # -------------------------------------------------------------------- if ($arg eq "-ev") { &msg("-ev: Wait Statistics From v\$system_event)"); $sqlstmt = ' select \'X\', translate(event,\' \',\'_\'), total_waits from v\$system_event order by 2;'; #&msg("sqlstmt=$sqlstmt"); print "Event Count\n"; print "---------------------------------------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if (/^ORA/); @words = split(); $verb = $words[0]; if ($verb eq "X") { $event = $words[1]; $count = $words[2]; printf "%-40s %10d \n",$event,$count; } } exit; } #-------------------------------------------------------------------- # -ub # -------------------------------------------------------------------- if ($arg eq "-ub") { $sqlstmt = ' select \'X\', owner, sum(bytes) from dba_segments group by owner order by owner;'; #&msg("sqlstmt=$sqlstmt"); &msg("Total Object Size by Owner\n"); print "Owner MBytes\n"; print "---------------- -----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; print if (/^ORA/); @words = split(); $verb = $words[0]; if ($verb eq "X") { $owner = $words[1]; $bytes = $words[2]; $mb = $bytes / 1000000; printf "%-16s %11.1f\n", $owner,$mb; $mb_total += $mb; } } print " ===========\n"; printf "%-16s %11.1f\n",$null,$mb_total; exit; } #-------------------------------------------------------------------- # -ut # -------------------------------------------------------------------- if ($arg eq "-ut") { $sqlstmt = ' select \'X\', owner, tablespace_name, sum(bytes) from dba_segments group by owner, tablespace_name order by 2, 3;'; #&msg("sqlstmt=$sqlstmt"); &msg("Total Object Size by Owner and Tablespace\n"); print "Owner Tablespace MBytes\n"; print "---------------- -------------------- -----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; print if (/^ORA/); @words = split(); $verb = $words[0]; if ($verb eq "X") { $owner = $words[1]; $ts = $words[2]; $bytes = $words[3]; $mb = $bytes / 1000000; printf "%-16s %-20s %11.1f\n", $owner,$ts, $mb; $mb_total += $mb; } } print " ===========\n"; printf "%-16s %-20s %11.1f\n",$null,$null,$mb_total; exit; } # -------------------------------------------------------------------- # -ex # -------------------------------------------------------------------- if ($arg eq "-ex") { #$sqlstmt = ' # select \'X\', # to_char(timestamp,\'YYYY/MM/DD-HH24:MI:SS\'), # lpad(\' \',2*level) || operation || \'\' || options || \' \' || object_name # from plan_table # connect by prior id=parent_id # start with id=1 # order by 2;'; $sqlstmt = " set charwidth 16; select \'X\', to_char(timestamp,\'YYYY/MM/DD-HH24:MI:SS\'), replace(operation, ' ','.'), replace(options, ' ','.'), replace(object_owner,' ','.'), replace(object_name, ' ','.'), replace(object_type, ' ','.'), nvl(to_char(id),'.'), nvl(to_char(parent_id),'.') from plan_table order by 2, id;"; #&msg("sqlstmt=$sqlstmt"); &msg("Archive Destinations (from v\$archive_dest)\n"); print "plan_table Explain Data\n"; print "====================================\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; print if (/^ORA/); @words = split(); $verb = $words[0]; if ($verb eq "X") { $ts = $words[1]; $op = $words[2]; $opt = $words[3]; $obj = $words[4] . '.' . $words[5]; $typ = $words[6]; #print "ts=$ts op=$op opt=$opt \n"; printf "%-s %-16s %-16s %-16s id=$words[7] parent_id=$words[8] \n", $ts, $op, $opt, $obj, $typ ; } } exit; } # -------------------------------------------------------------------- # -ph1 # -------------------------------------------------------------------- if ($arg eq "-ph1") { $sqlstmt = ' select \'X\', address , hash_value , buffer_gets , executions -- from v\$sqlarea from v\$sql where buffer_gets > 50000 and executions > 0 order by 3;'; #&msg("sqlstmt=$sqlstmt"); &msg("Archive Destinations (from v\$archive_dest)\n"); print "Address BufGets Execs BufGets/Exec\n"; print "============ ============== ============== ============\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if (/^ORA/); @words = split(); $verb = $words[0]; $address = $words[1]; $bufgets = $words[2]; $execs = $words[3]; $getsexec = $bufgets / $execs if $execs > 0; if ($verb eq "X") { printf "%-12s %14.0f %14.0f %12.1f \n", $address,$bufgets,$execs,$getsexec; } } exit; } # -------------------------------------------------------------------- # -qs # -------------------------------------------------------------------- if ($arg eq "-qs") { $sqlstmt = ' select \'Y\', sum(executions) from -- v\$sqlarea; v\$sql; select \'X\', command_type , sum(users_executing) , sum(executions) from -- v\$sqlarea v\$sql group by \'X\', command_type order by 4 desc;'; #&msg("sqlstmt=$sqlstmt"); &msg("-qs: SQL Statement Type Execution Counts Since Instance Start\n"); print "SQL Statement Type Executing Now Total Executions\n"; print "-------------------- -------------- -------------- -----\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if (/^ORA/); @words = split(); $verb = $words[0]; if ($verb eq "Y") { $grant_tot = $words[1]; } if ($verb eq "X") { $cmd_type = $words[1]; $exec_now = $words[2]; $exec_tot = $words[3]; if ($cmd_type == 2) { $sql_type = "INSERT"; } elsif ($cmd_type == 3) { $sql_type = "SELECT"; } elsif ($cmd_type == 6) { $sql_type = "UPDATE"; } elsif ($cmd_type == 7) { $sql_type = "DELETE"; } elsif ($cmd_type == 9) { $sql_type = "CREATE_INDEX"; } elsif ($cmd_type == 10) { $sql_type = "DROP_INDEX"; } elsif ($cmd_type == 11) { $sql_type = "ALTER_INDEX"; } elsif ($cmd_type == 12) { $sql_type = "DROP_INDEX"; } elsif ($cmd_type == 15) { $sql_type = "ALTER_TABLE"; } elsif ($cmd_type == 16) { $sql_type = "DROP_SEQUENCE"; } elsif ($cmd_type == 17) { $sql_type = "GRANT"; } elsif ($cmd_type == 18) { $sql_type = "REVOKE"; } elsif ($cmd_type == 19) { $sql_type = "CREATE_SYNONYM"; } elsif ($cmd_type == 26) { $sql_type = "LOCK_TABLE"; } elsif ($cmd_type == 28) { $sql_type = "RENAME"; } elsif ($cmd_type == 35) { $sql_type = "ALTER_DATABASE"; } elsif ($cmd_type == 39) { $sql_type = "CREATE_TABLESPACE"; } elsif ($cmd_type == 40) { $sql_type = "ALTER_TABLESPACE"; } elsif ($cmd_type == 41) { $sql_type = "DROP_TABLESPACE"; } elsif ($cmd_type == 42) { $sql_type = "ALTER_SESSION"; } elsif ($cmd_type == 44) { $sql_type = "COMMIT"; } elsif ($cmd_type == 47) { $sql_type = "PL/SQL_EXECUTE"; } elsif ($cmd_type == 48) { $sql_type = "SET_TRANSACTION"; } elsif ($cmd_type == 49) { $sql_type = "ALTER_SYS_SW_LOG"; } elsif ($cmd_type == 62) { $sql_type = "ANALYZE_TABLE"; } elsif ($cmd_type == 63) { $sql_type = "ANALYZE_INDEX"; } else { $sql_type = "OTHER-$cmd_type"; } $pctof = 100 * ($exec_tot / $grant_tot); printf "%-20s %14.0f %14.0f %4.1f%%\n", $sql_type,$exec_now,$exec_tot,$pctof; $t_now += $exec_now; $t_tot += $exec_tot; } } print "-------------------- -------------- -------------- -----\n"; printf "%-20s %14.0f %14.0f %4.1f%%\n", $zzzz,$t_now,$t_tot,$zzzz; exit; } # -------------------------------------------------------------------- # -lk # -------------------------------------------------------------------- if ($arg eq "-lk") { &msg("TX Locks (Non-Row Locks) (Long Running)"); $sqlstmt = ' alter session set optimizer_goal=RULE; select \'X\', rpad(osuser, 9)||lpad(p.spid, 5) osuser, rpad(s.username,8)||lpad(s.sid, 4)||lpad(s.serial#, 5) username, decode(l.type, \'MR\', \'Media_Reco\', \'RT\', \'Redo_Thred\', \'UN\', \'User_Name\', \'TX\', \'Trans\', \'TM\', \'DML\', \'UL\', \'PL/SQL_Usr\', \'DX\', \'Dist._Tran\', \'CF\', \'Cntrl_File\', \'IS\', \'Inst_State\', \'FS\', \'File_Set\', \'IR\', \'Inst_Reco\', \'ST\', \'Disk_Space\', \'TS\', \'Temp_Seg\', \'IV\', \'Cache_Inv\', \'LS\', \'Log_Switch\', \'RW\', \'Row_Wait\', \'SQ\', \'Seq_Number\', \'TE\', \'Extend_Tbl\', \'TT\', \'Temp_Table\', l.type) locktype, \'.\' object_name, decode(lmode,1,Null,2,\'Row_Share\',3,\'Row_Excl\',4,\'Share\', 5,\'Sh_Row_Ex\',6,\'Exclusive\',\' \') held, decode(request,1,Null,2,\'Row_Share\',3,\'Row_Excl\',4,\'Share\', 5,\'Sh_Row_Ex\',6,\'Exclusive\',\' \') request from v\$lock l, v\$session s, v\$process p where s.sid = l.sid and s.username <> \' \' and s.paddr = p.addr and l.type <> \'TM\' and (l.type <> \'TX\' or l.type = \'TX\' and l.lmode <> 6) union select \'X\', rpad(osuser, 9)||lpad(p.spid, 5) osuser, rpad(s.username,8)||lpad(s.sid, 4)||lpad(s.serial#, 5) username, decode(l.type, \'MR\', \'Media_Reco\', \'RT\', \'Redo_Thred\', \'UN\', \'User_Name\', \'TX\', \'Trans\', \'TM\', \'DML\', \'UL\', \'PL/SQL_Usr\', \'DX\', \'Dist._Tran\', \'CF\', \'Cntrl_File\', \'IS\', \'Inst_State\', \'FS\', \'File_Set\', \'IR\', \'Inst_Reco\', \'ST\', \'Disk_Space\', \'TS\', \'Temp_Seg\', \'IV\', \'Cache_Inv\', \'LS\', \'Log_Switch\', \'RW\', \'Row_Wait\', \'SQ\', \'Seq_Number\', \'TE\', \'Extend_Tbl\', \'TT\', \'Temp_Table\', l.type) locktype, object_name, decode(lmode,1,NULL,2,\'Row_Share\',3,\'Row_Excl\',4,\'Share\', 5,\'Sh_Row_Ex\',6,\'Exclusive\',NULL) held, decode(request,1,NULL,2,\'Row_Share\',3,\'Row_Excl\',4,\'Share\', 5,\'Sh_Row_Ex\',6,\'Exclusive\',NULL) request from v\$lock l, v\$session s, v\$process p, sys.dba_objects o where s.sid = l.sid and o.object_id = l.id1 and l.type = \'TM\' and s.username <> \' \' and s.paddr = p.addr union select \'X\', rpad(osuser, 9)||lpad(p.spid, 5) osuser, rpad(s.username,8)||lpad(s.sid, 4)||lpad(s.serial#, 5) username, decode(l.type, \'MR\', \'Media_Reco\', \'RT\', \'Redo_Thred\', \'UN\', \'User_Name\', \'TX\', \'Trans\', \'TM\', \'DML\', \'UL\', \'PL/SQL_Usr\', \'DX\', \'Dist._Tran\', \'CF\', \'Cntrl_File\', \'IS\', \'Inst_State\', \'FS\', \'File_Set\', \'IR\', \'Inst_Reco\', \'ST\', \'Disk_Space\', \'TS\', \'Temp_Seg\', \'IV\', \'Cache_Inv\', \'LS\', \'Log_Switch\', \'RW\', \'Row_Wait\', \'SQ\', \'Seq_Number\', \'TE\', \'Extend_Tbl\', \'TT\', \'Temp_Table\', l.type) locktype, \'(Rollback=\'||rtrim(r.name)||\')\' object_name, decode(lmode,1,NULL,2,\'Row_Share\',3,\'Row_Excl\',4,\'Share\', 5,\'Sh_Row_Ex\',6,\'Exclusive\',NULL) held, decode(request,1,NULL,2,\'Row_Share\',3,\'Row_Excl\',4,\'Share\', 5,\'Sh_Row_Ex\',6,\'Exclusive\',NULL) request from v\$lock l, v\$session s, v\$process p, v\$rollname r where s.sid = l.sid and l.type = \'TX\' and l.lmode = 6 and trunc(l.id1/65536) = r.usn and s.username <> \' \' and s.paddr = p.addr order by 5, 6;'; $locks = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; $osuser = $words[1]; $pid = $words[2]; $dbuser = $words[3]; $dbid = $words[4]; $dbser = $words[5]; $type = $words[6]; $obj = $words[7]; $held = $words[8]; $reqd = $words[9]; if ($verb eq "X") { if ($locks == 0) { print "OS User PID DB User ID Ser# Type Object Name Lock Held Lock Reqd\n"; print "-------- ----- -------- ---- ---- ---------- --------------- --------- ---------\n"; } printf "%-8s %-5s %-8s %4s %4s %-10s %-15s %-8s %-8s\n", $osuser,$pid,$dbuser,$dbid,$dbser,$type,$obj,$held,$reqd; $locks++; } } print "\n"; &msg("$locks Locks Found"); exit; } # -------------------------------------------------------------------- # sg # -------------------------------------------------------------------- if ($arg eq "-sg") { &msg("SGA Status"); print "\n"; $sqlstmt = ' select \'X\', pool, name, bytes from v\$sgastat order by 2; select \'Y\', value from v\$parameter where name = \'shared_pool_size\'; select \'Z\', value from v\$parameter where name = \'sga_target\'; '; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; $all = $_; @words = split(); $verb = $words[0]; $pool1 = $words[1]; $pool2 = $words[2]; $word1 = $words[3]; $word2 = $words[4]; $word3 = $words[5]; #$word4 = $words[6]; $wordlast = $words[$#words]; $ndx = index($_,"()"); $desc = substr($_,$ndx+3,40); if ($verb eq "Z") { $sga_target = $words[1]; } if ($verb eq "Y") { $shared_pool_size = $words[1]; if ($shared_pool_size =~ /M$/) { chop($shared_pool_size); $shared_pool_size *= 2**20; } } if ($verb eq "X") { if ($pool1 eq "shared" && $pool2 eq "pool" && $word1 eq "free" && $word2 eq "memory") { $freemem = $word3; } elsif ($pool1 eq "large" && $pool2 eq "pool" && $word1 eq "free" && $word2 eq "memory") { $freememlarge = $word3; } elsif ($pool1 eq "java" && $pool2 eq "pool" && $word1 eq "free" && $word2 eq "memory") { $freememjava = $word3; } elsif ($pool1 eq "shared" && $pool2 eq "pool" && $word1 eq "sql" && $word2 eq "area") { $sqlarea = $word3; } elsif ($pool1 eq "shared" && $pool2 eq "pool" && $word1 eq "library" && $word2 eq "cache") { $libcache = $word3; } elsif ($all =~ /db_block_buffers/) { $dbblock = $wordlast; } elsif ($all =~ /buffer_cache/) { $dbblock = $wordlast; } elsif ($all =~ /log_buffer/) { $logbuf = $wordlast; } elsif ($all =~ /fixed_sga/) { $fixedsize = $wordlast; } elsif ($pool1 eq "shared" && $pool2 eq "pool") { $sharedtot += $wordlast; } } } $total = $sharedtot + $dbblock + $logbuf + $fixedsize + $sqlarea + $libcache + $freememlarge + $freememjava; $freesharedpct = 100 - ($freemem / $shared_pool_size * 100) if $shared_pool_size > 0; ##print "sps=$shared_pool_size\n"; print "SGA Pool Size(Bytes) Size(MB)\n"; print "-------------------- --------------- ----------\n"; printf "Shared Pool (Misc.) %14s %9.2f\n",$sharedtot,$sharedtot/1000000; printf "SQL Area %14s %9.2f\n",$sqlarea,$sqlarea/1000000; printf "Library Cache %14s %9.2f\n",$libcache,$libcache/1000000; printf "DB Block Buffer %14s %9.2f\n",$dbblock,$dbblock/1000000; printf "Redo Log Buffer %14s %9.2f\n",$logbuf,$logbuf/1000000; printf "Fixed SGA %14s %9.2f\n",$fixedsize,$fixedsize/1000000; printf "Large Pool Free %14s %9.2f \n",$freememlarge,$freememlarge/1000000; printf "Java Pool Free %14s %9.2f \n",$freememjava,$freememjava/1000000; print "==================== =============== ==========\n"; printf "SGA Total Used %14s %9.2f\n",$total,$total/1000000; printf "Shared Pool Free %14s %9.2f\n",$freemem,$freemem/1000000; print "==================== =============== ==========\n"; printf "Total Shared Memory %14s %9.2f\n",$total+$freemem,($total+$freemem)/1000000; print "\n"; if ($sga_target > 0) { &msg("This instance uses AMM (sga_target=$sga_target)"); &run_amm; } else { printf "shared_pool_size %14s \n",$shared_pool_size; printf "Shared Pool Free %14d \n",$freemem; printf "Shared Pool %% Full %9.2f%% \n",$freesharedpct; } exit; } # -------------------------------------------------------------------- # rc, rd # -------------------------------------------------------------------- if ($arg eq "-rc" || $arg eq "-rd") { &msg("-rc: List and Shrink All Rollback Segments") if $arg eq "-rc"; &msg("-rd: List and ALTER MAXEXENTS UNLIMITED All Rollback Segments") if $arg eq "-rd"; $sqlstmt = 'select \'X\', SEGMENT_NAME, OWNER, TABLESPACE_NAME, SEGMENT_ID, INITIAL_EXTENT, NEXT_EXTENT, MIN_EXTENTS, MAX_EXTENTS, PCT_INCREASE, STATUS from dba_rollback_segs;'; &msg("Rollback Segments"); print "Name Owner Tablespace X-Init X-Next X-Min X-Max Status\n"; print "-------- -------- ------------ -------- -------- -------- -------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; $name = $words[1]; $owner = $words[2]; $ts = $words[3]; $id = $words[4]; $xinit = $words[5]; $xnext = $words[6]; $xmin = $words[7]; $xmax = $words[8]; $xpct = $words[9]; $status = $words[10]; if ($verb eq "X") { if ($name =~ /SYSSMU/) { &msg("NOTE: The RB segment name $name indicates that this DB has SMU turned on"); &msg("Exiting"); exit; } printf "%-8s %-8s %-12s %8d %8d %8d %8d %-10s\n", $name,$owner,$ts,$xinit,$xnext,$xmin,$xmax,$status; if ($arg eq "-rc") { &msg("(Shrinking rollback segment: $name)"); system("$os_scmd <&1 $os_conn !echo 'Issuing alter rollback segment $name shrink;'; alter rollback segment $name shrink; !"); } if ($arg eq "-rd") { &msg("(Altering rollback segment: $name MAXEXTENTS UNLIMITED)"); system("$os_scmd <&1 $os_conn alter rollback segment $name storage ( maxextents unlimited ); !"); } } } exit; } # -------------------------------------------------------------------- # rb # -------------------------------------------------------------------- if ($arg eq "-rb") { &msg("Rollback Segments"); print "\n"; $sqlstmt = 'select \'X\', s.SEGMENT_NAME, s.OWNER, s.TABLESPACE_NAME, s.BYTES, s.INITIAL_EXTENT, s.NEXT_EXTENT, s.MIN_EXTENTS, s.MAX_EXTENTS, s.PCT_INCREASE, s.EXTENTS, r.status, r.owner from dba_segments s, dba_rollback_segs r where s.segment_type=\'ROLLBACK\' and s.segment_name=r.segment_name;'; print "Name Tablespace Extents X-Init X-Next X-Min X-Max Status PUBLIC/SYS\n"; print "------------------ ------------ -------- -------- -------- -------- ---------- -------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; $name = $words[1]; $owner = $words[2]; $ts = $words[3]; $bytes = $words[4]; $xinit = $words[5]; $xnext = $words[6]; $xmin = $words[7]; $xmax = $words[8]; $xpct = $words[9]; $extents = $words[10]; $status = $words[11]; $owner = $words[12]; if ($verb eq "X") { printf "%-18s %-12s %8d %8d %8d %8d %10d %-8s %-10s\n", $name,$ts,$extents,$xinit,$xnext,$xmin,$xmax,$status,$owner; } } exit; } # -------------------------------------------------------------------- # -------------------------------------------------------------------- # ra # -------------------------------------------------------------------- if ($arg eq "-ra") { $sqlstmt = 'select \'X\', rn.NAME, rs.EXTENTS, rs.EXTENDS, rs.RSSIZE, rs.XACTS, rs.GETS, rs.HWMSIZE, rs.WRAPS, rs.AVEACTIVE, rs.STATUS, rs.WAITS, rs.optsize from v\$rollstat rs, v\$rollname rn where rn.usn=rs.usn;'; print "$P | Rollback Segments Statistics\n\n"; print "RSSize : Current rollback segment size in bytes\n"; print "A Xn's : Number of current transactions using the rollback segment\n"; print "HWMSize : High Water Mark size in bytes\n"; print "Wraps : Cumulative # of times a X'n continues writing from one\n"; print " extents to another existing extent\n"; print "Avg Actv: Avg # of bytes in active extents in the rbs measured over time\n\n"; print "Name Extents Extends RSSize A Xn's Gets HWMSize Wraps Avg Actv Status Waits Optimal\n"; print "------------ -------- -------- -------------- -------- ---------- -------------- ------ --------- -------- ------ -------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; $name = $words[1]; $extents = $words[2]; $extends = $words[3]; $rssize = $words[4]; $xacts = $words[5]; $num_gets = $words[6]; $hwmsize = $words[7]; $wraps = $words[8]; $aveactive = $words[9]; $status = $words[10]; $waits = $words[11]; $optimal = $words[12]; if ($verb eq "X") { printf "%-12s %8d %8d %14d %8d %10d %14d %6s %10d %-8s %6d %-8s\n", $name,$extents,$extends,$rssize,$xacts,$num_gets,$hwmsize,$wraps,$aveactive,$status,$waits,$optimal; $t_waits += $waits; $t_gets += $num_gets; } #if ($xacts > 1) { $xacts_flag = 1; } #if ($waits > 1) { $waits_flag = 1; } } print "\n"; #if ($xacts_flag) #{ # &msg("Since at least one segment has >1 transaction running against it,"); # &msg("try increasing the number of rollback segments."); #} #if ($waits_flag) #{ # &msg("Since at least one segment has >=1 transaction(s) waiting for it,"); # &msg("try increasing the number of rollback segments."); #} $waits_gets_r = 100 * ($t_waits/$t_gets); $waits_gets_r = sprintf("%8.5f",$waits_gets_r); &msg("Total Waits: $t_waits"); &msg("Total Gets: $t_gets"); &msg("Ratio of Waits to Gets: $waits_gets_r%"); if ($waits_gets_r > 1) { &msg("Because the ratio is > 1, add more rollback segments"); } exit; } # -------------------------------------------------------------------- # se # -------------------------------------------------------------------- if ($arg eq "-se" || $arg eq "-sd") { &msg("Active Sessions"); print "\n"; $jobcnt = 0; $sesscnt = 0; sub seTitle { print "SID-Ser# Sess. Type Status OS:Userid-PID-Server SPID DB Userid Session Start Time Program\n"; print "------------ ---------- -------- -------------------------- ----- ---------------- ------------------- --------------------\n"; } &seTitle if $arg eq "-se"; $sqlstmt = ' select distinct \'Y\', sid from v\$mystat; select \'X\', s.sid, s.serial#, nvl(p.spid,-1), s.type, --translate(s.osuser,\' \',\'-\'), translate(nvl(s.osuser,\'?\'),\' \',\'-\'), to_char(logon_time,\'YYYY/MM/DD-HH24:MI:SS\') logon_time, nvl(s.status,\'?\'), nvl(s.process,\'?\'), nvl(s.machine,\'?\'), nvl(s.username,\'?\'), nvl(s.program,\'?\'), p.program from v\$session s, v\$process p where --osuser is not null and p.addr = s.paddr order by 2; select /*+ rule */ \'Z\', s.sid, s.serial#, s.type, to_char(logon_time,\'YYYY/MM/DD-HH24:MI:SS\') logon_time, s.status, s.username, j.job, o.what from v\$session s, dba_jobs_running j, dba_jobs o where j.sid = s.sid and j.job = o.job order by 2; '; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Y") { $mysid = $words[1]; } if ($verb eq "Z") { ##print; $sid = $words[1]; $ser = $words[2]; $type = "JOB"; $logtime = $words[4]; $status = $words[5]; $dbuser = $words[6]; $jobnum = "JobNum=$words[7]"; $jobname = "JobName=$words[8]"; $sidser = "$sid,$ser"; $jobinfo = "$jobname $jobnum"; $jobcnt++; ##print "dbuser=$dbuser\n"; printf "%-12s %-10s %-8s %-26s %-5s %-16s %-19s %-20s\n", $sidser,$type,$status,"","",$dbuser,$logtime,$jobinfo; } if ($verb eq "X") { $sid = $words[1]; $ser = $words[2]; $shadow = $words[3]; $type = $words[4]; $user = $words[5]; $logtime = $words[6]; $status = $words[7]; $process = $words[8]; $machine = $words[9]; $dbuser = $words[10]; $program = $words[11] . $words[12] . $words[13] . $words[14]; $comb = "$user-$process-$machine"; $comb = substr($comb,0,26) if length($comb) > 26; $sidser = "$sid,$ser"; if ($arg eq "-sd") { print "==========================================================================================================\n"; &seTitle; } $sesscnt++; $sescount{$status}++ if $type =~ /USER/; if ($user eq "") { $user = "."; } if ($sid == $mysid) { $type = "USER*"; } ###print "user=$user\n"; printf "%-12s %-10s %-8s %-26s %-5s %-16s %-19s %-20s\n", $sidser,$type,$status,$comb,$shadow,$dbuser,$logtime,$program; if ($arg eq "-sd" && $type ne "BACKGROUND") { print "\n$P | SQL For Session $sid \n"; &srSub($sid); print "\n$P | Waits For Session $sid \n\n"; &swSub($sid); print "==========================================================================================================\n\n"; } } } print "\n"; @sorted = sort keys %sescount; foreach (@sorted) { &msg("Count of USER session(s) in $_ status: $sescount{$_}"); } &msg("There are $sesscnt total sessions (mysid=$mysid - denoted by *)"); &msg("There are $jobcnt total jobs running"); exit; } # -------------------------------------------------------------------- # sw # -------------------------------------------------------------------- if ($arg eq "-sw") { sub swTitle { print "SID DB-User WaitType St WTSeq Tmr WTTimSec Wait Event Details\n"; print "------ ---------------- -------- -- ------ --- -------- -------------------------------------\n"; } &msg("Session Waits"); print "\n"; &swTitle; &swSub; exit; } sub swSub { $sqlstmt = 'select \'X\', sw.sid, sw.seq#, nvl(sw.wait_time, 0), nvl(sw.seconds_in_wait,0), nvl(se.username,\'.\'), nvl(se.status,\'.\'), sw.p1raw, sw.p2raw, sw.p3raw, sw.event, sw.state, sw.p1text, sw.p1, sw.p2text, sw.p2, sw.p3text, sw.p3 from v\$session_wait sw, v\$session se where sw.sid = se.sid order by 2;'; &oraSQL($sqlstmt); @saveSQLout = @oraSQLout; $wait_idle_count = 0; $wait_real_count = 0; $total_sessions = 0; foreach (@saveSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; $sidno = $words[1]; $seq = $words[2]; $waittime= $words[3]; $sectimer= $words[4]; $se_user = $words[5]; $se_stat = substr($words[6],0,1); $p1raw = $words[7]; $p2raw = $words[8]; $p3raw = $words[9]; ##print "words=$#words\n"; $rawtext = "P1Raw=$p1raw P2Raw=$p2raw P3Raw=$p3raw "; $text = $rawtext; for ($i = 10; $i <= $#words; $i++) { $text .= $words[$i]; $text .= " "; } if ($verb eq "X") { $total_sessions++; $wait_type = "NoWait"; if ($sectimer > 0) { if ( $text =~ /SQL\*Net/ || $text =~ /slave wait/ || $text =~ /pmon timer/ || $text =~ /smon timer/ || $text =~ /wait for unread/ || $text =~ /queue message/ || $text =~ /waiting for/ || $text =~ /idle wait/ || $text =~ /rdbms ipc message/ ) { $wait_type = "IdleWait"; $wait_idle_count++; } else { $wait_type = "RealWait"; $wait_real_count++; } } ##print "sidno=$sidno sid=$sid \n"; next if $sidno ne $sid && $arg eq "-sd"; &swTitle if $arg eq "-sd"; if ($user eq "") { $user = "."; } ##print "sectimer=$sectimer\n"; printf "%-6d %-16s %-8s %2s %6d %3d %8d %-40s\n", $sidno,$se_user,$wait_type,$se_stat,$seq,$waittime,$sectimer,$text; #---- FUTURE ## SELECT ## SID, ## USERNAME, ## TERMINAL, ## PROGRAM ## FROM ## V$SESSION ## WHERE ## SADDR in ## ( ## SELECT ## KGLLKSES ## FROM ## X$KGLLK LOCK_A ## WHERE KGLLKREQ = 0 ## AND EXISTS ## (SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B ## WHERE KGLLKSES = 'C000000089485210' /* BLOCKED SESSION */ ## AND LOCK_A.KGLLKHDL = LOCK_B.KGLLKHDL ## AND KGLLKREQ > 0) ); #---- Analyze selected waits if ($text =~ /library cache pin/ && $p1raw) { print " -------------------------------------------------------------------\n"; print " Wait analysis for [library cache pin] wait:\n"; &oraSQL(" SELECT 'Z', kglnaown \"Owner\", kglnaobj \"Object\" FROM x\\\$kglob WHERE kglhdadr='$p1raw'; "); @save2SQLout = @oraSQLout; foreach (@save2SQLout) { ##print; @words2 = split(); $verb2 = $words2[0]; if ($verb2 eq "Z") { $diag_obj_owner = $words2[1]; $diag_obj_name = $words2[2]; print " Object Being Latched: $diag_obj_owner.$diag_obj_name\n"; } } &oraSQL(" SELECT 'Z', s.sid, kglpnmod \"Mode\", kglpnreq \"Req\" FROM x\\\$kglpn p, v\\\$session s WHERE p.kglpnuse=s.saddr AND kglpnhdl='$p1raw'; "); @save2SQLout = @oraSQLout; foreach (@save2SQLout) { ##print; @words2 = split(); $verb2 = $words2[0]; if ($verb2 eq "Z") { $diag_sid = $words2[1]; $diag_mode = $words2[2]; $diag_req = $words2[3]; if ($diag_mode == 0) { $diag_mode_long = "WAITING"; } if ($diag_mode == 2) { $diag_mode_long = "SHARED"; } if ($diag_mode == 3) { $diag_mode_long = "EXCLUSIVE"; } if ($diag_req == 0) { $diag_req_long = "NOT_WAITING"; } if ($diag_req == 2) { $diag_req_long = "SHARED"; } if ($diag_req == 3) { $diag_req_long = "EXCLUSIVE"; } print " - Session $diag_sid is holding this resource in mode $diag_mode_long - Requesting mode $diag_req_long\n"; } } print " -------------------------------------------------------------------\n"; } } } print "\n"; &msg("Total Sessions=$total_sessions - Idle Waits=$wait_idle_count - Real Waits=$wait_real_count"); } # -------------------------------------------------------------------- # sl # -------------------------------------------------------------------- if ($arg eq "-sl") { sub slTitle { print "SID DB-User St SQL Text\n"; print "------ ---------- --------------------------------------------------------------\n"; } &msg("-sl: Session Latch Waits - SQL"); print "\n"; &slTitle; &slSub; exit; } sub slSub { $sqlstmt = ' select \'X\', sw.sid, nvl(se.username,\'.\'), nvl(se.status,\'.\'), sq.sql_text from v\$session_wait sw, v\$session se, v\$sqltext sq where sw.sid = se.sid and se.sql_address = sq.address and se.sql_hash_value = sq.hash_value and sw.event = \'latch free\' order by 2, sq.piece; '; &oraSQL($sqlstmt); @saveSQLout = @oraSQLout; foreach (@saveSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; $sidno = $words[1]; $se_user = $words[2]; $se_stat = substr($words[3],0,1); $sql = ""; for ($i = 4; $i <= $#words; $i++) { $sql .= $words[$i]; $sql .= " "; } if ($verb eq "X") { ##print "sidno=$sidno sid=$sid \n"; next if $sidno ne $sid && $arg eq "-sd"; &swTitle if $arg eq "-sd"; if ($user eq "") { $user = "."; } ##print "sectimer=$sectimer\n"; if ($sidno != $lastses) { printf "%-6d %-8s %1s %-40s\n", $sidno,$se_user,$se_stat,$sql; } else { printf " %-40s\n", $sql; } $lastses = $sidno; } } } # -------------------------------------------------------------------- # rh # -------------------------------------------------------------------- if ($arg eq "-rh") { &msg("-rh: Archive Log History"); if ($oraver_num >= 9) { $zwasp = "alter session set workarea_size_policy=manual;"; } else { $zwasp = ""; } $sqlstmt = " $zwasp alter session set sort_area_size = 500000000; alter session set sort_area_retained_size = 500000000; select \'X\', THREAD#, SEQUENCE#, FIRST_CHANGE#, switch_change#, to_char(first_time,\'MM/DD/YYYY-HH24:MI:SS\') from v\\\$loghist order by 5 ;"; print "\n"; print "Thread ArcLog First Chg. Num Last Chg. Num Timestamp \n"; print "------ -------- --------------- --------------- ------------------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; $diag .= $_; @words = split(); $verb = $words[0]; $thread = $words[1]; $seq = $words[2]; $fstchg = $words[3]; $swchg = $words[4]; $fsttime= $words[5]; if ($verb eq "X") { ##print "fsttime=$fsttime\n"; printf "%6d %8d %15.0f %15.0f %-24s\n", $thread,$seq,$fstchg,$swchg,$fsttime; #last if ++$counter > 500; ++$counter; } } if ($counter < 1) { &msg("ERROR: No rows found"); &msg("diag=$diag"); } exit; } #------------------------------------------------------------------------------ sub timeToText #------------------------------------------------------------------------------ { $zz_ts = $_[0]; ($sec,$min,$hour,$mday,$mon,$year) = localtime($zz_ts); $year += 1900; $mon += 1; # Pad with 0's $yy = sprintf("%04d",$year); $mm = sprintf("%02d",$mon); $dd = sprintf("%02d",$mday); $hh = sprintf("%02d",$hour); $mi = sprintf("%02d",$min); $ss = sprintf("%02d",$sec); $date = "$yy/$mm/$dd-$hh:$mi:$ss"; return $date; } #------------------------------------------------------------------------------ sub timeToNum #------------------------------------------------------------------------------ { $zz_text = $_[0]; $zz_text =~ s/-/\//g; $zz_text =~ s/:/\//g; ##print "zz_text=$zz_text\n"; @words = split(/\//,$zz_text); if ($#words != 5) { &error("timeToNum() Input timestamp ($zz_text) should be in the format: YYYY/MM/DD-HH:MM:SS"); } $zz_yyyy = $words[0]; $zz_mon = $words[1]; $zz_dd = $words[2]; $zz_hh = $words[3]; $zz_mm = $words[4]; $zz_ss = $words[5]; ##print "zz_yyyy=$zz_yyyy zz_mon=$zz_mon zz_dd=$zz_dd zz_hh=$zz_hh zz_mm=$zz_mm zz_ss=$zz_ss\n"; &error("timeToNum() - ($zz_text) YYYY must be 2002-2099") if ($zz_yyyy < 2002 || $zz_yyyy > 2099); &error("timeToNum() - ($zz_text) MON must be 1-12 ") if ($zz_mon < 1 || $zz_mon > 12); &error("timeToNum() - ($zz_text) DD must be 1-31 ") if ($zz_dd < 1 || $zz_dd > 31); &error("timeToNum() - ($zz_text) HH must be 0-23 ") if ($zz_hh < 0 || $zz_hh > 23); &error("timeToNum() - ($zz_text) MM must be 0-59 ") if ($zz_mm < 0 || $zz_mm > 59); &error("timeToNum() - ($zz_text) SS must be 0-59 ") if ($zz_ss < 0 || $zz_ss > 59); @zz_date=($zz_ss,$zz_mm,$zz_hh,$zz_dd,--$zz_mon,$zz_yyyy); $zz_result = &timelocal(@zz_date); return $zz_result; } # -------------------------------------------------------------------- # al # -------------------------------------------------------------------- if ($arg eq "-al") { $where = "and sequence# = $arg2" if $arg2 ne ""; $where = "and first_time >= (sysdate - $arg3)" if $arg3 ne ""; &msg("-al: Archive Logs - arg2=$arg2 arg3=$arg3 arg4=$arg4"); $sqlstmt = "select \'X\', THREAD#, SEQUENCE#, name, FIRST_CHANGE#, to_char(first_time,\'YYYY/MM/DD-HH24:MI:SS\'), blocks, block_size, to_char(completion_time,\'YYYY/MM/DD-HH24:MI:SS\') from v\\\$archived_log where creator != 'RMAN' and name is not null $where order by 6 ;"; ##print "sqlstmt=$sqlstmt\n"; &msg("Archived Logs History - Sorted by 1stTimestamp"); print "Thread Seq. Archived Log File Name 1st SCN 1stTimestamp File Size Completion Timestamp \n"; print "------ ------ ------------------------------------------------------- ---------------- ------------------- ------------ --------------------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; $thread = $words[1]; $seq = $words[2]; $name = $words[3]; $fstchg = $words[4]; $fsttime= $words[5]; $blks = $words[6]; $blksize= $words[7]; $cmptime= $words[8]; if ($verb eq "X") { if ($arg4 eq "FINDIT") { next if $name =~ /STANDBY/; ##&msg("Looking for $name and $name.gzRMAN/bkRMAN"); if (! -e "$name" && ! -e "$name.gzRMAN" && ! -e "$name.bkRMAN") { next; } } $ctime_num = ""; $ctime_num = &timeToNum($cmptime) unless $cmptime eq ""; $logsize = ($blks * $blksize) + 1024; ##print "fsttime=$fsttime\n"; printf "%6d %6d %-56s %15s %-19s %12d %-19s %10d\n", $thread,$seq,$name,$fstchg,$fsttime,$logsize,$cmptime,$ctime_num; #last if ++$counter > 500; ++$counter; } } close(RO); if ($counter < 1) { print "$P | ERROR: No rows found\n"; } exit; } # -------------------------------------------------------------------- # rs # -------------------------------------------------------------------- if ($arg eq "-rs") { &msg("REDO Logs - Status"); $sqlstmt = 'select \'X\', GROUP#, THREAD#, SEQUENCE#, BYTES, MEMBERS, ARCHIVED, STATUS, FIRST_CHANGE#, to_char(first_time,\'YYYY/MM/DD-HH24:MI:SS\') from v\$log order by 3, 2;'; print "Group Thread Seq. Bytes Mbrs. Archived Status 1st Chg. 1st Date \n"; print "----- ------ -------- ---------- ----- -------- ---------- -------------- -------------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; $group = $words[1]; $thread = $words[2]; $seq = $words[3]; $bytes = $words[4]; $members= $words[5]; $arched = $words[6]; $status = $words[7]; $fstchg = $words[8]; $fsttime= $words[9]; if ($verb eq "X") { ##print "fsttime=$fsttime\n"; printf "%5d %6d %8d %10d %5d %-8s %-10s %14s %-16s\n", $group,$thread,$seq,$bytes,$members,$arched,$status,$fstchg,$fsttime; } } close(RO); exit; } # -------------------------------------------------------------------- # rr # -------------------------------------------------------------------- if ($arg eq "-rr") { &msg("REDO Log Recovery Report - CURRENT Online Redo Log Info"); $sqlstmt = 'select \'X\', a.GROUP#, a.FIRST_CHANGE#, b.member, a.SEQUENCE# from v\$log a, v\$logfile b where a.group# = b.group# and a.status = \'CURRENT\';'; print "Group 1stChange# Name Seq.\n"; print "----- ---------- -------------------------------------------------- ------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; $group = $words[1]; $fstchg = $words[2]; $name = $words[3]; $seq = $words[4]; if ($verb eq "X") { ##print "fsttime=$fsttime\n"; printf "%5d %10s %-50s %6d\n", $group,$fstchg,$name,$seq; } } exit; } # -------------------------------------------------------------------- # -iv # -------------------------------------------------------------------- if ($arg eq "-iv") { &msg("Invalid Objects"); $sqlstmt = 'select \'X\', owner || \'.\' || object_name, status, object_type from dba_objects where status != \'VALID\' order by 1, 2;'; print "Object Name Object Type Status\n"; print "-------------------------------------------------- -------------- ------\n"; $count = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; @words = split(); $verb = $words[0]; $object = $words[1]; $status = $words[2]; $type = $words[3] . ' ' . $words[4]; if ($verb eq "X") { printf "%-50s %-14s %-16s\n",$object,$type,$status; ++$count; } } print "\n"; &msg("Found $count Invalid Objects"); exit; } # -------------------------------------------------------------------- # -lf -rl # -------------------------------------------------------------------- if ($arg eq "-lf" || $arg eq "-rl") { &msg("$arg: REDO Logs - Files"); $sqlstmt = ' select \'X\', group#, member, status from v\$logfile order by 1,2;'; print "Group Name Status\n"; print "----- -------------------------------------------------- --------------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; $group = $words[1]; $member = $words[2]; $status = $words[3]; $fstchg = $words[4]; if ($verb eq "X") { printf "%5d %-50s %-20s %-10s\n",$group,$member,$status,$fstchg; } } exit; } # -------------------------------------------------------------------- # -cf # -------------------------------------------------------------------- if ($arg eq "-cf") { &msg("Control Files"); $sqlstmt = 'select \'X\', name, status from v\$controlfile;'; print "Name Status\n"; print "-------------------------------------------------- --------------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; $name = $words[1]; $stat = $words[2]; if ($verb eq "X") { printf "%-50s %-20s\n",$name,$status; } } exit; } # -------------------------------------------------------------------- # -st # -------------------------------------------------------------------- if ($arg eq "-st") { $sqlstmt = ' select \'X\', class, value, name from v\$sysstat order by 2 desc, 4;'; &msg("System Statistics"); print "\n"; print "Class Statistic Name Value\n"; print "----- -------------------------------------------------- ---------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { #print; @words = split(); $verb = $words[0]; if ($verb eq "X") { $class = $words[1]; $value = $words[2]; $namet = $words[3]; ##print "z=$z \n"; chop($name = substr($_,index($_,$namet),50)); if ($name eq "table scans (short tables)") { $scans_short = $value; } if ($name eq "table scans (long tables)") { $scans_long = $value; } if ($name eq "sorts (disk)") { $sorts_disk = $value; } if ($name eq "sorts (memory)") { $sorts_mem = $value; } printf "%5d %-50s %15s\n",$class,$name,$value; } } print "\nCalculated Statistics:\n"; $scans_total = $scans_short + $scans_long; $scans_pct = ($scans_long / $scans_total) * 100; $scans_pct = sprintf("%8.5f",$scans_pct); printf "Long Table Scans / Total Table Scans: %9s%%\n",$scans_pct; $sorts_total = $sorts_disk + $sorts_mem; $sorts_pct = ($sorts_disk / $sorts_total) * 100; $sorts_pct = sprintf("%8.5f",$sorts_pct); printf "Disk Sorts / Total Sorts: %9s%%\n",$sorts_pct; exit; } # -------------------------------------------------------------------- # -ar Activity Rate # -------------------------------------------------------------------- if ($arg eq "-ar") { &msg("-ar: Current Activity Report"); &msg("Collecting 'before' Sample"); $sqlstmt = 'select \'X\', value, name from v\$sysstat where name like \'%user%\';'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; if ($verb eq "X") { $value = $words[1]; $name1 = $words[2]; $name2 = $words[3]; if ($name1 eq "user" && $name2 eq "calls") { $b4_calls = $value; } if ($name1 eq "user" && $name2 eq "commits") { $b4_commits = $value; } $b4_time = time; } } &msg("Sleeping 10 seconds"); sleep 10; &msg("Collecting 'after' Sample"); &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; if ($verb eq "X") { $value = $words[1]; $name1 = $words[2]; $name2 = $words[3]; if ($name1 eq "user" && $name2 eq "calls") { $af_calls = $value; } if ($name1 eq "user" && $name2 eq "commits") { $af_commits = $value; } $af_time = time; } } $df_commits = $af_commits - $b4_commits; $df_calls = $af_calls - $b4_calls ; $df_time = $af_time - $b4_time ; $rt_calls = $df_calls / $df_time; $rt_commits = $df_commits / $df_time; print "$P | Time Interval: $df_time seconds\n\n"; print " Commit Count Call Count \n"; print " ------------ ------------ \n"; printf "Sample #1: %12d %12d \n",$b4_commits,$b4_calls; printf "Sample #2: %12d %12d \n",$af_commits,$af_calls; print " ============ ============ \n"; printf "Difference: %12d %12d \n",$df_commits,$df_calls; printf "Rate (Per Second): %12.1f %12.1f \n",$rt_commits,$rt_calls; exit; } # -------------------------------------------------------------------- # -az Activity Rate (logged) # -------------------------------------------------------------------- if ($arg eq "-az") { &msg("-az: Current Activity Report"); &msg("Collecting 'before' Sample"); $sqlstmt = 'select \'X\', value, name from v\$sysstat where name like \'%user%\' or name like \'%db block%\';'; ##print "sqlstmt=$sqlstmt\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; if ($verb eq "X") { $value = $words[1]; $name1 = $words[2]; $name2 = $words[3]; $name3 = $words[4]; if ($name1 eq "user" && $name2 eq "calls") { $b4_calls = $value; } if ($name1 eq "user" && $name2 eq "commits") { $b4_commits = $value; } if ($name1 eq "db" && $name2 eq "block" && $name3 eq "gets" ) { $b4_gets = $value; } if ($name1 eq "db" && $name2 eq "block" && $name3 eq "changes") { $b4_chgs = $value; } if ($name1 eq "table" && $name2 eq "scans" && $name3 eq "(long") { $b4_lscans = $value; } $b4_time = time; } } #Get latch detail samples chop($b4_lw_lc = `orastat -la | grep 'library cache' | awk '{ print \$4 }'`); chop($b4_lw_cb = `orastat -la | grep 'cache buffers chains' | awk '{ print \$5 }'`); &msg("Sleeping 10 seconds"); sleep 10; &msg("Collecting 'after' Sample"); &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; if ($verb eq "X") { $value = $words[1]; $name1 = $words[2]; $name2 = $words[3]; $name3 = $words[4]; if ($name1 eq "user" && $name2 eq "calls") { $af_calls = $value; } if ($name1 eq "user" && $name2 eq "commits") { $af_commits = $value; } if ($name1 eq "db" && $name2 eq "block" && $name3 eq "gets" ) { $af_gets = $value; } if ($name1 eq "db" && $name2 eq "block" && $name3 eq "changes") { $af_chgs = $value; } if ($name1 eq "table" && $name2 eq "scans" && $name3 eq "(long") { $af_lscans = $value; } $af_time = time; } } #Get latch detail samples chop($af_lw_lc = `orastat -la | grep 'library cache' | awk '{ print \$4 }'`); chop($af_lw_cb = `orastat -la | grep 'cache buffers chains' | awk '{ print \$5 }'`); $df_commits = $af_commits - $b4_commits; $df_calls = $af_calls - $b4_calls ; $df_time = $af_time - $b4_time ; $df_gets = $af_gets - $b4_gets ; $df_chgs = $af_chgs - $b4_chgs ; $df_lscans = $af_lscans - $b4_lscans ; $rt_calls = $df_calls / $df_time; $rt_commits = $df_commits / $df_time; $rt_gets = int($df_gets / $df_time); $rt_chgs = int($df_chgs / $df_time); $rt_lw_lc = int(($af_lw_lc - $b4_lw_lc) / $df_time); $rt_lw_cb = int(($af_lw_cb - $b4_lw_cb) / $df_time); $rt_lscans = int($df_lscans / $df_time); print "rt_gets=$rt_gets b4_gets=$b4_gets af_gets=$af_gets rt_lw_lc=$rt_lw_lc rt_lw_cb=$rt_lw_cb\n"; print "$P | Time Interval: $df_time seconds\n\n"; print " Commit Count Call Count \n"; print " ------------ ------------ \n"; printf "Sample #1: %12d %12d \n",$b4_commits,$b4_calls; printf "Sample #2: %12d %12d \n",$af_commits,$af_calls; print " ============ ============ \n"; printf "Difference: %12d %12d \n",$df_commits,$df_calls; printf "Rate (Per Second): %12.1f %12.1f \n",$rt_commits,$rt_calls; $cpuidle = "?"; $cpubusy = "?"; if (`uname` =~ /^Linux/) { $ENV{"TERM"} = "xterm"; &msg("Collecting Linux CPU busy sample"); foreach (`vmstat 5 2 | tail -1`) { print; #---- DEBUG $cpuidle = (split) [14]; $cpubusy = 100-$cpuidle; last; } } else { &msg("Collecting CPU busy sample"); #---- Old way #chop($cpuidle = `timex -s sleep 2 2>&1 | grep ":" | tail -1 | awk '{ print \$5 }'`); #---- New way chop($cpuidle = `vmstat 1 5 | tail -4 | awk '{total +=\$NF};END {print (total/4) }'`); $cpubusy = 100-$cpuidle; } &msg("cpuidle=$cpuidle cpubusy=$cpubusy"); #---- Collect mem free &msg("Collecting free memory sample"); $tmp = "/tmp/${P}_$$.txt"; unlink $tmp; if (`uname` =~ /^Linux/) { system("free >$tmp 2>&1"); } else { system("top -d 1 -f $tmp >/dev/null 2>&1"); } open(TOP, "$tmp") || &error("Cannot open input $tmp - $!"); while() { if (/^Mem/) { if (`uname` =~ /^Linux/) { $memfree_raw = (split) [3]; $memfree_raw .= "K"; } else { $memfree_raw = (split) [7]; } last; } } close(TOP); unlink $tmp; chop($memfree_mb = $memfree_raw); $memfree_mb = int($memfree_mb / 1024); &msg("memfree_mb=($memfree_raw) $memfree_mb"); &msg("Collecting Session Count sample"); @z = `orastat -se | tail -10 | grep 'Count of' | grep ACTIVE | awk '{ print \$NF }'`; chop($ses_act = $z[0]); $ses_act--; # Subtract the orastat session chop($ses_inact = $z[1]); $ses_tot = $ses_act + $ses_inact; &msg("ses_act=$ses_act ses_tot=$ses_tot ses_inact=$ses_inact"); &msg("Collecting FREE BUFFERS sample"); chop($free_buffers = `orastat -bo 1 | grep 'Status=free' | awk '{ print \$2 }'`); $free_buffers = "0" if $free_buffers eq ""; &msg("free_buffers=$free_buffers"); &msg("Collecting Latch Wait sample"); chop($ses_lw = `orastat -sw | grep 'latch' | wc -l`); &msg("ses_lw=$ses_lw"); $usersqlfile = "/opt/oracle/admin/AZ.sql"; $sql_time = "?"; &msg("Looking for $usersqlfile"); if (-e $usersqlfile) { &msg("Collecting user sql time (from $usersqlfile)"); $tmp = "/tmp/${P}_$$.txt"; system("cp $usersqlfile $tmp"); system("echo 'exit' >> $tmp"); chop($sql_time = `timex sqlplus internal \@$tmp 2>&1 | grep ^real | awk '{ print \$2 }'`); &msg("sql_time=$sql_time"); system("rm $tmp"); } # Most recent IO wait &msg("Collecting I/O wait sample (orastat -po)"); chop($mr_io_wt = `orastat -po | grep '^Average' | awk '{ print \$2 }'`); # Hit ratio &msg("Collecting DB cache hit ratio (orastat -pb)"); chop($hitr_tot = `orastat -pd | grep '^DB_BLOCK' | grep DEFAULT | head -1 | awk '{ print \$9 }'`); chop($hitr_now = `orastat -pb | grep '^Current' | awk '{ print \$NF }'`); # Sort disk/mem ratio chop($sort_disk = `orastat -st | grep 'sorts (disk)' | awk '{ print \$4 }'`); chop($sort_mem = `orastat -st | grep 'sorts (memory)' | awk '{ print \$4 }'`); &msg("sort_disk=$sort_disk sort_mem=$sort_mem"); $sort_ratio = 100 * ($sort_disk/$sort_mem); $sort_ratio = sprintf("%8.5f",$sort_ratio); &msg("sort_ratio=$sort_ratio"); # Sample biggest wait chop($_ = `orastat -wx | tail -1`); @words = split(); $wait_most_event = $words[0]; $wait_most_count = $words[1]; $wait_most_event = "?" if $wait_most_event =~ /^-/; $wait_most_count = "?" if $wait_most_count =~ /^-/; # Get archiver count chop($archiver_count = `orastat -ap | grep BUSY | wc -l`); $archiver_count =~ s/ //g; # Get arc fs full chop($arc_full = `orastat -l | grep 'Archive Dest FS Full' | awk '{ print \$NF }' | sed s/%//g`); #---- Get SGA pool free number chop($sgafree_sp = `orastat -sg | grep '^Shared Pool Free' | head -1 | awk '{ print \$NF }'`); chop($sgafree_lp = `orastat -sg | grep '^Large Pool Free' | head -1 | awk '{ print \$NF }'`); chop($sgafree_jp = `orastat -sg | grep '^Java Pool Free' | head -1 | awk '{ print \$NF }'`); &msg("DEBUG - rt_commits=$rt_commits rt_calls=$rt_calls cpubusy=$cpubusy sql_time=$sql_time archive_count=$archiver_count free_buffers=$free_buffers memfree_mb=$memfree_mb"); chop($date = `date +%Y/%m/%d-%H:%M:%S`); &msg("Logging to $savedir/ora_activity_rate_$os.txt"); $out = sprintf "$date [1] CommitRt: %5.0f DBCallRt: %5.0f CPUBusy%%: %5s SQLETime: %5s ArcsBusy: %5s FreeBufs: %5s FreeMemMB: %5s",$rt_commits,$rt_calls,$cpubusy,$sql_time,$archiver_count,$free_buffers,$memfree_mb; system("echo '$out' >> $savedir/ora_activity_rate_$os.txt"); $out = sprintf "$date [2] BufGetRt: %5s BufChgRt: %5s ActivSes: %5s TotalSes: %5s LatWtSes: %5s SGAF-SLJ: %s",$rt_gets,$rt_chgs,$ses_act,$ses_tot,$ses_lw,"$sgafree_sp/$sgafree_lp/$sgafree_jp"; system("echo '$out' >> $savedir/ora_activity_rate_$os.txt"); $out = sprintf "$date [3] LW_DC_Rt: %5s LW_CB_Rt: %5s MaxWait: $wait_most_event/$wait_most_count",$rt_lw_lc,$rt_lw_cb; system("echo '$out' >> $savedir/ora_activity_rate_$os.txt"); $out = sprintf "$date [4] MR_IO_Wt: %5s HitRaTot: %5s HitRaNow: %5s ArcFSFul: %5s SrtDskRt: %5s LngScnRt: %5s",$mr_io_wt,$hitr_tot,$hitr_now,$arc_full,$sort_ratio, $rt_lscans; system("echo '$out' >> $savedir/ora_activity_rate_$os.txt"); ##system("echo '.' >> $savedir/ora_activity_rate_$os.txt"); exit; } # -------------------------------------------------------------------- # -m # -------------------------------------------------------------------- if ($arg eq "-m") { $sqlstmt = ' select \'Z\', value from v\$parameter where name =\'background_dump_dest\';'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Z") { $fname = $words[1]; } } close(RO); $fname =~ s/\?/$oh/g; print "orastat | Alert Log: $fname\n"; print "orastat | ================================================================\n"; print "\n"; if ($fname eq "") { print "$P | ERROR: bdump Directory is BLANK - Something is Wrong!\n"; $fname = "/opt/oracle/admin/$os/bdump"; print "$P | Trying $fname \n"; } if (! -e "$fname/alert_$os.log") { print "$P | ERROR: Still cannot find $fname/alert_$os.log\n"; chop ($cluster_name = $os); #---- Try cutting off instance number $fname = "/opt/oracle/admin/$cluster_name/bdump"; print "$P | Trying $fname \n"; } if (! -e "$fname/alert_$os.log") { print "$P | ERROR: Still2 cannot find $fname/alert_$os.log\n"; $fname = "/opt/oracle/diag/rdbms/$os/$os/trace"; print "$P | Trying $fname \n"; } if (! -e "$fname/alert_$os.log") { print "$P | ERROR: Still3 cannot find $fname/alert_$os.log\n"; $fname = "/opt/oracle/admin/$os/diag/rdbms/$os/$os/trace"; print "$P | Trying $fname \n"; } if ($ENV{"LINES"} > 20) { $numlines = $ENV{"LINES"} - 11; } else { $numlines = 20; } &error("Alert Log file $fname/alert_$os.log Does not exist") if ! -e "$fname/alert_$os.log"; &error("No READ permission on Alert Log file $fname/alert_$os.log") if ! -r "$fname/alert_$os.log"; $cmd = "tail -$numlines $fname/alert_$os.log"; system($cmd); print "\n"; print "orastat | ================================================================\n"; print "orastat | Command=$cmd\n"; exit; } # -------------------------------------------------------------------- # -mv # -------------------------------------------------------------------- if ($arg eq "-mv") { $sqlstmt = ' select \'Z\', value from v\$parameter where name =\'background_dump_dest\';'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Z") { $fname = $words[1]; } } close(RO); $fname =~ s/\?/$oh/g; print "orastat | Alert Log: $fname\n"; print "orastat | ================================================================\n"; if ($fname eq "") { print "$P | ERROR: bdump Directory is BLANK - Something is Wrong!\n"; $fname = "/opt/oracle/admin/$os/bdump"; print "$P | Trying $fname \n"; } $cmd = "view $fname/alert_$os.log"; system($cmd); print "orastat | ================================================================\n"; print "orastat | Command=$cmd\n"; exit; } # -------------------------------------------------------------------- # -mf # -------------------------------------------------------------------- if ($arg eq "-mf") { $sqlstmt = ' select \'Z\', value from v\$parameter where name =\'background_dump_dest\';'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Z") { $fname = $words[1]; } } close(RO); $fname =~ s/\?/$oh/g; print "orastat | Alert Log: $fname\n"; print "orastat | ================================================================\n"; if ($fname eq "") { print "$P | ERROR: bdump Directory is BLANK - Something is Wrong!\n"; $fname = "/opt/oracle/admin/$os/bdump"; print "$P | Trying $fname \n"; } $cmd = "tail -90f $fname/alert_$os.log"; system($cmd); print "orastat | ================================================================\n"; print "orastat | Command=$cmd\n"; exit; } # -------------------------------------------------------------------- # -ma # -------------------------------------------------------------------- if ($arg eq "-ma") { $sqlstmt = ' select \'Z\', value from v\$parameter where name =\'background_dump_dest\';'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Z") { $fname = $words[1]; } } close(RO); $fname =~ s/\?/$oh/g; print "orastat | Alert Log: $fname\n"; print "orastat | ================================================================\n"; if ($fname eq "") { print "$P | ERROR: bdump Directory is BLANK - Something is Wrong!\n"; $fname = "/opt/oracle/admin/$os/bdump"; print "$P | Trying $fname \n"; } $cmd = "cat $fname/alert_$os.log"; system($cmd); print "orastat | ================================================================\n"; print "orastat | Command=$cmd\n"; exit; } # -------------------------------------------------------------------- # -c # -------------------------------------------------------------------- if ($arg eq "-c") { push(@zfiles,"$oh/dbs/init$os.ora"); push(@zfiles,"$oh/dbs/spfile$os.ora"); foreach $zfile (@zfiles) { &msg("Looking for init.ora/SPFile file: $zfile"); if (-e "$zfile") { &msg("Contents of init.ora/SPFile file: $zfile"); open(RO,"strings $zfile |") || die "Cannot OPEN $zfile - $!"; $zflag = 1; } else { &msg("File: $zfile not found"); } } die "Cannot find any init.ora/SPFiles\n" if ! $zflag; print "\n"; while () { @words = split; print; $linect++; if (substr($words[0],0,5) eq "ifile") { $ifile = $words[$#words]; print "#**** Contents of ifile: $ifile *****\n"; system("strings $ifile"); print "#**** End of ifile: $ifile *****\n"; } } close(RO); print "\n"; &msg("Found $linect PFILE lines"); exit; } # -------------------------------------------------------------------- # -ce # -------------------------------------------------------------------- if ($arg eq "-ce") { system("vi $oh/dbs/init$os.ora"); exit; } # -------------------------------------------------------------------- # -ec # -------------------------------------------------------------------- if ($arg eq "-ec") { system("vi /opt/oracle/admin/$os/pfile/config$os.ora"); exit; } # -------------------------------------------------------------------- # -ct # -------------------------------------------------------------------- if ($arg eq "-ct") { &msg("-ct: Coalesce TEMP Tablespace"); $sqlstmt = ' select \'X\', a.tablespace_name as tablespace_name, d.contents, a.sum_bytes as bytes_avail, a.max_id, nvl(b.sum_bytes,0) as bytes_used, nvl(c.sum_bytes,0) as bytes_free, round(nvl(b.sum_bytes,0.00) / a.sum_bytes * 100.0, 2) as pct_used, d.status from ( select tablespace_name, sum(bytes) sum_bytes, count(1) max_id from dba_data_files group by tablespace_name ) a, ( select tablespace_name, sum(bytes) sum_bytes from dba_extents group by tablespace_name ) b, ( select tablespace_name, sum(bytes) sum_bytes from dba_free_space group by tablespace_name ) c, dba_tablespaces d where a.tablespace_name = b.tablespace_name (+) and a.tablespace_name = c.tablespace_name (+) and a.tablespace_name = d.tablespace_name (+) and d.contents = \'TEMPORARY\';'; print "Tablespace Type Status NumDF Size(MB) Free(MB) Used(MB) Pct\n"; print "-------------------- ---- -------- ----- --------- --------- --------- -----\n"; $ts_count = -1; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $ts_count+=1; $found = 1; $ts = $words[1]; $type = substr($words[2],0,4); $size = $words[3]/1048576; $max = $words[4]; $used = $words[5]/1048576; $free = $words[6]/1048576; $pct = $words[7]; $status = $words[8]; $temp_ts[$ts_count] = $ts; printf("%-20s %-4s %-8s %5d %9d %9d %9d %5.1f\n",$ts,$type,$status,$max,$size,$free,$used,$pct); $tot_size += $size; $tot_free += $free; $tot_used += $used; $tot_df += $max; } } if (!$found) { &msg("Something is wrong - query returned no rows"); exit 1; } #### !echo 'Issuing coalesce statements;'; foreach $temp_tablespace (@temp_ts) { print "\n"; print "Coalescing $temp_tablespace tablespace...\n"; system("$os_scmd <&1 $os_conn alter tablespace $temp_tablespace default storage (pctincrease 1); alter tablespace $temp_tablespace coalesce; alter tablespace $temp_tablespace coalesce; alter tablespace $temp_tablespace coalesce; alter tablespace $temp_tablespace coalesce; alter tablespace $temp_tablespace default storage (pctincrease 0); !"); } print "\n"; print "Tablespace Type Status NumDF Size(MB) Free(MB) Used(MB) Pct\n"; print "-------------------- ---- -------- ----- --------- --------- --------- -----\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $found = 1; $ts = $words[1]; $type = substr($words[2],0,4); $size = $words[3]/1048576; $max = $words[4]; $used = $words[5]/1048576; $free = $words[6]/1048576; $pct = $words[7]; $status = $words[8]; printf("%-20s %-4s %-8s %5d %9d %9d %9d %5.1f\n",$ts,$type,$status,$max,$size,$free,$used,$pct); $tot_size += $size; $tot_free += $free; $tot_used += $used; $tot_df += $max; } if (!$found) { print "$P | Something is wrong - query returned no rows\n"; exit 1; } } exit; } # -------------------------------------------------------------------- # -ts # -------------------------------------------------------------------- if ($arg eq "-ts") { # If this is 8.1+, then also get extent mgmt ... #if (-s "$oh/install/unix.rgs") if ($oraver_num >= 8.1) { $where = ", d.extent_management, d.allocation_type" } else { $where = ""; } ##print "w=$where \n"; if ($arg3) { $where2 = "and a.tablespace_name like '${arg3}%' " } $sqlstmt = " select \'X\', a.tablespace_name as tablespace_name, d.contents, a.sum_bytes as bytes_avail, a.max_id, a.sum_bytes - nvl(c.sum_bytes,0) as bytes_used, nvl(c.sum_bytes,0) as bytes_free, round((a.sum_bytes - nvl(c.sum_bytes,0.00)) / a.sum_bytes * 100.0, 2) as pct_used, d.status $where from ( select tablespace_name, sum(bytes) sum_bytes, count(1) max_id from dba_data_files group by tablespace_name ) a, ( select tablespace_name, sum(bytes) sum_bytes from dba_free_space group by tablespace_name ) c, dba_tablespaces d where a.tablespace_name = c.tablespace_name (+) $where2 and a.tablespace_name = d.tablespace_name (+) order by 2; select \'Y\', count(distinct tablespace_name) from dba_temp_files; "; print "\n"; print "PermanentTablespace Type Status ExtentMgmt AllocTyp NumDF Size(MB) Free(MB) Used(MB) Pct\n"; print "------------------------ ---- -------- ---------- -------- ----- --------- --------- --------- ------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/ && !/^ORA-00942/; @words = split; $verb = $words[0]; if ($verb eq "Y") { $found = 1; if ($words[1] > 0) { $foundtemp = 1; $counttemp = $words[1]; } } if ($verb eq "X") { $tscount++; $found = 1; $ts = $words[1]; $type = substr($words[2],0,4); $size = $words[3]/1048576; $max = $words[4]; $used = $words[5]/1048576; $free = $words[6]/1048576; $pct = $words[7]; $status = $words[8]; $extmgmt = $words[9]; $alloctyp = $words[10]; $extmgmt = "." if $extmgmt eq ""; $alloctyp = "." if $alloctyp eq ""; $used = $size - $free; #---- Old #if ($arg2) { $z = "$date "; } #else { $z = ""; } if ($arg2 && substr($ts,0,1) eq $arg2) { &msg("Skipping ts=$ts - arg2=$arg2"); next; } printf("${z}%-24s %-4s %-8s %-10s %-8s %5d %9d %9d %9d %6.2f \n",$ts,$type,$status,$extmgmt,$alloctyp,$max,$size,$free,$used,$pct); $tot_size += $size; $tot_free += $free; $tot_used += $used; $tot_df += $max; } } if (!$found) { print "$P | Something is wrong - query returned no rows\n"; exit 1; } print "======================== ==== ======== ========== ======== ===== ========= ========= ========= ======\n"; $ts = "Total: ($tscount TS)"; $pct = ($tot_used / $tot_size * 100); printf("%-24s %5d %9d %9d %9d %6.2f\n",$ts,$tot_df,$tot_size,$tot_free,$tot_used,$pct); print "\n"; &msg("Found $tscount tablespace(s)\n"); if ($foundtemp && ! $arg3) { print "Note: This DB also has $counttemp 8i+ Temporary TS(s) listed in dba_temp_files - invoking orastat -tt\n\n"; &run_tt; exit; } else { exit; } } # -------------------------------------------------------------------- # -tt # -------------------------------------------------------------------- if ($arg eq "-ttold") { # If this is 8.1+, then also get extent mgmt ... #if (-r "$oh/install/unix.rgs") if ($oraver_num >= 8.1) { $where = ", d.extent_management, d.allocation_type" } else { $where = ""; } ##print "w=$where \n"; $tot_size = 0; $tot_free = 0; $tot_used = 0; $tot_df = 0; $sqlstmt = "select \'X\', a.tablespace_name as tablespace_name, d.contents, a.sum_bytes as bytes_avail, nvl(a.max_id,0), nvl(a.sum_bytes-c.sum_bytes,0) as bytes_used, nvl(c.sum_bytes,0) as bytes_free, round(nvl((a.sum_bytes-c.sum_bytes),0.00) / a.sum_bytes * 100.0, 2) as pct_used, d.status $where from ( select tablespace_name, sum(bytes) sum_bytes, count(1) max_id from dba_temp_files group by tablespace_name ) a, ( select tablespace_name, sum(bytes) sum_bytes from dba_free_space group by tablespace_name ) c, dba_tablespaces d where a.tablespace_name = c.tablespace_name (+) and a.tablespace_name = d.tablespace_name (+); "; print "TemporaryTablespace Type Status ExtentMgmt AllocTyp NumDF Size(MB) Free(MB) Used(MB) Pct\n"; print "------------------------ ---- -------- ---------- -------- ----- --------- --------- --------- -----\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split; $verb = $words[0]; if ($verb eq "X") { $found = 1; $ts = $words[1]; $type = substr($words[2],0,4); $size = $words[3]/1048576; $max = $words[4]; $used = $words[5]/1048576; $free = $words[6]/1048576; $pct = $words[7]; $status = $words[8]; $extmgmt = $words[9]; $alloctyp = $words[10]; printf("%-24s %-4s %-8s %-10s %-8s %5d %9d %9d %9d %5.1f \n",$ts,$type,$status,$extmgmt,$alloctyp,$max,$size,$free,$used,$pct); $tot_size += $size; $tot_free += $free; $tot_used += $used; $tot_df += $max; } } if (!$found) { print "$P | Something is wrong - query returned no rows\n"; exit 1; } print "======================== ==== ======== ========== ======== ===== ========= ========= ========= =====\n"; $ts = "Total:"; $pct = ($tot_used / $tot_size * 100); printf("%-20s %5d %9d %9d %9d %5.1f\n",$ts,$tot_df,$tot_size,$tot_free,$tot_used,$pct); print "\nNote: The 'Used' and 'Free' numbers above are not accurate. Run orastat -si for Sort Segment information\n"; exit; } # -------------------------------------------------------------------- # -tc # -------------------------------------------------------------------- if ($arg eq "-tc") { &msg("-tc: Create SQL to count the rows in all permanent tables"); $sqlstmt = ' select \'X\', owner, segment_name, tablespace_name, blocks, extents, max_extents from dba_segments where segment_type = \'TABLE\' order by 2,3;'; &oraSQL($sqlstmt); $count = 0; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $owner = $words[1]; $table = $words[2]; $obj = "$owner.$table"; $outdata .= "select \'$obj\', count(*), to_char(sysdate,\'YYYY/MM/DD-HH24:MI:SS\') from $obj ;\n"; $count++; } } open(OUTDATA, ">/tmp/orastat_tables.sql") || die "Cannot open output orastat_tables.sql - $!"; print OUTDATA "$outdata"; close(OUTDATA); &msg("Wrote $count SQL statements to /tmp/orastat_tables.sql"); exit; } #=============================================================================== # -er Select from dba.errors #=============================================================================== if ($arg eq "-er") { &msg("-er: Display DBA_ERRORS"); $sqlstmt = 'select \'X\', OWNER, NAME, TYPE, SEQUENCE, LINE, POSITION, trim(trailing \' \' from TEXT) from dba_errors ;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $text = substr($_,index($_,$words[7])); print "Owner=$words[1] Name=$words[2] Type=$words[3] Seq=$words[4] Line=$words[5] Position=$words[6] Text=$text"; $count++; } } if ($count < 1) { &msg("No rows selected"); } exit; } #=============================================================================== # -de Create script to rm all datafiles, redo logs and control files #=============================================================================== if ($arg eq "-de") { &msg("All Datafiles, Online Redo Logs and Control Files"); $sqlstmt = ' select \'W\', file_name, tablespace_name from dba_temp_files union all select \'X\', file_name, tablespace_name from dba_data_files union all select \'Y\', member, \' \' from v\$logfile union all select \'Z\', name, \' \' from v\$controlfile order by 1, 2;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; $ts = $words[2]; if ($verb eq "W") { $f = $words[1]; print "CMD $f # Temp File (TS=$ts)\n"; } if ($verb eq "X") { $f = $words[1]; print "CMD $f # DF (TS=$ts)\n"; } if ($verb eq "Y") { $f = $words[1]; print "CMD $f # Online Redo Log\n"; } if ($verb eq "Z") { $f = $words[1]; print "CMD $f # Control File\n"; } } exit; } #=============================================================================== # -dc List Datafiles #=============================================================================== if ($arg eq "-dc") { $sqlstmt = 'select \'X\', tablespace_name, file_name, bytes, file_id from dba_data_files order by 1, 2;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $df = $words[2]; $newdf = $df; $newdf =~ s/$os/NEWDBNAME/g; @words = split(/\//,$df); $lastnode = $words[$#words]; ##print "1=$words[1] #=$#words\n"; ##print "lastnode=$lastnode\n"; $newdir = $df; $newdir =~ s/$lastnode//g; $newdir =~ s/$os/NEWDBNAME/g; printf("time mkdir -p %s\n", $newdir); printf("time cp %s %s\n",$df, $newdf); } } exit; } #=============================================================================== # -df List Datafiles #=============================================================================== if ($arg eq "-df") { &msg("-df Datafiles"); print "\n"; print "Tablespace DF Datafile Datafile Datafile FS Free \n"; print "Name Num Path Status Size(MB) Space(MB)\n"; print "------------------------ ---- ---------------------------------------------------------------------- --------- --------- ---------\n"; $sqlstmt = 'column file_name format a80 select \'X\', tablespace_name, file_name, nvl(bytes,0), file_id, nvl(status,\'?\') from dba_data_files order by 2, 5;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $dfcount++; $status = ""; $ts = $words[1]; $df = $words[2]; $size = $words[3]/1048576; $num = $words[4]; $status = $words[5]; ##print "num=$num \n"; if (-c $df) { $fs = "(Raw)"; } else { if ($arg2 eq "FSCHECK") { $fs = `$bdfcmd $df | awk '{ print \$4 }' | tail -1`; $fs = sprintf("%9d",$fs / 1024); } else { $fs = "."; } } if ($ts eq $lastts) { #$tsout = '""'; $tsout = $ts; } else { $tsout = $ts; } printf("%-24s %4d %-70s %-8s %9d %9s\n",$tsout,$num,$df,$status,$size,$fs); $lastts = $ts; } } print "\n"; &msg("Found $dfcount datafile(s)"); exit; } #=============================================================================== # -df2 List Datafiles by filesize desc #=============================================================================== if ($arg eq "-df2") { &msg("-df2 Datafiles"); print "\n"; print "Tablespace DF Datafile Datafile Datafile FS Free \n"; print "Name Num Path Status Size(MB) Space(MB)\n"; print "------------------------ ---- ---------------------------------------------------------------------- --------- --------- ---------\n"; $sqlstmt = ' column file_name format a70 select \'X\', tablespace_name, file_name, nvl(bytes,0), file_id, nvl(status,\'?\') from dba_data_files order by 4 desc, 3;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $dfcount++; $status = ""; $ts = $words[1]; $df = $words[2]; $size = $words[3]/1048576; $num = $words[4]; $status = $words[5]; ##print "num=$num \n"; if (-c $df) { $fs = "(Raw)"; } else { if ($arg2 eq "FSCHECK") { $fs = `$bdfcmd $df | awk '{ print \$4 }' | tail -1`; $fs = sprintf("%9d",$fs / 1024); } else { $fs = "."; } } if ($ts eq $lastts) { #$tsout = '""'; $tsout = $ts; } else { $tsout = $ts; } printf("%-24s %4d %-70s %-8s %9d %9s\n",$tsout,$num,$df,$status,$size,$fs); $lastts = $ts; } } print "\n"; &msg("Found $dfcount datafile(s)"); exit; } #=============================================================================== # -tf List Tempfiles #=============================================================================== if ($arg eq "-tf") { &msg("-tf Tempfiles"); print "\n"; print "Tablespace DF Tempfile Tempfile Tempfile FS Free Possible\n"; print "Name Num Path Status Size(MB) Space(MB) Issue(s)\n"; print "---------------- ---- ------------------------------------------------------- --------- --------- --------- ----------\n"; $sqlstmt = 'select \'X\', tablespace_name, file_name, nvl(bytes,0), file_id, nvl(status,\'?\') from dba_temp_files order by 2, 5;'; $sparsecnt = 0; $sparse = ""; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $dfcount++; $status = ""; $ts = $words[1]; $df = $words[2]; $size = $words[3]/1048576; $num = $words[4]; $status = $words[5]; ##print "num=$num \n"; if (-c $df) { $fs = "(Raw)"; } else { if ($arg2 eq "FSCHECK" && $df !~ /\+/) { $fs = `$bdfcmd $df | awk '{ print \$4 }' | tail -1`; $fs = sprintf("%9d",$fs / 1024); } else { $fs = "."; } } if ($ts eq $lastts) { #$tsout = '""'; $tsout = $ts; } else { $tsout = $ts; } if ($df !~ /^\+/) { #---- See if this is a sparse file $spdev = ""; $spmtime = ""; $sprdev = ""; $spmode = ""; $spatime = ""; $spgid = ""; $spuid = ""; $spino = ""; $spnlink = ""; $spctime = ""; $sparse = ""; ($spdev,$spino,$spmode,$spnlink,$spuid,$spgid,$sprdev,$spsize, $spatime,$spmtime,$spctime,$spblksize,$spblocks) = stat($df); $spblksize = 512; #---- stat is wrong chop($spblocks = `ls -ls $df | awk '{ print \$1 }'`); $sizecalc = $spblocks * $spblksize; if ($spsize > 0 && $sizecalc > 0 && $sizecalc < ($spsize - (1024*1024))) { $sizecalc_mb = int($sizecalc / (1024 * 1024)); ##$sparse = "(SPARSE - Filesize=${sizecalc_mb}MB sizecalc=$sizecalc spsize=$spsize spblocks=$spblocks spblksize=$spblksize)"; $sparse = "(SPARSE - ActualFilesize=${sizecalc_mb}MB)"; $sparsecnt++; } else { $sparse = ""; } } printf("%-16s %4d %-55s %-8s %9d %9s %s\n",$tsout,$num,$df,$status,$size,$fs,$sparse); $lastts = $ts; } } print "\n"; &msg("Found $dfcount tempfile(s)"); &msg("SparseFileCnt: $sparsecnt"); exit; } #=============================================================================== # -fs List freespace in Datafiles #=============================================================================== if ($arg eq "-fs") { &msg("Datafile Free Space"); $sqlstmt = 'select \'X\', df.tablespace_name, df.file_name, df.file_id, nvl(df.bytes,0), nvl(sum(fs.bytes),0) from dba_data_files df, dba_free_space fs where df.file_id = fs.file_id group by \'X\', df.tablespace_name, df.file_name, df.file_id, df.bytes order by 2,4;'; print "Tablespace DF Datafile Datafile Datafile Datafile \n"; print "Name Num Path Alloc(Kb) Used(Kb) Free(Kb) \n"; print "---------------- ---- ------------------------------------------------------- --------- --------- --------- \n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $dfcount++; $ts = $words[1]; $df = $words[2]; $num = $words[3]; $size = $words[4]/1024; $free = $words[5]/1024; printf("%-16s %4d %-55s %9d %9d %9d\n",$ts,$num,$df,$size,$size-$free,$free); } } print "\n"; &msg("Found $dfcount datafile(s) with free space."); exit; } #=============================================================================== # -ft List fast start recovery transactions #=============================================================================== if ($arg eq "-ft") { &msg("-ft: List Fast Start Transactions Being Rolled Back"); $sqlstmt = ' select \'Y\', name, value from v\$parameter where name in (\'db_block_size\'); select \'X\', usn, slt, seq, state, undoblocksdone, undoblockstotal, cputime from v\$fast_start_transactions order by 2,3,4;'; print "\n"; print "Undo Seg/Slt/Inc Rollback State CPU Time Blks Done Blks Total mB Done mb Total Pct.\n"; print "---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ----\n"; $transcount = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Y") { $blocksize = $words[1]; } if ($verb eq "X") { $transcount++; $usn = $words[1]; $slt = $words[2]; $seq = $words[3]; $state = $words[4]; $blks_d = $words[5]; $blks_t = $words[6]; $cputim = $words[7]; $undo = "$usn/$slt/$seq"; $pctdone = ($blks_d / $blks_t) * 100; $pctdone = sprintf("%.2f",$pctdone); $undo_t_mb = int(($blocksize * $blks_t) / 1000000); $undo_d_mb = int(($blocksize * $blks_d) / 1000000); printf("%-16s %-16s %10s %10s %10s %10s %10s %-4s\n", $undo, $state, $cputim, $blks_d, $blks_t, $undo_d_mb, $undo_t_mb, $pctdone); } } print "\n"; &msg("Found $transcount Transactions being rolled back"); exit; } # -------------------------------------------------------------------- # -us # -------------------------------------------------------------------- if ($arg eq "-us") { &msg("All Users"); print "\n"; if ($oraver_num < 8.0) { $sqlstmt = 'select \'X\', username, nvl(password,\'?\'), default_tablespace, temporary_tablespace, to_char(created, \'YYYY/MM/DD-HH24:MI:SS\'), nvl(profile,\'?\') from dba_users order by 2;'; } else { $sqlstmt = 'select \'X\', username, nvl(password,\'?\'), default_tablespace, temporary_tablespace, to_char(created, \'YYYY/MM/DD-HH24:MI:SS\'), profile, translate(account_status,\' \',\'_\') from dba_users order by 2;'; } print "User Password Profile DefaultTS TempTS Created AccountStatus\n"; print "-------------------------- ---------- -------------------------------- -------------------- ---------- ------------------- --------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $user = $words[1]; $pw = $words[2]; $ts = $words[3]; $temp = $words[4]; $crdate = $words[5]; $profile = $words[6]; $status = $words[7]; if ($pw ne "EXTERNAL") { $pw = "(Set)"; } printf("%-26s %-10s %-32s %-20s %-10s %-19s %-s\n",$user,$pw,$profile,$ts,$temp,$crdate,$status); $found++; } } print "\n"; &msg("$found Total Users"); exit; } # -------------------------------------------------------------------- # -ru # -------------------------------------------------------------------- if ($arg eq "-ru") { &msg("-ru: Rollback Usage - By Session"); print "\n"; $sqlstmt = 'select \'X\', s.username, s.sid, s.serial#, t.used_ublk, translate(t.start_time,\' \',\'-\') from v\$transaction t, v\$session s where t.addr = s.taddr order by 5 desc;'; print "DBUserid SID Serial Undo Blks Trans. Started \n"; print "------------ ------ ------ ---------- -----------------\n"; &oraSQL($sqlstmt); $cnt = 0; foreach (@oraSQLout) { #3print; print if /^ORA/; @words = split; $verb = shift(@words); if ($verb eq "X") { $user = shift(@words); $sid = shift(@words); $ser = shift(@words); $blks = shift(@words); $strttime = shift(@words); printf("%-12s %-6s %-6s %10s %-19s\n",$user,$sid,$ser,$blks,$strttime); $cnt++; } } print "\n"; &msg("$cnt Total Active Transactions"); exit; } # -------------------------------------------------------------------- # -tz # -------------------------------------------------------------------- if ($arg eq "-tz") { if ($arg2 eq "top") { $orderby = "5 desc"; } else { $orderby = "2,3"; } &msg("Non-SYS Tables (From DBA_TABLES)"); &msg("Note: Totals are only valid if ANALYZE/dbms_stats Has Been Run"); $sqlstmt = " select \'W\', sum(blocks) from dba_tables; select \'Y\', name, value from v\\\$parameter where name in (\'db_block_size\',\'db_block_buffers\'); select \'X\', owner, table_name, nvl(tablespace_name,\'?\'), nvl(blocks,-1), nvl(num_rows,-1), nvl(buffer_pool,\'?\'), nvl(to_char(last_analyzed,\'MM/DD/YYYY-HH24\'),-1) from dba_tables order by $orderby ;"; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "Owner.Table TableSpace Rows Last Analyzed Buf-Pool Blocks MBytes %OfTot\n"; print "----------------------------------- -------------- --------- ------------- -------- -------- -------- ------\n"; $total_objs = 0; $total_anal = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "W") { $sumblocks = $words[1]; ##print "sumblocks=$sumblocks\n"; } if ($verb eq "Y") { if ($words[1] eq "db_block_size") { $bs = $words[2]; ##print "bs=$bs\n"; } } if ($verb eq "X") { $owner = $words[1]; $table = $words[2]; $ts = $words[3]; $blks = $words[4]; $rows = $words[5]; $bp = $words[6]; $la = $words[7]; $t = $owner . "." . $table; if ($owner ne "SYS" && $owner ne "SYSTEM") { $found_tables++; $total_objs++; $total_anal++ if $rows > -1; $mb = int(($bs * $blks) / 1000000); if ($mb > $top_table_mb) { $top_table_name = $owner . "." . $table; $top_table_mb = $mb; $top_table_rows = $rows; } $pct = ""; if ($blks > 0 && $sumblocks > 0) { $pct = ($blks / $sumblocks) * 100; $pct = sprintf("%4.1f",$pct); $total_pct += $pct; } printf("%-35s %-14s %9d %13s %-8s %8d %8d %6s\n",$t,$ts,$rows,$la,$bp,$blks,$mb,$pct); if ($bp eq "DEFAULT") { $def_total += $mb; } elsif ($bp eq "KEEP") { $kep_total += $mb; } elsif ($bp eq "RECYCLE") { $rec_total += $mb; } $total_mb += $mb; if ($arg2 eq "top" && $found_tables >= $arg3) { last; } } } } print "=================================== ============== ========= ============= ======== ======== ======== ======\n"; printf("%-35s %-14s %9s %13s %-8s %8s %8d %6s\n","Total:","","","","","",$total_mb,$total_pct); print "\n"; &msg("$found_tables Tables"); print "\n"; &msg("Non-SYS Indexes (From DBA_INDEXES)"); &msg("Note: Totals are only valid if ANALYZE/dbms_stats Has Been Run"); $sqlstmt = " select \'W\', sum(leaf_blocks) from dba_indexes; select \'X\', owner, index_name, nvl(tablespace_name,\'?\'), nvl(leaf_blocks,-1), nvl(num_rows,-1), nvl(buffer_pool,\'?\'), nvl(to_char(last_analyzed,\'MM/DD/YYYY-HH24\'),-1) from dba_indexes order by $orderby ;"; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "Owner.Index TableSpace Rows Last Analyzed Buf-Pool Blocks MBytes %OfTot\n"; print "----------------------------------- -------------- --------- ------------- -------- -------- -------- ------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "W") { $sumblocks = $words[1]; ##print "sumblocks=$sumblocks\n"; } if ($verb eq "X") { $owner = $words[1]; $table = $words[2]; $ts = $words[3]; $blks = $words[4]; $rows = $words[5]; $bp = $words[6]; $la = $words[7]; $t = $owner . "." . $table; if ($owner ne "SYS" && $owner ne "SYSTEM") { $found_indexes++; $total_objs++; $total_anal++ if $rows != -1; $mb = int(($bs * $blks) / 1000000); if ($mb > $top_index_mb) { $top_index_name = $owner . "." . $table; $top_index_mb = $mb; $top_index_rows = int($rows); } $pct = ""; if ($blks > 0 && $sumblocks > 0) { $pct = ($blks / $sumblocks) * 100; $pct = sprintf("%4.1f",$pct); $total_pct += $pct; } printf("%-35s %-14s %9d %13s %-8s %8d %8d %6s\n",$t,$ts,$rows,$la,$bp,$blks,$mb,$pct); if ($bp eq "DEFAULT") { $def_total += $mb; } elsif ($bp eq "KEEP") { $kep_total += $mb; } elsif ($bp eq "RECYCLE") { $rec_total += $mb; } $total_mb += $mb; if ($arg2 eq "top" && $found_indexes >= $arg3) { last; } } } } print "=================================== ============== ========= ============= ======== ======== ======== ======\n"; printf("%-35s %-14s %9s %13s %-8s %8s %8d %6s\n","Total:","","","","","",$total_mb,$total_pct); print "\n"; &msg("$found_indexes Indexes"); print "\n"; $def_blks = int(($def_total*1000000) / $bs); $kep_blks = int(($kep_total*1000000) / $bs); $rec_blks = int(($rec_total*1000000) / $bs); $total_blks = $def_blks + $kep_blks + $rec_blks; &msg("Total Size By Buffer Pool (Sum of Sizes of Above Tables And Indexes):"); print "\n"; print "Buffer Pool Total Size (mB) Total Blks \n"; print "----------- --------------- -----------\n"; printf("%-11s %15d %11d\n","DEFAULT", $def_total, $def_blks); printf("%-11s %15d %11d\n","KEEP", $kep_total, $kep_blks); printf("%-11s %15d %11d\n","RECYCLE", $rec_total, $rec_blks); print "=========== =============== ===========\n"; printf("%-11s %15d %11d\n","Total:", $total_mb,$total_blks); print "\n"; $total_pct = sprintf("%.2f",($total_anal/$total_objs)*100); &msg("Analyzed Objects: $total_anal/$total_objs (${total_pct}%)"); if ($top_table_name) { &msg("Largest Table: $top_table_name ($top_table_rows Rows - ${top_table_mb} MB)"); } if ($top_index_name) { &msg("Largest Index: $top_index_name ($top_index_rows Rows - ${top_index_mb} MB)"); } exit; } # -------------------------------------------------------------------- # -tp # -------------------------------------------------------------------- if ($arg eq "-tp") { if ($arg2 eq "top") { $orderby = "6 desc"; } else { $orderby = "2,3,4"; } &msg("-tp: Largest Objects"); &msg("Non-SYS Objects (From DBA_SEGMENTS)"); $sqlstmt = " select \'W\', sum(blocks) from dba_segments where owner not in ('SYS','SYSTEM'); select \'Y\', name, value from v\\\$parameter where name in (\'db_block_size\',\'db_block_buffers\'); select \'X\', owner, segment_name, translate(segment_type,' ','_'), tablespace_name, nvl(blocks,-1), buffer_pool from dba_segments where owner not in ('SYS','SYSTEM') order by $orderby ;"; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "Owner.Object ObjectType TableSpace Buf-Pool Blocks MBytes %OfTot\n"; print "---------------------------------------- ---------- -------------- -------- --------- -------- ------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "W") { $sumblocks = $words[1]; ##print "sumblocks=$sumblocks\n"; } if ($verb eq "Y") { if ($words[1] eq "db_block_size") { $bs = $words[2]; ##print "bs=$bs\n"; } } if ($verb eq "X") { $owner = $words[1]; $name = $words[2]; $type = $words[3]; $ts = $words[4]; $blks = $words[5]; $bp = $words[6]; $type = "INDXPART" if $type eq "INDEX_PARTITION"; $type = "TABLPART" if $type eq "TABLE_PARTITION"; $obj = $owner . "." . $name; $found_obj++; $mb = int(($bs * $blks) / 1000000); $total_blks += $blks; $pct = ""; if ($blks > 0 && $sumblocks > 0) { $pct = ($blks / $sumblocks) * 100; $pct = sprintf("%4.1f",$pct); $total_pct += $pct; } printf("%-40s %-10s %-14s %-8s %9d %8d %6s\n",$obj,$type,$ts,$bp,$blks,$mb,$pct); if ($bp eq "DEFAULT") { $def_total += $mb; $def_blks += $blks; } elsif ($bp eq "KEEP") { $kep_total += $mb; $kep_blks += $blks; } elsif ($bp eq "RECYCLE") { $rec_total += $mb; $rec_blks += $blks; } $total_mb += $mb; if ($arg2 eq "top" && $found_obj >= $arg3) { last; } } } print "======================================== ========== ============== ======== ========= ======== ======\n"; printf("%-40s %-10s %-14s %-8s %9d %8d %6s\n","Total:","","","",$total_blks,$total_mb,$total_pct); print "\n"; &msg("$found_obj Objects"); print "\n"; $total_blks = $def_blks + $kep_blks + $rec_blks; &msg("Total Size By Buffer Pool (Sum of Sizes of Above Tables And Indexes):"); print "\n"; print "Buffer Pool Total Size (mB) Total Blks \n"; print "----------- --------------- -----------\n"; printf("%-11s %15d %11d\n","DEFAULT", $def_total, $def_blks); printf("%-11s %15d %11d\n","KEEP", $kep_total, $kep_blks); printf("%-11s %15d %11d\n","RECYCLE", $rec_total, $rec_blks); print "=========== =============== ===========\n"; printf("%-11s %15d %11d\n","Total:", $total_mb,$total_blks); exit; } # -------------------------------------------------------------------- # -nl # -------------------------------------------------------------------- if ($arg eq "-nl") { &msg("-nl: NOLOGGING Objects - Where tablespace_name is not NULL"); $found = 0; $sqlstmt = ' select \'X\', t.owner, t.table_name, nvl(t.logging,\'(Null-L)\'), nvl(t.tablespace_name,\'(Null-TS)\'), o.object_type from dba_tables t, dba_objects o where t.table_name = o.object_name and t.owner = o.owner and t.logging = \'NO\' and t.tablespace_name is not null order by 2,3; select \'X\', i.owner, i.index_name, nvl(i.logging,\'(Null-L)\'), nvl(i.tablespace_name,\'(Null-TS)\') -- o.object_type from dba_indexes i -- dba_objects o where -- i.index_name = o.object_name --and i.owner = o.owner i.logging = \'NO\' and i.tablespace_name is not null order by 2,3; '; print "\n"; print "Owner.Object Object Type TS LOGGING \n"; print "---------------------------------------- -------------------- -------------------- --------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $owner = $words[1]; $obj = $words[2]; $logging = $words[3]; $ts = $words[4]; $objtype = ""; for ($i = 5; $i <= $#words; $i++) { $objtype .= $words[$i]; $objtype .= " "; } $objtype = "INDEX" if $objtype eq ""; $both = $owner . "." . $obj; if ($owner ne "SYS" && $owner ne "SYSTEM") { printf("%-40s %-20s %-20s %-8s\n",$both,$objtype,$ts,$logging); $found++; } } } print "\n"; &msg("Found $found NOLOGGING Objects"); exit; } # -------------------------------------------------------------------- # -in # -------------------------------------------------------------------- if ($arg eq "-in") { $key = '{INDEX}' if $arg2 eq '-key'; if ($arg3 ne "") { $z_owner = (split(/\./,$arg3))[0]; $z_table = (split(/\./,$arg3))[1]; $table_where = " and nx.table_owner = '$z_owner' and nx.table_name = '$z_table'"; } &msg("All Indices (From DBA_SEGMENTS)"); print "\n"; $sqlstmt = "select \'Y\', name, value from v\\\$parameter where name in (\'db_block_size\',\'db_block_buffers\'); select \'X\', sg.owner, sg.segment_name, sg.tablespace_name, sg.blocks, sg.extents, sg.max_extents, nx.status, nx.table_name from dba_segments sg, dba_indexes nx where segment_type = \'INDEX\' and sg.segment_name = nx.index_name and sg.owner = nx.owner $table_where order by 2,3;"; print "Owner.Index TableSpace Blocks MB Xtents MaxXtnt Status\n"; print "----------------------------------------- ------------ ------ ------ ------ -------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Y") { if ($words[1] eq "db_block_size") { $bs = $words[2]; ##print "bs=$bs\n"; } } if ($verb eq "X") { $owner = $words[1]; $table = $words[2]; $ts = $words[3]; $blks = $words[4]; $exts = $words[5]; $maxx = $words[6]; $stat = $words[7]; $tbl = $words[8]; $mb = ($blks * $bs) / (1024 * 1024); if ($maxx == 2147483645) { $maxx = "(Unlim)"; } $t = $owner . "." . $table; if (substr($owner,0,3) ne "SYS") { printf("%-41s %-12s %6d %6d %6d %8s %-10s $key\n",$t,$ts,$blks,$mb,$exts,$maxx,$stat); $found++; $tot_mb += $mb; $tot_xt += $exts; } } } print "========================================= ============ ====== ====== ====== ======== ==========\n"; printf "(%6s Total Indexes) %6d %6d\n\n",$found,$tot_mb,$tot_xt; exit; } # -------------------------------------------------------------------- # -ve # -------------------------------------------------------------------- if ($arg eq "-ve") { &msg("Running dbverify on all datafiles"); $sqlstmt = ' select \'Y\', name, value from v\$parameter where name in (\'db_block_size\'); select \'W\', count(*) from dba_data_files; select \'X\', file_name from dba_data_files order by 2;'; $num_ok = 0; $num_ng = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "W") { $datafiles_tot = $words[1]; &msg("Total datafiles=$datafiles_tot"); } if ($verb eq "Y") { if ($words[1] eq "db_block_size") { $bs = $words[2]; ##print "bs=$bs\n"; } } if ($verb eq "X") { $dfname = $words[1]; $dfcount++; $pct = int(($dfcount / $datafiles_tot) * 100); &msg("Running dbverify on datafile=$dfname - $dfcount of $datafiles_tot - ${pct}%"); $rc = system("dbv file=$dfname blocksize=$bs"); $num_ok++ if $rc == 0; $num_ng++ if $rc != 0; if ($rc != 0) { push @failed,"dbv Failed for datafile=$dfname"; } } } print "\n"; &msg("Number of datafiles that Do exhibit dbv errors: $num_ng "); &msg("Number of datafiles that Do Not exhibit dbv errors: $num_ok "); foreach (@failed) { &msg("dbv Errors seen for datafile=$_"); } exit; } # -------------------------------------------------------------------- # -ba # -------------------------------------------------------------------- if ($arg eq "-ba") { &msg("Contents of DBAMON.BACKUP_AGE"); print "\n"; print "SID Level Timestamp DBSize Elapsed Age(Days)\n"; print "-------- ---------- ------------------- -------- -------- ----------\n"; $now = time; $sqlstmt = 'select \'Y\', SID, BCKLEVEL, TSNUM, TSTEXT, DBSIZE, ELAPSED from dbamon.backup_age order by 5;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Y") { $sid = $words[1]; $level = $words[2]; $tsnum = $words[3]; $tstext = $words[4]; $dbsize = $words[5]; $elapsed = $words[6]; $age = ($now - $tsnum) / (60*60*24); printf("%-8s %-10s %-16s %8d %8d %10d \n",$sid,$level,$tstext,$dbsize,$elapsed,$age); } } print "======== ========== =================== ======== ======== ==========\n"; exit; } # -------------------------------------------------------------------- # -ta # -------------------------------------------------------------------- if ($arg eq "-ta") { $tablekey = '{TABLE}' if $arg2 eq '-key'; if ($arg3 ne "") { $z_owner = (split(/\./,$arg3))[0]; $z_table = (split(/\./,$arg3))[1]; $table_where = " and owner = '$z_owner' and segment_name = '$z_table'"; } &msg("All Tables (From DBA_SEGMENTS) Except SYS and SYSTEM Tables"); print "\n"; print "Owner.Table TableSpace Blocks MB Xtents MaxXtnt\n"; print "----------------------------------------- ------------ ------ ------ ------ --------\n"; $sqlstmt = "select \'Y\', name, value from v\\\$parameter where name in (\'db_block_size\',\'db_block_buffers\'); select \'X\', owner, segment_name, tablespace_name, blocks, extents, max_extents from dba_segments where segment_type = \'TABLE\' $table_where order by 2,3;"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Y") { if ($words[1] eq "db_block_size") { $bs = $words[2]; ##print "bs=$bs\n"; } } if ($verb eq "X") { $owner = $words[1]; $table = $words[2]; $ts = $words[3]; $blks = $words[4]; $exts = $words[5]; $maxx = $words[6]; $mb = ($blks * $bs) / (1024 * 1024); if ($maxx == 2147483645) { $maxx = "(Unlim)"; } $t = $owner . "." . $table; #if (substr($owner,0,3) ne "SYS") if (($owner eq "SYS" || $owner eq "SYSTEM") && $arg2 ne "ALL") { next; } printf("%-41s %-12s %6d %6d %6d %8s $tablekey\n",$t,$ts,$blks,$mb,$exts,$maxx); $found++; $tot_mb += $mb; $tot_xt += $exts; } } print "========================================= ============ ====== ====== ====== ========\n"; printf "(%6s Total Tables) %6d %6d\n\n",$found,$tot_mb,$tot_xt; exit; } # -------------------------------------------------------------------- # -bk # -------------------------------------------------------------------- if ($arg eq "-bk") { open(BK,"grep -v '^#' /opt/oracle/adm/config/*.sched | grep $os |") || die "Cannot OPEN backup schedules"; while () { #print; $found = 1; @words = split(/:/); $sched = $words[0]; ###$thedb = $words[1]; $bkfiles = $words[2]; $when = $words[3]; print "Schedule: $sched\n"; print "Backup File(s): $bkfiles\n"; print "When: $when\n"; } close(BK); if (!$found) { print "orastat | No Backup Definitions Found For ORACLE_SID=$os\n"; } exit; } # -------------------------------------------------------------------- # -ud # -------------------------------------------------------------------- if ($arg eq "-ud") { &msg("Users granted the DBA role"); $sqlstmt = 'select \'X\', grantee from dba_role_privs where granted_role = \'DBA\' order by 2;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $user = $words[1]; print "$user\n"; } } exit; } # -------------------------------------------------------------------- # -ro # -------------------------------------------------------------------- if ($arg eq "-ro") { &msg("Roles"); $sqlstmt = 'select \'X\', role from dba_roles order by 1;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $role = $words[1]; print "$role\n"; $count++; } } &msg("Found $count roles"); exit; } # -------------------------------------------------------------------- # -po # -------------------------------------------------------------------- if ($arg eq "-po") { &msg("Performance: I/O Stats"); $sqlstmt = 'select \'X\', avg(lstiotim)*10 from v\$filestat where lstiotim != 65535;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $num = $words[1]; $num = sprintf("%8.1f",$num); print "Average_Most_Recent_Datafile_I/O_Wait_Time: $num (MS)\n"; } } exit; } # -------------------------------------------------------------------- # -pp # -------------------------------------------------------------------- if ($arg eq "-pp") { &msg("Performance: I/O Stats - Datafile/Tempfile I/O Service Time"); print " MR I/O \n"; print "Datafile Time (MS)\n"; print "-------------------------------------------------- ---------\n"; $sqlstmt = ' select \'X\', d.name, f.lstiotim*10 from v\$filestat f, v\$datafile d where f.file# = d.file# and lstiotim > 0 and lstiotim != 65535 union all select \'X\', d.name, f.lstiotim*10 from v\$tempstat f, v\$tempfile d where f.file# = d.file# and lstiotim > 0 and lstiotim != 65535 order by 3 ;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $df = $words[1]; $num = $words[2]; printf "%-50s %9s\n",$df,$num; } } exit; } # -------------------------------------------------------------------- # -pi # -------------------------------------------------------------------- if ($arg eq "-pi") { &msg("Performance - I/O Distribution"); print "\n"; $stars = "**********"; $gt = 0; $sqlstmt = ' select \'Y1\', sum(phyblkrd + phyblkwrt) from v\$filestat; select \'Y2\', sum(phyblkrd + phyblkwrt) from v\$tempstat; select \'X\', d.name filename, f.phyblkrd blocks_r, f.phyblkwrt block_w, f.phyblkrd + f.phyblkwrt total_io from v\$filestat f, v\$datafile d where f.file# = d.file# union all select \'X\', d.name filename, f.phyblkrd blocks_r, f.phyblkwrt block_w, f.phyblkrd + f.phyblkwrt total_io from v\$tempstat f, v\$tempfile d where f.file# = d.file# order by 5 desc; '; print " Pct Of\n"; print " 1000's 1000's 1000's DB I/O\n"; print "Datafile Reads Writes R+W Total\n"; print "------------------------------------------------------------ ------ ------ ------ ------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split; $verb = $words[0]; if ($verb eq "Y1" || $verb eq "Y2") { $gt += int($words[1]/1000); } if ($verb eq "X") { $df = $words[1]; $r = int($words[2]/1000); $w = int($words[3]/1000); $t = int($words[4]/1000); $pct = $t / $gt * 100; $pct1 = int($t / $gt * 10) + 1; $hist = substr($stars,0,$pct1); printf "%-60s %6d %6d %6d %5.2f%% %-10s\n",$df,$r,$w,$t,$pct,$hist; $t_r += $r; $t_w += $w; $t_t += $t; } } printf " ====== ====== ======\n"; printf "(Total): %6d %6d %6d\n",$t_r, $t_w, $t_t; exit; } # -------------------------------------------------------------------- # -pa # -------------------------------------------------------------------- if ($arg eq "-pa") { &msg("Performance - I/O Distribution - By Tablespace"); print "\n"; $stars = "**********"; $gt = 0; $sqlstmt = ' select \'Y1\', sum(phyblkrd + phyblkwrt) from v\$filestat; select \'Y2\', sum(phyblkrd + phyblkwrt) from v\$tempstat; select \'X\', t.name, d.name, f.phyblkrd, f.phyblkwrt from v\$filestat f, v\$datafile d, v\$tablespace t where f.file# = d.file# and d.ts# = t.ts# union all select \'X\', t.name, d.name, f.phyblkrd, f.phyblkwrt from v\$tempstat f, v\$tempfile d, v\$tablespace t where f.file# = d.file# and d.ts# = t.ts# order by 2, 1; '; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Y1" || $verb eq "Y2") { $gt += int($words[1]/1000); } if ($verb eq "X") { $ts = $words[1]; $df = $words[2]; $r = int($words[3]/1000); $w = int($words[4]/1000); if ($ts =~ /X$/) { $tscat = "Index"; } elsif ($ts =~ /INDEX/) { $tscat = "Index"; } elsif ($ts =~ /SYSTEM/) { $tscat = "System"; } elsif ($ts =~ /RBS/) { $tscat = "Undo"; } elsif ($ts =~ /UNDO/) { $tscat = "Undo"; } elsif ($ts =~ /TEMP/) { $tscat = "Temp"; } elsif ($ts =~ /^P/) { $tscat = "Purge"; } else { $tscat = "Other"; } ##print "ts=$ts df=$df r=$r w=$w\n"; $tstotal_r{$ts} += $r; $tstotal_w{$ts} += $w; $tstotal_cat{$ts} = $tscat; $cats_r{$tscat} += $r; $cats_w{$tscat} += $w; ##print " tstotal_r{$ts}=$tstotal_r{$ts} tstotal_w{$ts}=$tstotal_w{$ts}\n"; ##print " cats_r{$tscat}=$cats_r{$tscat} cats_w{$tscat}=$cats_w{$tscat}\n"; } } $t_r = 0; $t_w = 0; $t_t = 0; print " Pct Of\n"; print " 1000's 1000's 1000's DB I/O\n"; print "Category Reads Writes R+W Total\n"; print "-------- ------------ ------------ ------------ -------\n"; foreach $tscat (sort keys %cats_r) { $t = $cats_r{$tscat} + $cats_w{$tscat}; $pct = $t / $gt * 100; $pct1 = (int(($t / $gt) * 100)) / 5 + 1; $hist = '*' x $pct1; printf "%-8s %12d %12d %12d %6.2f%% %-10s\n",$tscat,$cats_r{$tscat},$cats_w{$tscat},$t,$pct,$hist; $t_r += $cats_r{$tscat}; $t_w += $cats_w{$tscat}; $t_t += $t; } print " ============ ============ ============\n"; printf "(Total): %12d %12d %12d\n",$t_r, $t_w, $t_t; $t_r = 0; $t_w = 0; $t_t = 0; print "\n"; print " Pct Of\n"; print " 1000's 1000's 1000's DB I/O\n"; print "Tablespace Category Reads Writes R+W Total\n"; print "------------------------ -------- ------------ ------------ ------------ -------\n"; foreach $ts (sort keys %tstotal_r) { $t = $tstotal_r{$ts} + $tstotal_w{$ts}; $pct = $t / $gt * 100; $pct1 = (int(($t / $gt) * 100)) / 5 + 1; $hist = '*' x $pct1; printf "%-24s %-8s %12d %12d %12d %6.2f%% %-10s\n",$ts,$tstotal_cat{$ts},$tstotal_r{$ts},$tstotal_w{$ts},$t,$pct,$hist; $t_r += $tstotal_r{$ts}; $t_w += $tstotal_w{$ts}; $t_t += $t; } print " ============ ============ ============\n"; printf "(Total): %12d %12d %12d\n",$t_r, $t_w, $t_t; exit; } # -------------------------------------------------------------------- # -tj # -------------------------------------------------------------------- if ($arg eq "-tj") { $len = $arg2; $len = 22 if $len eq ""; &msg("-tj: Datafile Bytes Allocated By Filesystem - len=$len"); print "\n"; $sqlstmt = " drop table orastat_tj; create global temporary table orastat_tj as select name, bytes from v\\\$datafile; insert into orastat_tj select name, bytes from v\\\$datafile; insert into orastat_tj select name, bytes from v\\\$tempfile; select \'X\', substr(name,1,$len), sum(bytes) from orastat_tj group by substr(name,1,$len) order by 2 ;"; ##print "sqlstmt=$sqlstmt\n"; print "Filesystem mB Alloc.\n"; print "------------------------------------------------------------ ---------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print if /^ORA/; ##print; @words = split; $verb = $words[0]; if ($verb eq "X") { $fs = $words[1]; $mb = int($words[2]/1000000); printf "%-60s %9d\n",$fs,$mb; $t_mb += $mb; } } printf " =========\n"; printf "(Total): %9d\n",$t_mb; exit; } # -------------------------------------------------------------------- # -pj # -------------------------------------------------------------------- if ($arg eq "-pj") { $len = $arg2; $len = 22 if $len eq ""; &msg("-pj: Performance - I/O Distribution By Filesystem - len=$len"); print "\n"; $gt = 0; $stars = "**********"; $sqlstmt = " select \'Y1\', sum(phyblkrd + phyblkwrt) from v\\\$filestat; select \'Y2\', sum(phyblkrd + phyblkwrt) from v\\\$tempstat; select \'X\', substr(d.name,1,$len), sum(f.phyblkrd), sum(f.phyblkwrt), sum(f.phyblkwrt + f.phyblkrd) from v\\\$filestat f, v\\\$datafile d where f.file# = d.file# group by substr(d.name,1,$len) union all select \'X\', substr(d.name,1,$len), sum(f.phyblkrd), sum(f.phyblkwrt), sum(f.phyblkwrt + f.phyblkrd) from v\\\$tempstat f, v\\\$tempfile d where f.file# = d.file# group by substr(d.name,1,$len) order by 5 desc; "; print " Pct Of\n"; print " 1000's 1000's 1000's DB I/O\n"; print "Filesystem Reads Writes R+W Total\n"; print "------------------------------------------------------------ --------- --------- --------- ------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split; $verb = $words[0]; if ($verb eq "Y1" || $verb eq "Y2") { $gt += int($words[1]/1000); } if ($verb eq "X") { $fs = $words[1]; $r = int($words[2]/1000); $w = int($words[3]/1000); $t = int($words[4]/1000); $pct = $t / $gt * 100; $pct1 = int($t / $gt * 10) + 1; $hist = substr($stars,0,$pct1); printf "%-60s %9d %9d %9d %5.2f%% %-10s\n",$fs,$r,$w,$t,$pct,$hist; $t_r += $r; $t_w += $w; $t_t += $t; } } printf " ========= ========= =========\n"; printf "(Total): %9d %9d %9d\n",$t_r, $t_w, $t_t; exit; } # -------------------------------------------------------------------- # -pk # -------------------------------------------------------------------- if ($arg eq "-pk") { &msg("-pk: Performance - I/O Distribution By Tablespace"); print "\n"; $stars = "**********"; $sqlstmt = " select \'Y\', sum(phyblkrd + phyblkwrt), sum(phyblkrd), sum(phyblkwrt) from v\\\$filestat; select \'Z\', sum(phyblkrd + phyblkwrt), sum(phyblkrd), sum(phyblkwrt) from v\\\$tempstat; select \'X\', t.name, sum(f.phyblkrd), sum(f.phyblkwrt), sum(f.phyblkwrt + f.phyblkrd) from v\\\$filestat f, v\\\$datafile d, v\\\$tablespace t where f.file# = d.file# and d.ts# = t.ts# group by t.name union all select \'X\', t.name, sum(f.phyblkrd), sum(f.phyblkwrt), sum(f.phyblkwrt + f.phyblkrd) from v\\\$tempstat f, v\\\$tempfile d, v\\\$tablespace t where f.file# = d.file# and d.ts# = t.ts# group by t.name order by 5 desc ;"; print " % Of % Of % Of\n"; print " 1000's 1000's 1000's Read Write R+W\n"; print "Tablespace Reads Writes R+W Total Total Total\n"; print "-------------------- --------- --------- --------- ------ ------ ------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split; $verb = $words[0]; if ($verb eq "Y") { $gt = int($words[1]/1000); $gt_r = int($words[2]/1000); $gt_w = int($words[3]/1000); } if ($verb eq "Z") { $gt += int($words[1]/1000); $gt_r += int($words[2]/1000); $gt_w += int($words[3]/1000); } if ($verb eq "X") { ##print "gt_r=$gt_r gt_w=$gt_w gt=$gt\n"; $ts = $words[1]; $r = int($words[2]/1000); $w = int($words[3]/1000); $t = int($words[4]/1000); $pct = $t / $gt * 100; $pct1 = int($t / $gt * 10) + 1; $hist = substr($stars,0,$pct1); $pct_r = $r / $gt_r * 100; $pct_w = $w / $gt_w * 100; printf "%-20s %9d %9d %9d %5.2f%% %5.2f%% %5.2f%% %-10s\n",$ts,$r,$w,$t,$pct_r,$pct_w,$pct,$hist; $t_r += $r; $t_w += $w; $t_t += $t; } } printf " ========= ========= =========\n"; printf "(Total): %9d %9d %9d\n",$t_r, $t_w, $t_t; exit; } # -------------------------------------------------------------------- # -pd # -------------------------------------------------------------------- if ($arg eq "-pd") { $sqlstmt = ' select \'X\', sum(decode(name, \'consistent gets\', value, 0)) consistent, sum(decode(name, \'db block gets\', value, 0)) db_blockgets, sum(decode(name, \'physical reads\', value, 0)) physical, round(((sum(decode(name, \'consistent gets\', value, 0)) + sum(decode(name, \'db block gets\', value, 0)) - sum(decode(name, \'physical reads\', value, 0))) / (sum(decode(name, \'consistent gets\', value, 0)) + sum(decode(name, \'db block gets\', value, 0)))) * 100, 2) hitratio from v\$sysstat; select \'Y\', name, value from v\$parameter where name in (\'db_block_size\',\'db_block_buffers\',\'db_cache_size\'); select \'V\', round((sum(gethits) / sum(gets) * 100),2) from v\$librarycache; select \'U\', round((sum(gets) - sum(getmisses)) / sum(gets) * 100,2) from v\$rowcache; select \'W\', name, 100* (1-(physical_reads / (DB_BLOCK_GETS + CONSISTENT_GETS))), set_msize from v\$buffer_pool_statistics where (db_block_gets + consistent_gets) > 0 order by 1; select \'Z\', 100* (1-(sum(physical_reads) / (sum(DB_BLOCK_GETS) + sum(CONSISTENT_GETS)))) from v\$buffer_pool_statistics where (db_block_gets + consistent_gets) > 0 and name != \'RECYCLE\' order by 1; '; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split; $verb = $words[0]; if ($verb eq "Z") { $cachehit_x_recycle = $words[1]; } if ($verb eq "V") { printf "Library Cache Hit Ratio: %7.2f%\n",$words[1]; } if ($verb eq "U") { printf "Dictionary Cache Hit Ratio: %7.2f%\n\n",$words[1]; } if ($verb eq "X") { &msg("Data Block Buffer Hit Ratio Data"); print "\n"; ##print "$words[1]\n"; printf "Consistent Gets: %15s\n",$words[1]; printf "DB Block Gets: %15s\n",$words[2]; printf "Physical Reads: %15s\n",$words[3]; printf "\nData Block Buffer Hit Ratio:%7.2f%\n",$words[4]; $db_block_gets = $words[2]; if ($db_block_gets =~ /1844/) { print "\n"; print "*****************************************************************************\n"; print " NOTE: db_block_gets value of $db_block_gets is invalid due to an\n"; print " Oracle bug. Therefore, the above Data Block Buffer Hit Ratio is\n"; print " invalid. The 8i+ Pool Hit Ratio numbers below are more accurate.\n"; print "*****************************************************************************\n"; print "\n"; } } if ($verb eq "Y") { if ($words[1] eq "db_block_size") { $bs = $words[2]; } if ($words[1] eq "db_block_buffers") { $bb = $words[2]; } if ($words[1] eq "db_cache_size") { $bc = $words[2]; } } if ($verb eq "W") { $pl = $words[1]; $ph = sprintf("%6.2f",$words[2]); $ps = int(($words[3]*$bs) / 1000000); printf "DB_BLOCK_BUFFER Read Hit Ratio - Pool: %-8s Hit_Ratio: %6.2f Pool_Size: %5s (MB)\n",$pl,$ph,$ps; } } print "\n"; printf "DB Block Size: %10d\n",$bs; if ($bb > 0) { printf "DB Block Buffers: %10d\n\n",$bb; $cache_mem = $bs*$bb/1000000; } elsif ($bc > 0) { printf "db_cache_size: %10.0f\n\n",$bc; $cache_mem = $bc/1000000; } printf "Total DB Block Buffer Size: %5d(MB) (This Oracle Instance)\n",$cache_mem; $shmused = `$toolsdir/shmem | grep '(Total)' | awk '{ print \$2 }'`; chop $shmused; $shmused = $shmused / 1000000; #$shmfree = 1700-$shmused; printf "Server Shared Memory Used: %5d(MB) (Entire Server)\n",$shmused; printf "DB Cache Hit Ratio: %7.2f%% (Excluding RECYCLE Pool)\n",$cachehit_x_recycle; #printf " Server Shared Memory Free: %5d(MB) (Approximate)\n\n",$shmfree; exit; } # -------------------------------------------------------------------- # -sh # -------------------------------------------------------------------- if ($arg eq "-sh") { &msg("-sh: Shared Pool Hit/Miss Info/Recommendations"); $sqlstmt = ' select \'Y\', name, value from v\$parameter where name in (\'db_block_size\',\'db_block_buffers\'); select \'T\', sum(reloads) / sum(pins) from v\$librarycache; select \'V\', sum(gethits) / sum(gets) from v\$librarycache; select \'U\', sum(getmisses) / sum(gets) from v\$rowcache; '; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split; $verb = $words[0]; if ($verb eq "T") { $pin_miss_ratio = $words[1] * 100; $pin_miss_ratio = sprintf("%6.2f",$pin_miss_ratio); if ($pin_miss_ratio >= 1) { $rec .= " (LC) Since the Library Cache reloads/pins ratio of $pin_miss_ratio exceeds 1%, you should increase the init.ora shared_pool_size parameter.\n"; } } if ($verb eq "V") { $lc_hit_ratio = $words[1] * 100; $lc_hit_ratio = sprintf("%6.2f",$lc_hit_ratio); if ($lc_hit_ratio < 90) { $rec .= " (LC) Since the Library Cache hit ratio $lc_hit_ratio is < 90%, you should increase the init.ora shared_pool_size parameter.\n"; } } if ($verb eq "U") { $dc_miss_ratio = $words[1] * 100; $dc_miss_ratio = sprintf("%6.2f",$dc_miss_ratio); if ($dc_miss_ratio >= 15) { $rec .= " (DC) Since the Dictionary Cache hit ratio $dc_miss_ratio is >= 15%%, you should increase the init.ora shared_pool_size parameter.\n"; } } if ($verb eq "Y") { if ($words[1] eq "db_block_size") { #$db_block_size = $words[2]; } if ($words[1] eq "db_block_buffers") { #$db_block_buffers = $words[2]; } } } print "\n"; printf "Library Cache Reloads/Pins Ratio: %6s%% (S/B < 1%)\n",$pin_miss_ratio; printf "Library Cache Hit Ratio: %6s%% (S/B >= 90%)\n",$lc_hit_ratio; printf "Dictionary Cache Miss Ratio: %6s%% (S/B < 15%)\n",$dc_miss_ratio; print "\n"; print "Recommendations:\n"; print $rec; print "(None)" if $rec eq ""; print "\n"; exit; } # -------------------------------------------------------------------- # -l # -------------------------------------------------------------------- if ($arg eq "-l") { &msg("-l: Archive Log Status"); &oraSQL(" set time off host echo 'Running archive log list' archive log list; "); print "\n"; foreach (@oraSQLout) { s/SQL> //g; s/SVRMGR> //g; print if $_ !~ /^$/; @words = split; $verb = $words[0]; if (/Database log mode/) { $arclogmode = $words[3] . $words[4]; } if (substr($_,0,18) eq "Automatic archival") { $arcauto = $words[2]; } if (substr($_,0,19) eq "Archive destination") { $arcdirraw = $words[2]; } } # Fix - bb - svrmgrl lists arcdest2 if it exists - we don't # want that, so we will get the first disk dest from orastat -ad chop($arcdirnew = `orastat -ad | grep ' /' | head -1 | awk '{ print \$NF }'`); ##print "arcdirnew=$arcdirnew\n"; if ($arcdirraw ne $arcdirnew && $arcdirnew ne "" && $arcdirnew =~ /^\//) { &msg("Overriding arcdirraw=$arcdirraw with $arcdirnew"); $arcdirraw = $arcdirnew; } # if the 1st char of arcdirraw is ?, then xlate it to oracle_home #if (substr($arcdirraw,0,1) eq "?") if ($arcdirraw =~ /\?/) { $arcdirraw =~ s/\?/$oh/; print "$P | arcdirraw Promoted from ?... to $arcdirraw \n"; } # Cut off last level of (example) /oracle/PD1/saparch/PD1arch, # only if the last char is NOT a SLASH $lastchar = substr($arcdirraw,length($arcdirraw)-1); $z = -e $arcdirraw; ##print "lastchar=$lastchar z=$z\n"; print "\n"; if ($lastchar ne "/" && $z == 0) { @words = split(/\//,$arcdirraw); $numlevels = $#words - 1; $arcdir = ""; for ($i = 1; $i <= $numlevels; $i++) { $arcdir = $arcdir . "/" . $words[$i]; } } else { $arcdir = $arcdirraw; } if ($arcdirraw eq "USE_DB_RECOVERY_FILE_DEST") { &msg("arcdirraw=$arcdirraw - Archivelog Dest uses FRA"); chop($arcfs = `orastat -cp | grep -i 'DB_RECOVERY_FILE_DEST' | head -1 | awk '{ print \$2 }'`); chop($arcdirfull = `orastat -fra | grep 'FRAFULL' | head -1 | awk '{ print \$NF }'`); chop $arcdirfull; #---- Remove % $arcdir = "?"; } elsif ($arcdir =~ /^\+/) { &msg("arcdir=$arcdir uses ASM"); $arcdirfull = "?"; $arcfs = "?"; } elsif ($arcdir ne "") { open(BDF, "$bdfcmd $arcdir | tail -1 |") || &error("Error running $bdfcmd"); while() { ##print; @words = split; $arcdirfull = $words[$#words-1]; $arcfs = $words[$#words]; # Remove the % sign chop $arcdirfull; } close(BDF); } &msg("Archive Dest.: $arcdirraw"); &msg("Archive Log Mode: $arclogmode"); &msg("Auto Archive: $arcauto"); &msg("Archive Dest Dir.: $arcdir"); &msg("Archive Dest FS: $arcfs"); &msg("Archive Dest FS Full: $arcdirfull%"); exit; } # -------------------------------------------------------------------- # -op # -------------------------------------------------------------------- if ($arg eq "-op") { &msg("OPS V\$PING Data - Lock Conversions"); print "Name File Class XNC\n"; print "-------------------- ---------- ---------- ----------\n"; $sqlstmt = ' select \'Z\', name, file#, class#, max(xnc) from v\$ping group by \'Z\', name, file#, class# order by 5;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Z") { $name = $words[1]; $file = $words[2]; $class = $words[3]; $xnc = $words[4]; printf("%-20s %10s %10s %10s\n",$name,$file,$class,$xnc); $total += $xnc } } print "==================== ========== ========== ==========\n"; printf("Total: %9d\n",$total); exit; } # -------------------------------------------------------------------- # -vs # -------------------------------------------------------------------- if ($arg eq "-vs") { &msg("All Views"); print "----------------------------------\n"; $sqlstmt = ' select \'Z\', owner, view_name from dba_views order by 2, 3;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Z") { $owner = $words[1]; $view = $words[2]; $name = "$owner.$view"; print "$name \n"; $total++; } } &msg("Total Number of Views: $total"); exit; } # -------------------------------------------------------------------- # -vw # -------------------------------------------------------------------- if ($arg eq "-vw") { &msg("View Count By Schema"); print "Schema View Count\n"; print "------------------ -----------\n"; $sqlstmt = ' select \'Z\', owner, count(*) from dba_views group by owner;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Z") { $owner = $words[1]; $tbls = $words[2]; printf("%-20s %9d\n",$owner,$tbls); $total += $tbls; } } print "================== ===========\n"; printf("Total: %9d\n",$total); exit; } # -------------------------------------------------------------------- # -tb # -------------------------------------------------------------------- if ($arg eq "-tb") { &msg("Table Count By Schema"); print "Schema Table Count\n"; print "------------------ -----------\n"; $sqlstmt = ' select \'Z\', owner, count(*) from dba_tables group by owner;'; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Z") { $owner = $words[1]; $tbls = $words[2]; printf("%-20s %9d\n",$owner,$tbls); $total += $tbls; } } print "================== ===========\n"; printf("Total: %9d\n",$total); exit; } # -------------------------------------------------------------------- # -an # -------------------------------------------------------------------- if ($arg eq "-an") { @words = split(/\./,$arg2); $owner = uc $words[0]; $table = uc $words[1]; if ($owner eq "" || $table eq "") { print "$P | Usage: $P -an TABLE-OWNER.TABLE-NAME\n"; exit 1; } print "Running ANALYZE TABLE for table $owner.$table\n\n"; open(RO,"$os_scmd <&1 $os_conn analyze table $owner.$table compute statistics for table; select \'Y\', avg_row_len, initial_extent, next_extent, num_rows from dba_tables where table_name = '$table' and owner = '$owner'; !|") || die "Cannot select from $table"; while () { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $rows = $words[1]; } if ($verb eq "Y") { $rowsize = $words[1]; $initial = $words[2]; $next = $words[3]; $rows = $words[4]; print "Current Row Count: $rows\n";; print "Average Row Size (Bytes): $words[1]\n"; print "Initial Extent Size (Bytes): $initial\n"; print "Next Extent Size (Bytes): $next\n"; } } $bytes = ($rowsize * $rows) * 1.25; $meg = int($bytes / (1024*1024)) + 1; print "Calculated Space Reqd. (Bytes): $bytes\n"; print "Calculated Space Reqd. (MB): $meg\n"; exit; } # -------------------------------------------------------------------- # -ti # -------------------------------------------------------------------- if ($arg eq "-ti") { @words = split(/\./,$arg2); $owner = uc $words[0]; $table = uc $words[1]; if ($owner eq "" || $table eq "") { print "$P | Usage: $P -ti TABLE-OWNER.TABLE-NAME\n"; exit 1; } &msg("Table Info for $owner.$table"); # optionally count rows if ($arg3 eq "-count") { $sqlstmt = "select \'X\', count(*) from $owner.$table;"; ##print "sqlstmt=$sqlstmt\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $rows_counted = $words[1]; } } } $sqlstmt = " select \'Y\', value from v\\\$parameter where name = \'db_block_size\'; select \'X\', tablespace_name, nvl(to_char( num_rows),\'(Null)\'), nvl(to_char(last_analyzed,\'YYYY/MM/DD-HH24:MI:SS\'),\'(Null)\'), initial_extent, next_extent, min_extents, max_extents, pct_increase, buffer_pool, nvl(to_char(blocks),\'(Null)\'), freelists, pct_free, ini_trans, max_trans, nvl(to_char(freelist_groups),\'(Null)\'), nvl(logging,\'(Null)\'), avg_row_len from dba_tables where table_name = \'$table\' and owner = \'$owner\';"; ##print "sqlstmt=$sqlstmt\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "Y") { $blocksize = $words[1]; } if ($verb eq "X") { $tblflag = 1; $ts = $words[1]; $numrows = $words[2]; $lastanal = $words[3]; $extinit = $words[4]; $extnext = $words[5]; $extmin = $words[6]; $extmax = $words[7]; $pctincr = $words[8]; $bufpool = $words[9]; $blocks = $words[10]; $freel = $words[11]; $pctfree = $words[12]; $initrans = $words[13]; $maxtrans = $words[14]; $flgrps = $words[15]; $logging = $words[16]; $avgrowl = $words[17]; $mb = int(($blocks * $blocksize) / 1000000); print "\nTable Data (from dba_tables)\n"; print "----------------------------\n"; printf "Tablespace: %-40s\n",$ts; printf "RowCount: %-19s (From ANALYZE)\n",$numrows; printf "LastAnalyzed: %-19s (From ANALYZE)\n",$lastanal; printf "Blocks: %-19s (From ANALYZE)\n",$blocks; printf "TableMegBytes: %-19s (From ANALYZE)\n",$mb; printf "AvgRowLen: %-19s (From ANALYZE)\n",$avgrowl; printf "ActualRows: %-19s (From SELECT COUNT(*))\n",$rows_counted if $rows_counted ne ""; printf "InitialExtents: %-15s\n",$extinit; printf "NextExtents: %-15s\n",$extnext; printf "MinExtents: %-15s\n",$extmin; printf "MaxExtents: %-15s\n",$extmax; printf "PercentIncr: %-15s\n",$pctincr; printf "BufferPool: %-15s\n",$bufpool; printf "Freelists: %-15s\n",$freel; printf "FreelistGroups: %-15s\n",$flgrps; printf "PctFree: %-15s\n",$pctfree; printf "IniTrans: %-15s\n",$initrans; printf "MaxTrans: %-15s\n",$maxtrans; printf "Logging: %-15s\n",$logging; } } if (!$tblflag) { &msg("Table $owner.$table does not exist"); exit 1; } # Column data print "\nColumn Data (from dba_tab_cols)\n"; print "-------------------------------\n"; $sqlstmt = "select \'X\', column_id, column_name, data_type, data_length, nvl(to_char(data_precision),\'(Null)\'), nvl(to_char(data_scale),\'(Null)\'), nvl(nullable,\'(Null)\'), avg_col_len from dba_tab_columns where table_name = \'$table\' and owner = \'$owner\' order by 2;"; ##print "sqlstmt=$sqlstmt\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { #$colflag = 1; $colid = $words[1]; $colname = $words[2]; $coltype = $words[3]; $collen = $words[4]; $colprec = $words[5]; #$colscale = $words[6]; $colnull = $words[7]; #$avg_len = $words[8]; printf "Num: %-2s Name: %-12s Type: %-12s Length: %-4s Precision: %-3s Null: %-3s \n",$colid,$colname,$coltype,$collen,$colprec,$colnull; } } # Index data $index_counter= 0; print "\nIndex Data (from dba_indexes and dba_ind_columns)\n"; print "----------------------------\n"; $sqlstmt = "select \'X\', owner, index_name, tablespace_name, nvl(to_char(last_analyzed, \'YYYY/MM/DD-HH24:MI:SS\'),\'(Null)\'), initial_extent, next_extent, min_extents, max_extents, pct_increase, buffer_pool, nvl(to_char(leaf_blocks),\'(Null)\'), status, freelists, pct_free, ini_trans, max_trans, nvl(to_char(freelist_groups),\'(Null)\'), nvl(logging,\'(Null)\') from dba_indexes where table_name = \'$table\' and table_owner = \'$owner\';"; ##print "sqlstmt=$sqlstmt\n"; &oraSQL($sqlstmt); @oraSQLoutsave1 = @oraSQLout; $ndx_count = 0; foreach (@oraSQLoutsave1) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $ndx_count++; $ndx_owner = $words[1]; $ndx_name = $words[2]; $ts = $words[3]; $lastanal = $words[4]; $extinit = $words[5]; $extnext = $words[6]; $extmin = $words[7]; $extmax = $words[8]; $pctincr = $words[9]; $bufpool = $words[10]; $leafblks = $words[11]; $ndxstatus = $words[12]; $freelists = $words[13]; $pctfree = $words[14]; $initrans = $words[15]; $maxtrans = $words[16]; $flgrps = $words[17]; $logging = $words[18]; $ndx = "$ndx_owner.$ndx_name"; $index_counter++; print "Index $index_counter: $ndx\n"; printf " IndexStatus: %-40s\n",$ndxstatus; printf " Tablespace: %-40s\n",$ts; printf " LastAnalyzed: %-19s (From ANALYZE)\n",$lastanal; printf " LeafBlocks: %-19s (From ANALYZE)\n",$leafblks; printf " InitialExtents: %-15s\n",$extinit; printf " NextExtents: %-15s\n",$extnext; printf " MinExtents: %-15s\n",$extmin; printf " MaxExtents: %-15s\n",$extmax; printf " PercentIncr: %-15s\n",$pctincr; printf " BufferPool: %-15s\n",$bufpool; printf " Freelists: %-15s\n",$freelists; printf " FreelistGroups: %-15s\n",$flgrps; printf " PctFree: %-15s\n",$pctfree; printf " IniTrans: %-15s\n",$initrans; printf " MaxTrans: %-15s\n",$maxtrans; printf " Logging: %-15s\n",$logging; $sqlstmt = "select \'X\', column_position, column_name, column_length, descend from dba_ind_columns where index_name = \'$ndx_name\' and index_owner = \'$ndx_owner\' order by 2;"; ##print "sqlstmt=$sqlstmt\n"; print "\n"; &oraSQL($sqlstmt); @oraSQLoutsave2 = @oraSQLout; foreach (@oraSQLoutsave2) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $colpos = $words[1]; $colname = $words[2]; $collen = $words[3]; $coldesc = $words[4]; printf " Index Column - Number: %-4s Name: %-15s Length: %-4s Descending: %-4s\n",$colpos,$colname, $collen, $coldesc; } } print "\n"; } } &msg("Found $ndx_count Indexes"); exit; } # -------------------------------------------------------------------- # -td # -------------------------------------------------------------------- if ($arg eq "-td") { if ($arg2 eq "") { print "$P | Usage: $P -td TABLE-OWNER.TABLE-NAME\n"; exit 1; } &msg("Describe table $arg2"); $sqlstmt = " set linesize 80 desc $arg2;"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print; } exit; } # -------------------------------------------------------------------- # -ls # -------------------------------------------------------------------- if ($arg eq "-ls") { &msg("Listener Status"); system("lsnrctl status 2>&1"); system("lsnrctl dbsnmp_status 2>&1"); exit; } # -------------------------------------------------------------------- # -sl # -------------------------------------------------------------------- if ($arg eq "-sl") { &msg("select * from $arg2"); &oraSQL("select * from $arg2;"); foreach (@oraSQLout) { print; } exit; } # -------------------------------------------------------------------- # -lo # -------------------------------------------------------------------- if ($arg eq "-lo") { &msg("-lo: Table Locks"); $sqlstmt = ' alter session set optimizer_goal=RULE; select \'X\', nvl(S.USERNAME,\'Internal\') username, nvl(S.TERMINAL,\'None\') terminal, L.SID||\',\'||S.SERIAL# Kill, U1.NAME||\'.\'||substr(T1.NAME,1,20) tab, decode(L.LMODE,1,\'No_Lock\', 2,\'Row_Share\', 3,\'Row_Exclusive\', 4,\'Share\', 5,\'Share_Row_Exclusive\', 6,\'Exclusive\',null) lmode, decode(L.REQUEST,1,\'No_Lock\', 2,\'Row_Share\', 3,\'Row_Exclusive\', 4,\'Share\', 5,\'Share_Row_Exclusive\', 6,\'Exclusive\',null) request from V\$LOCK L, V\$SESSION S, SYS.USER\$ U1, SYS.OBJ\$ T1 where L.SID = S.SID and T1.OBJ# = decode(L.ID2,0,L.ID1,L.ID2) and U1.USER# = T1.OWNER# and S.TYPE != \'BACKGROUND\' order by 2,3,6;'; ##print "sqlstmt=$sqlstmt\n"; print "\n"; print "User Term Sess,Ser Table Lock Held Lock Reqd.\n"; print "------------ -------- ---------- ---------------------------- ------------------- -----------------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; @words = split; $verb = $words[0]; if ($verb eq "X") { $user = $words[1]; $term = $words[2]; $sess = $words[3]; $tabl = $words[4]; $held = $words[5]; $reqd = $words[6]; printf "%-12s %-8s %-10s %-28s %-20s %-20s\n", $user,$term,$sess,$tabl,$held,$reqd; $count++; } } print "\n"; if ($count < 1) { &msg("No table locks found"); } exit; } # -------------------------------------------------------------------- # -sq # -------------------------------------------------------------------- if ($arg eq "-sq") { shift @ARGV; foreach $arg (@ARGV) { $sql .= "$arg "; } $sql .= " ; "; &msg("Executing SQL Statement: $sql"); &oraSQL("$sql"); foreach (@oraSQLout) { print; } exit; } # -------------------------------------------------------------------- # -sn # -------------------------------------------------------------------- if ($arg eq "-sn") { print "-sn: Create Oracle Diagnostic SNAPSHOT - Data Saved In UDUMP\n"; system("$os_scmd <<@ 2>&1 $os_conn alter session set max_dump_file_size=unlimited; alter session set events 'immediate trace name systemstate level 10'; !echo 'orastat Sleeping 60' !sleep 60 alter session set events 'immediate trace name systemstate level 10'; !echo 'orastat Sleeping 60' !sleep 60 alter session set events 'immediate trace name systemstate level 10'; !echo 'orastat Done' @"); exit; } # -------------------------------------------------------------------- # -lv # -------------------------------------------------------------------- if ($arg eq "-lv") { if (lc $host eq "phxprd" || lc $host eq "phxdev" || lc $host eq "agmxsv13") { $nonstandard = 1; ## Allow orastat -lv to run on phoenix systems. } # Save BDF list @fss = `$bdfcmd | grep "^/dev"`; open(RO,'vgdisplay -v | grep "LV Name" |') || die "Cannot run vgdisplay"; while () { ##print; @words = split; $verb = $words[0]; $lvol = $words[2]; push(@lvs,$lvol); } close(RO); # Get list of links in /var/opt/oracle/rdisk if ($nonstandard) { @dblinks = `find /oradata* -type l | xargs ll | sed 's/rlvol/lvol/g' | awk '{print \$NF " " \$9}'`; } else { @dblinks = `find /var/opt/oracle/rdisk -type l | xargs ll | sed 's/rlvol/lvol/g' | awk '{ print \$NF " " \$9 }'`; } # Get list of datafiles/redo/ctl @datafiles = `orastat -de | grep CMD | awk '{ print substr(\$0,5) }'`; foreach $lv (@lvs) { $size = `lvdisplay $lv | grep 'LV Size' | awk '{ print \$4 }'`; chop($size); $usage = ""; # Is is used as a FS? foreach $fs (@fss) { if ($fs =~ /^$lv/) { chop($fsraw = substr($fs,49)); $usage = "(FS:$fsraw)"; $totals{"FS Used Space:"} += $size; } } # Is is used as a oracle link? foreach $dblink (@dblinks) { @splitlv = split('/',$lv); @splitlink = split('/',$dblink); $vg = $splitlv[2]; if ("$dblink " =~ /^$lv / || ($splitlink[3] =~ "r$splitlv[3]" && $nonstandard)) { ##print "##HIT## dblink=$dblink lv=$lv\n"; $_ = $dblink; @words = split; $lvol = $words[0]; $link = $words[1]; # Is is used as a datafile $dbusage = ""; foreach $datafile (@datafiles) { ##print "datafile=$datafile link=$link\n"; if ($datafile =~ /^$link/) { $_ = $datafile; @words = split; $dbusage .= $words[2]; $dbusage .= $words[3]; $dbusage .= $words[4]; } } if ($dbusage eq "") { $dbusage = "DBUnused"; } $usage = sprintf("(DBUsage=%-16s DBLink=%-40s)",$dbusage,$link); if ($link) { $vginstances{$vg} .= $splitlink[8] . " " if $vginstances{$vg} !~ /$splitlink[8]/; } if ($lv =~ /\/dev\/vg_ops_1/) { $totals{"DB Used Space - vg_ops_1*:"} += $size; } else { $totals{"DB Used Space - vg_Other: "} += $size; } } } if ($usage eq "") { $usage = "(LVUnused)"; $totals{"Unused Space: "} += $size; $vg_freespace{$vg} += $size; } $vg_total{$vg} += $size; printf "%-22s %6d %-30s\n",$lv,$size,$usage; $totals{"Total Space: "} += $size; } print "\n"; &msg("Totals:"); @sorted = sort keys %totals; foreach (@sorted) { $key = $_; printf "%-22s %6d\n",$key,$totals{$key}; } print "\n"; print "Volume Group Size Used Free Instance(s)\n"; print "------------ -------- -------- -------- --------------------\n"; foreach $thisvg (sort keys %vg_total) { $vgsize = $vg_total{$thisvg}; $vgfree = $vg_freespace{$thisvg}; $vgused = $vgsize - $vgfree; printf "%-12s %8d %8d %8d %-s\n",$thisvg,$vgsize,$vgused,$vgfree,$vginstances{$thisvg}; $t_size += $vgsize; $t_free += $vgfree; $t_used += $vgfree; } print "============ ======== ======== ========\n"; printf "%-12s %8d %8d %8d %-s\n","Total:",$t_size,$t_used,$t_free; exit; } # -------------------------------------------------------------------- # -lw # -------------------------------------------------------------------- if ($arg eq "-lw") { print "-lw: Create Sym Links for 'rdisk' Raw Logical Volumes\n"; # Save BDF list @unusedvols = `orastat -lv | grep '(Unused)' | egrep -v 'vg00|vg01|vg02' | sort | awk '{ print \$1 }'`; #print "num=$#unusedvols\n"; # Find 1st unused disknn name chop($l = `ll -d /var/opt/oracle/rdisk* 2>&1`); if ($l eq "/var/opt/oracle/rdisk* not found") { $highdisk = 0; } else { chop($l = `ll -d /var/opt/oracle/rdisk* | tail -1 | awk '{ print \$NF}'`); $highdisk = substr($l,length($l)-2); } #print "$P | l=$l highdisk=$highdisk\n"; print "$P | Highest Existing rdisk Link=$highdisk\n\n"; foreach $lv (@unusedvols) { chop $lv; ##print "$P | Found unused volume: $lv\n"; $thisdisk = ++$highdisk; if (length($thisdisk) < 2) { $thisdisko = "0" . $thisdisk; } else { $thisdisko = $thisdisk; } $lv =~ s/lvol/rlvol/g; print "ln -s $lv /var/opt/oracle/rdisk$thisdisko\n"; } exit; } # -------------------------------------------------------------------- # -ps & -rac # -------------------------------------------------------------------- if ($arg eq "-ps" || $arg eq "-rac") { &msg("-ps: RAC (OPS) Status"); $sqlstmt = ' select \'X\', status, parallel from v\$instance; select \'Y\', inst_number, inst_name from v\$active_instances; select \'Z\', value, name from v\$dlm_misc;'; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $status = $words[1]; $par = $words[2]; print "\nParallel Server On: $par Instance Status: $status\n"; print "\nInstances in Cluster:\n\n"; print "Node Name\n"; print "======== ==================\n"; } if ($verb eq "Y") { $num = "Node:" . $words[1]; $name = $words[2]; printf "%-7s %-30s\n",$num,$name; } if ($verb eq "Z") { if (!$zflag) { print "\nDLM Statistics:\n\n"; print "Name Value\n"; print "==================================== =========\n"; $zflag = 1; } $value = $words[1]; $name = $words[2] . " " . $words[3] . " " . $words[4] . " " . $words[5] . " " . $words[6]; printf "%-36s %9d\n",$name,$value; } } exit; } # -------------------------------------------------------------------- # -sal # -------------------------------------------------------------------- if ($arg eq "-sal") { if ($arg2 eq "" ) { print "$P | Usage: $P -sal SESSION_NUMBER\n"; exit 1; } $ses = $arg2; #---- Get running SQL print "\nSession SQL:\n"; system("orastat -sr $ses 2>&1 | grep -v 'orastat |'"); #---- Get running SQL print "\nSession Current Wait State:\n"; system("orastat -sw | head -7 | grep -v 'orastat |'"); system("orastat -sw | grep '^$ses ' 2>&1"); print "\nSession Stats:\n"; system("orastat -sc $ses 2>&1 | grep -v 'orastat |'"); print "\n"; &msg("$P | -sal Done"); exit; } # -------------------------------------------------------------------- # -sr # -------------------------------------------------------------------- if ($arg eq "-sr") { if ($arg2 eq "" ) { print "$P | Usage: $P -sr SESSION_NUMBER\n"; exit 1; } &msg("orastat -sr: SQL Session $arg2"); $sql = "select \'X\', sql_hash_value, prev_hash_value from v\\\$session where sid = $arg2 ; "; ##&msg("sql=$sql"); &oraSQL("$sql"); $sql = ""; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = shift(@words); if ($verb eq "X") { &msg("Session $arg2 - SQLHashValue: $words[0] PrevHashValue: $words[1]"); } } &msg("SQL Statement:"); $z = "-" x 80; print "$z \n"; &srSub($arg2); $z = "-" x 80; print "$z \n"; exit; } # -------------------------------------------------------------------- sub srSub # -------------------------------------------------------------------- { $sessionid = $_[0]; $sql = "select \'Z\', sql_text from --v\\\$sqltext_with_newlines v\\\$sqltext where address = (select sql_address from v\\\$session where sid = $sessionid) order by piece; "; #print "sql=$sql \n"; &oraSQL("$sql"); $sql = ""; foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = shift(@words); if ($verb eq "Z") { $foundsql = 1; foreach (@words) { ##print "inword >$_< \n"; $sql .= $_ . " "; $inword = $_; } ##chop $sql; # In some cases, pad with a blank to prevent the last word being joined with the first word of the next line $z = uc $inword; ##print "z=$z \n"; if ($z eq "FROM" || $z eq "AND") { $sql .= " "; } ##print "sql >$sql< \n"; } } # Massage $_ = $sql; s/\n//g; $sql = $_; ##&msg("DEBUG - sql=$sql"); $_ = $sql; $sqlout = ""; @sqlwords = split; foreach (@sqlwords) { $word = $_; ##print "word=$word \n"; $worduc = uc $word; $newlineflag = 0; $newlineflag = 1 if $worduc eq "SELECT" || $worduc eq "FROM" || $worduc eq "ORDER" || $worduc eq "WHERE" || $worduc eq "GROUP" || $worduc eq "FROM" || $worduc eq "UNION"; $sqlout .= "\n" if $newlineflag; $sqlout .= $word; $sqlout .= "\n " if $newlineflag; $sqlout .= " "; } print "$sqlout"; print "\n"; print "Executing SQL for Session: $sessionid Not Found\n" if ! $foundsql; print "\n"; } # -------------------------------------------------------------------- # -ug # -------------------------------------------------------------------- if ($arg eq "-ug") { &msg("-ug: User Grants (Much Output)"); chop($date = `date`); if ($arg2 ne "") { $where = "where grantee = '$arg2'"; } &msg("Date=$date Where=$where"); $sqlstmt = " select \'X\', grantee, owner, table_name, privilege, grantable from dba_tab_privs ${where} order by 1,2,3;"; print "Grantee Table Privilege Grantable?\n"; print "---------------------- ---------------------------------------- ------------ ----------\n"; $count = 0; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $found = 1; $grantee = $words[1]; $owner = $words[2]; $tab = $words[3]; $priv = $words[4]; $gable = $words[5]; $table = $owner . "." . $tab; $count++; printf("%-22s %-40s %-12s %-8s\n",$grantee,$table,$priv,$gable); } } print "\n"; &msg("$count Grants found"); exit; } # -------------------------------------------------------------------- # -ss # -------------------------------------------------------------------- if ($arg eq "-ss") { &msg("-ss: Default Storage Setting - By Tablespace"); $sqlstmt = 'select \'X\', tablespace_name, initial_extent, next_extent, min_extents, max_extents, pct_increase from dba_tablespaces order by tablespace_name;'; print "\n"; print "Tablespace Initial Next Min Max Pct Increase\n"; print "-------------------- ---------- ---------- ---------- ----------- ------------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $found = 1; $ts = $words[1]; $initial = $words[2]; $next = $words[3]; $min = $words[4]; $max = $words[5]; $pct = $words[6]; printf("%-20s %10d %10d %10d %11d %12d\n",$ts,$initial,$next,$min,$max,$pct); } } if (!$found) { &msg("Something is wrong - query returned no rows"); exit 1; } exit; } # -------------------------------------------------------------------- # bp # -------------------------------------------------------------------- if ($arg eq "-bp") { &msg("RMAN Backup Sessions"); $sqlstmt = 'select \'X\', to_char(logon_time, \'DD-MON-YY\'), to_char(logon_time, \'HH24:MM:SS\'), sid,serial#,process,status,module from v\$session where module like \'%backup%\';'; print "Start Date Start Time SID Serial# Process Status Module\n"; print "---------- ---------- ------ --------- -------- ---------- --------------------------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { @words = split(); $verb = $words[0]; $date = $words[1]; $time = $words[2]; $sid = $words[3]; $serial = $words[4]; $process = $words[5]; if ($process eq "ACTIVE" | $process eq "INACTIVE") { $process = "."; $status = $words[5]; } else {$status = $words[6];} $module = $words[7] . " " . $words[8] . " " . $words[9] . " " . $words[10]; if ($verb eq "X") { printf "%9s %9s %8s %9s %8s %10s %s\n", $date, $time, $sid, $serial, $process, $status, $module; } } exit; } # -------------------------------------------------------------------- # sp # -------------------------------------------------------------------- if ($arg eq "-sp") { &msg("StatsPack Data"); $sqlstmt = 'select \'X\', to_char(snap_time, \'YYYY/MM/DD-HH24:MI:SS\'), snap_id, snap_level, sysdate - snap_time from perfstat.stats\$snapshot order by 2;'; print " Snap ID Snap Timestamp Snap Lvl Snap Age (Days)\n"; print "-------- ------------------- -------- ---------------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = $words[0]; if ($verb eq "X") { $ts = $words[1]; $num = $words[2]; $lvl = $words[3]; $age = $words[4]; $age = sprintf("%5.3f",$age); printf "%8s %18s %8s %15.3f\n", $num, $ts, $lvl, $age; } } exit; } # -------------------------------------------------------------------- # lh # -------------------------------------------------------------------- if ($arg eq "-lh" || $arg eq "-lc") { &msg("$arg: Lock Holders/Waiters (?/rdbms/admin/catblock.sql Must Have Been Run)"); $sqlstmt = ' alter session set optimizer_goal=RULE; select \'X\', waiting_session, holding_session, lock_type, mode_held, mode_requested, lock_id1, lock_id2 from dba_waiters order by 1;'; print "\n"; print " Waiting Holding Lock Mode Mode Lock\n"; print " Session Session Type Holding Reqd. ID1 ID2\n"; print "-------- -------- ------------ ------------ ------------ -------------------------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { print if /^ORA/; ##print; @words = split(); $verb = $words[0]; if ($verb eq "X") { $ses_wt = $words[1]; $ses_hld = $words[2]; $lk_type = $words[3]; $mode_hld = $words[4]; $mode_req = $words[5]; $lock_id = "$words[6] $words[7] $words[8] $words[9] $words[10]"; $age = sprintf("%5.1f",$age); printf "%-8s %-8s %-12s %-12s %-12s %s %s \n", $ses_wt, $ses_hld, $lk_type, $mode_hld, $mode_req, $lock_id; $counter++; if ($arg eq "-lc") { print "\n"; print "=== (Start) === Session Details of Holding and Waiting sessions =========\n"; #---- Holding session &lc_display($ses_hld,"Holding"); #---- Waiting session &lc_display($ses_wt,"Waiting"); print "=== (End) ===============================================================\n"; print "\n"; } } } print "\n"; if ($counter < 1) { &msg("No Lock Waiters Found"); } else { &msg("$counter Lock Waiter(s) Found"); } exit; } sub lc_display { $this_sid = $_[0]; $this_what = $_[1]; print "\n"; &msg("SQL running now for $this_what session $this_sid"); system("orastat -sr $this_sid"); print "\n"; &msg("Session Details of $this_what session $this_sid"); system("orastat -se | head -7 | tail -3"); system("orastat -se | grep '^$this_sid,'"); print "\n"; &msg("Wait Status of $this_what session $this_sid"); system("orastat -sw | head -7 | tail -3"); system("orastat -sw | grep '^$this_sid '"); print "\n"; } # -------------------------------------------------------------------- # sb # -------------------------------------------------------------------- if ($arg eq "-sb") { &msg("-sb: Standby DB Log Gaps"); $sqlstmt = ' SELECT \'X\', high.thread#, "LowGap#", "HighGap#"FROM( SELECT thread#, MIN(sequence#)-1 "HighGap#" FROM ( SELECT a.thread#, a.sequence# FROM ( SELECT * FROM v\$archived_log ) a, ( SELECT thread#, MAX(next_change#)gap1 FROM v\$log_history GROUP BY thread# ) b WHERE a.thread# = b.thread# AND a.next_change# > gap1 ) GROUP BY thread#) high,( SELECT thread#, MIN(sequence#) "LowGap#" FROM ( SELECT thread#, sequence# FROM v\$log_history, v\$datafile WHERE checkpoint_change# <= next_change# AND checkpoint_change# >= first_change# ) GROUP BY thread#) low WHERE low.thread# = high.thread# AND "LowGap#" < "LowGap#";'; print " <=Missing Log Range=>\n"; print "Thread Low High\n"; print "------ ---------- ----------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $thread = $words[1]; $lo = $words[2]; $hi = $words[3]; printf "%6s %10s %10s\n", $thread, $lo, $hi; } } exit; } # -------------------------------------------------------------------- # rp # -------------------------------------------------------------------- if ($arg eq "-rp") { &msg("-rp: RMAN Long Operation Progression"); $sqlstmt = ' select \'Y\', value from v\$parameter where name = \'db_block_size\'; select \'Z\', sid, serial#, context, sofar, totalwork, last_update_time - start_time, --round(sofar/totalwork*100,2) "PctComplete", to_char(start_time,\'YYYY/MM/DD-HH24:MI:SS\') , to_char(last_update_time,\'YYYY/MM/DD-HH24:MI:SS\') , opname from v\$session_longops where opname like \'RMAN%\' and opname not like \'RMAN: aggregate%\' --and sofar <> totalwork order by 8, 4;'; print "SID-Ser# Start Last Updated El. Mins GB/Hour Work Sofar Work Total Pct. Done Desc.\n"; print "--------- ------------------- ------------------- -------- -------- ---------- ---------- ---------- ------------------------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; $sid = $words[1]; $ser = $words[2]; #$context = $words[3]; $sofar = $words[4]; $totalwk = $words[5]; $etime = sprintf("%5.1f",$words[6] * (24*60)); $stime = $words[7]; $utime = $words[8]; $opname = $words[9] . $words[10] . $words[11] . $words[12]; if ($totalwk > 0) { $pctcomp = sprintf("%7.3f",($sofar/$totalwk)*100); } else { $pctcomp = "*"; } $totalsize = $blocksize * $sofar; $gbrate = int((($totalsize / $etime) * 60) / (1024 * 1024 * 1024)) if $etime > 0; $sidser = "$sid-$ser"; if ($verb eq "Y") { $blocksize = $words[1]; } if ($verb eq "Z") { printf "%-9s %-19s %-19s %8s %8s %10s %10s %10s %-10s \n",$sidser,$stime,$utime,$etime, $gbrate, $sofar,$totalwk,$pctcomp,$opname; } } exit; } # -------------------------------------------------------------------- # tu # -------------------------------------------------------------------- if ($arg eq "-tu") { print "\n"; &msg("-tu: Temp Segment Usage By User (From v\$sort_usage)\n"); $sqlstmt = ' select \'Y\', value from v\$parameter where name in (\'db_block_size\'); select \'X\', sid, serial#, v\$session.username, extents, contents, blocks from v\$session, v\$sort_usage where v\$session.saddr = v\$sort_usage.session_addr ; '; print "SID-Ser# User Extents Blocks MB Contents\n"; print "------------ ---------------- -------- -------- -------- -------------\n"; $t_blocks = 0; $t_mb = 0; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; $sid = $words[1]; $ser = $words[2]; $user = $words[3]; $ex = $words[4]; $contents = $words[5]; $blocks = $words[6]; $sidser = "$sid-$ser"; if ($verb eq "Y") { $blocksize = $words[1]; ##print "blocksize=$blocksize\n"; next; } if ($verb eq "X") { if ($user eq "") { $user = "."; } $mb = int(($blocks * $blocksize) / 1000000); ###print "user=$user\n"; printf "%-12s %-16s %8s %8s %8s %-20s\n", $sidser,$user,$ex,$blocks,$mb,$contents; $t_blocks += $blocks; $t_mb += $mb; } } print "\n"; &msg("Total TEMP Blocks In Use: $t_blocks"); &msg("Total TEMP mB In Use: $t_mb"); exit; } # -------------------------------------------------------------------- # si # -------------------------------------------------------------------- if ($arg eq "-si") { print "\n"; $sqlstmt = ' select \'Y\', value from v\$parameter where name in (\'db_block_size\'); select \'X\', tablespace_name, current_users, total_blocks, used_blocks, free_blocks, max_blocks from v\$sort_segment order by 1 ; '; &msg("-si: Sort Segment Information (From v\$sort_segment)\n"); print "Temp TS Name Cur-Users SegSize(mB) Used(mB) Free(mb) MaxUsed(mB)\n"; print "---------------- ------------ ------------ ------------ ------------ ------------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "Y") { $blocksize = $words[1]; ##print "blocksize=$blocksize\n"; next; } if ($verb eq "X") { $ts = $words[1]; $cusers = $words[2]; $tblocks = $words[3]; $ublocks = $words[4]; $fblocks = $words[5]; $mblocks = $words[6]; $tsize = int(($tblocks * $blocksize) / 1000000); $usize = int(($ublocks * $blocksize) / 1000000); $fsize = int(($fblocks * $blocksize) / 1000000); $msize = int(($mblocks * $blocksize) / 1000000); ##print "tblocks=$tblocks\n"; printf "%-16s %12s %12s %12s %12s %12s\n", $ts,$cusers,$tsize,$usize,$fsize,$msize; $t_cusers += $cusers; $t_tsize += $tsize; $t_usize += $usize; $t_fsize += $fsize; $t_msize += $msize; } } print "================ ============ ============ ============ ============ ============\n"; printf "%-16s %12s %12s %12s %12s %12s\n", "",$t_cusers,$t_tsize,$t_usize,$t_fsize,$t_msize; print "\n"; exit; } # -------------------------------------------------------------------- # pf # -------------------------------------------------------------------- if ($arg eq "-pf") { &msg("Instance Total Freelist Wait Percentage"); $sqlstmt = 'select \'X\', (a.count/sum(b.value))*100 free_list from v\$waitstat a, v\$sysstat b where a.class = \'free list\' and b.name in (\'db block gets\',\'consistent gets\') group by a.count;'; print "\n"; print "% Of Data Requests That\n"; print " Waited for a Freelist\n"; print "-----------------------\n"; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $pct = $words[1] + 0; $pct = sprintf("%7.2f",$pct); printf "%23s\n", $pct; } } print "\n"; if ($pct < 1) { &msg("Since the percent of total request that encountered a freelist"); &msg("wait is less than 1, you don't need to add freelists."); } if ($pct >= 1) { &msg("Since the percent of total request that encountered a freelist"); &msg("wait is >= l, consider adding freelists."); } exit; } # -------------------------------------------------------------------- # ck # -------------------------------------------------------------------- if ($arg eq "-ck") { &msg("Checkpoint Data"); $sqlstmt = 'select \'X\', min(sysdate - CHECKPOINT_TIME) from v\$datafile_header;'; &oraSQL("$sqlstmt"); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $minago = $words[1] * 24 * 60; $minago = '.' if $minago eq ""; printf "\nLastCheckpoint: %10.2f (Minutes Ago)\n", $minago; } } exit; } # -------------------------------------------------------------------- # sc # -------------------------------------------------------------------- if ($arg eq "-sc") { $where_ses = " and vs.sid = $arg2 " if $arg2; $sqlstmt = "select \'X\', vs.sid, vs.serial#, vs.type, vs.osuser, sysdate - logon_time logon_time, vs.process, vs.machine, vs.username, vss.value, vs.program from v\\\$session vs, v\\\$sesstat vss, v\\\$statname vsn where (vss.statistic#=vsn.statistic#) AND (vs.sid=vss.sid) AND (vsn.name = \'CPU used by this session\') $where_ses AND vss.value <> 0 order by 10;"; &msg("Sessions - Ordered By Session CPU Time\n"); print " ------------------------------------------Session------------------------------------------\n"; print "SID-Ser# OS:Userid-PID-Server DB:User Program Hours CPUTm Commit PFBlks TScans MemSorts DiskSorts Con+BuGet PhysReads RHRat LokWaitTm\n"; print "--------- ------------------------ ---------- ------------ ------ ------ ------ ------ ------ --------- --------- --------- --------- ------ ---------\n"; &oraSQL($sqlstmt); @saveSQLout = @oraSQLout; foreach (@saveSQLout) { ##print; @words = split(); $verb = $words[0]; $sid = $words[1]; $serial = $words[2]; $type = $words[3]; $osuser = $words[4]; $sessdur = $words[5]; $process = $words[6]; $machine = $words[7]; $username = $words[8]; $sesscpu = $words[9]; $program = $words[10] . $words[11] . $words[12] . $words[13]; $sesser = $sid . "," . $serial; $comb = "$osuser-$process-$machine"; $comb = substr($comb,0,24) if length($comb) > 24; $sdur = $sessdur * 24; $program = substr($program,0,12) if length($program) > 12; ##print "$sessdur $sdur\n"; if ($verb eq "X") { # convert stat names into statistic#'s if ($statnumbers eq "") { $substmt = " select distinct 'X', statistic#, name from v\\\$statname where name in ( 'user commits', 'prefetched blocks', 'transaction lock foreground wait time', 'db block gets', 'consistent gets', 'physical reads', 'sorts (memory)', 'sorts (disk)', 'table scans (short tables)', 'table scans (long tables)' ) order by 2;"; &oraSQL($substmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; if ($verb eq "X") { $statnumbers .= "$words[1],"; $commits_code = $words[1] if (/user commits/); $prefetch_code = $words[1] if (/prefetched blocks/); $locktime_code = $words[1] if (/transaction lock foreground wait time/); $blkgets_code = $words[1] if (/db block gets/); $congets_code = $words[1] if (/consistent gets/); $preads_code = $words[1] if (/physical reads/); $sorts_m_code = $words[1] if (/sorts \(memory\)/); $sorts_d_code = $words[1] if (/sorts \(disk\)/); $scans_s_code = $words[1] if (/table scans \(short tables\)/); $scans_l_code = $words[1] if (/table scans \(long tables\)/); } } chop $statnumbers; #print "statnumbers=$statnumbers\n"; #print "blkgets_code=$blkgets_code\n"; #print "prefetch_code=$prefetch_code\n"; #print "locktime_code=$locktime_code\n"; #print "congets_code=$congets_code\n"; #print "preads_code=$preads_code\n"; #print "sorts_m_code=$sorts_m_code\n"; #print "sorts_d_code=$sorts_d_code\n"; #print "scans_s_code=$scans_s_code\n"; #print "scans_l_code=$scans_l_code\n"; } # Get other stats #&scSub2($sid,"4,84,38,40,180,181,150,151"); ##print "statnumbers=$statnumbers\n"; &scSub2($sid,"$statnumbers"); foreach(@scArray) { @subwords = split; #print "stat=$subwords[0] value=$subwords[1]\n"; $s_locktime = $subwords[1] if $subwords[0] == $locktime_code; $s_commits = $subwords[1] if $subwords[0] == $commits_code; $s_prefetch = $subwords[1] if $subwords[0] == $prefetch_code; $s_blkgets = $subwords[1] if $subwords[0] == $blkgets_code; $s_congets = $subwords[1] if $subwords[0] == $congets_code; $s_phreads = $subwords[1] if $subwords[0] == $preads_code; $s_sorts_m = $subwords[1] if $subwords[0] == $sorts_m_code; $s_sorts_d = $subwords[1] if $subwords[0] == $sorts_d_code; $s_scans_s = $subwords[1] if $subwords[0] == $scans_s_code; $s_scans_l = $subwords[1] if $subwords[0] == $scans_l_code; #print "sc=$s_commits\n"; } $s_scans = $s_scans_s + $s_scans_l; if ($s_congets + $s_blkgets > 0) { $rhrat = (($s_congets + $s_blkgets - $s_phreads) / ($s_congets + $s_blkgets) * 100); } else { $rhrat = "."; } $rhrat = "-1" if $rhrat < 1; $gets = $s_congets + $s_blkgets; ##print "cg=$s_congets bg=$s_blkgets \n";; #$s_commits = &scSub($sid,4); #$s_prefetch = &scSub($sid,84); #$s_blkgets = &scSub($sid,38); #$s_phreads = &scSub($sid,40); #$s_sorts_m = &scSub($sid,180); #$s_sorts_d = &scSub($sid,181); #$s_scans_s = &scSub($sid,150); #$s_scans_l = &scSub($sid,151); #$s_scans = $s_scans_s + $s_scans_l; printf "%-9s %-24s %-10s %-12s %6.1f %6.0f %6.0f %6.0f %6.0f %9.0f %9.0f %9.0f %9.0f %6.1f %9.0f\n", $sesser, $comb, $username, $program, $sdur, $sesscpu, $s_commits, $s_prefetch, $s_scans, $s_sorts_m, $s_sorts_d, $gets, $s_phreads, $rhrat, $s_locktime; } } exit; } sub scSub { $mysid = $_[0]; $mystat = $_[1]; $sqlsub = "select \'X\', value from v\\\$sesstat where sid = $mysid and statistic# = $mystat;"; &oraSQL($sqlsub); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $value = $words[1]; } } return $value; } sub scSub2 { $mysid = $_[0]; $mystats = $_[1]; $sqlsub = "select \'X\', statistic#, value from v\\\$sesstat where sid = $mysid and statistic# in ($mystats);"; ##print "sqlsub=$sqlsub\n"; &oraSQL($sqlsub); foreach (@oraSQLout) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $stat = $words[1]; $value = $words[2]; push(@scArray,"$stat $value"); } } return; } # -------------------------------------------------------------------- # so # -------------------------------------------------------------------- if ($arg eq "-so") { &msg("-so: Sorts By User"); $sqlstmt = 'select \'X\', vss.value, substr(vsn.name,1,20) "Type of Sort", substr(vs.osuser,1,20) "os user", substr(vs.username,1,20) "db user" from v\$session vs, v\$sesstat vss, v\$statname vsn where (vss.statistic#=vsn.statistic#) AND (vs.sid=vss.sid) AND (vsn.name like \'%sort%\') AND vss.value <> 0 order by 2,3;'; print "DB User OS User Sort Type Value\n"; print "---------- ---------- --------------- ----------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; $value = $words[1]; $s_type1 = $words[2]; $s_type2 = $words[3]; $osuser = $words[4]; $dbuser = $words[5]; $s_type="$s_type1 $s_type2"; $_=$dbuser; s/ //g; $dbuser=$_; $_=$osuser; s/ //g; $osuser=$_; if ($verb eq "X") { if ($dbuser eq "") { $dbuser = "."; } if ($osuser eq "") { $osuser = "."; } printf "%-10s %-10s %-15s %10s\n", $dbuser,$osuser,$s_type,$value; } } exit; } # -------------------------------------------------------------------- # wx # -------------------------------------------------------------------- if ($arg eq "-wx") { &msg("-wx: Wait Reason - By Event Type (Idle Waits Excluded)"); $sqlstmt = 'select \'X\', count(*), \'.\', translate(sw.event,\' \',\'_\') from v\$session se, v\$session_wait sw where sw.sid = se.sid and se.username >= \'A\' and sw.event not like \'PX Deq%\' and sw.event not like \'SQL*Net%\' and sw.event not like \'pipe get%\' and sw.event not like \'wait for unread message%\' and sw.event not like \'%waiting for messages%\' and sw.event not like \'queue messages%\' and sw.event not like \'latch free\' group by \' \', translate(sw.event,\' \',\'_\') union all select \'X\', count(*), translate(la.name,\' \',\'_\'), translate(sw.event,\' \',\'_\') from v\$session se, v\$session_wait sw, v\$latch la where sw.sid = se.sid and se.username >= \'A\' and sw.event = \'latch free\' and sw.p2 = la.latch# group by translate(la.name,\' \',\'_\'), translate(sw.event,\' \',\'_\') order by 2; '; print "\n"; print "Wait Event Sessions Waiting\n"; print "---------------------------------------- ----------------\n"; $count_tot = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /ORA-/; @words = split(); $verb = $words[0]; ##print "v=$verb wc=$#words w0=$words[0] w1=$words[1] w2=$words[2] w3=$words[3] \n"; if ($verb eq "X") { $count = $words[1]; $p2 = $words[2]; $text = $words[3]; if ($text eq "latch_free") { $text .= "_$p2"; } printf "%-40s %16s\n", $text,$count; $count_tot += $count; } } exit; } # -------------------------------------------------------------------- # wt # -------------------------------------------------------------------- if ($arg eq "-wt") { ## &msg("-wt: Waits - By Event Type (Idle and Network Waits Excluded) >= 10g Only"); &msg("-wt: Waits - By Event Type (Idle Waits Excluded) Ordered By Descending Session Count >= 10g Only"); if ($oraver < 10) { &msg("orastat -wt Only works with Oracle 10g or Higher"); exit; } $sqlstmt = 'select \'X\', count(*), translate(sw.wait_class,\' \',\'_\'), translate(sw.event,\' \',\'_\') from v\$session se, v\$session_wait sw where sw.sid = se.sid -- and se.username >= \'A\' and sw.event is not null and sw.wait_class != \'Idle\' group by translate(sw.wait_class,\' \',\'_\'), translate(sw.event,\' \',\'_\') order by 2 desc; '; print "\n"; print "Wait Event Wait Class Sessions Waiting\n"; print "---------------------------------------- ------------ ----------------\n"; $count_tot = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /ORA-/; @words = split(); $verb = $words[0]; ##print "v=$verb wc=$#words w0=$words[0] w1=$words[1] w2=$words[2] w3=$words[3] \n"; if ($verb eq "X") { $count = $words[1]; $wait_class= $words[2]; $text = $words[3]; next if $text =~ /message_to_client/; printf "%-40s %-12s %16s\n", $text,$wait_class,$count; $count_tot += $count; } } print "\n"; &msg("Total Sessions Waiting: $count_tot"); exit; } # -------------------------------------------------------------------- # wr # -------------------------------------------------------------------- if ($arg eq "-wr") { &msg("-wr: Wait Reasons - By User and Event Type (Idle Waits Excluded)"); $sqlstmt = 'select \'X\', se.username, count(*), sw.event from v\$session se, v\$session_wait sw where sw.sid = se.sid and se.username > \'A\' and sw.event not like \'SQL*Net%\' and sw.event not like \'PX Deq%\' -- and sw.event not like \'PX Deq: Table Q Normal%\' -- and sw.event not like \'PX Deq: Execution Msg%\' and sw.event not like \'pipe get%\' and sw.event not like \'queue message%\' and sw.event not like \'wait for unread%\' and sw.event not like \'%waiting for messages%\' group by se.username, sw.event; '; print "\n"; print "DB User Wait Event Type Sessions Waiting\n"; print "---------- ---------------------------------------- ----------------\n"; $count_tot = 0; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; print if /ORA-/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $user = $words[1]; $count = $words[2]; $text = ""; for ($i = 3; $i <= $#words; $i++) { $text .= $words[$i]; $text .= " "; } printf "%-10s %-40s %16s\n", $user,$text,$count; $count_tot += $count; } } print "\n"; &msg("Total Session(s) Waiting: $count_tot"); exit; } # -------------------------------------------------------------------- # sa # -------------------------------------------------------------------- if ($arg eq "-sa") { &msg("-sa: Session Statistics"); $sqlstmt = 'select \'X\', sum(vss.value), count(*), --substr(vsn.name,1,20) vsn.name from v\$sesstat vss, v\$statname vsn where (vss.statistic#=vsn.statistic#) AND vss.value <> 0 --group by substr(vsn.name,1,20) group by vsn.name order by 4;'; print "Session Statistic Value Sessions Per Session\n"; print "------------------------------------------------------------ --------------- -------- ---------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { ##print; @words = split(); $verb = $words[0]; if ($verb eq 'X') { $value = $words[1]; $count = $words[2]; ##print "count=$count\n"; $perses = ""; $perses = int($value / $count) if $count > 0; $text = ""; for ($i = 3; $i <= $#words; $i++) { $text .= $words[$i]; $text .= " "; } printf "%-60s %15s %8s %15s\n",$text,$value,$count,$perses; } } exit; } # -------------------------------------------------------------------- # -br # -------------------------------------------------------------------- if ($arg eq "-br") { &msg("-br: Backups"); $sqlstmt = 'select \'X\', max(recid) from v\$backup_set where incremental_level = \'0\';'; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $l0_recid = $words[1]; } } &msg("Most recent L0 recid=$l0_recid"); $sqlstmt = "select \'X\', to_char(completion_time,\'YYYY/MM/DD-HH24:MI:SS\') from v\\\$backup_set where recid = $l0_recid;"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $l0_ts = $words[1]; } } &msg("Most recent L0 timestamp=$l0_ts"); $sqlstmt = "select \'X\', to_char(completion_time,\'YYYY/MM/DD-HH24:MI:SS\'), media from v\\\$backup_piece where recid >= $l0_recid;"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $ts = $words[1]; $tp = $words[2]; ##print "$ts $tp\n"; if (index($tplist,$tp) == -1) { $tplist .= "$tp,"; $tphash{$tp} = 1; } } } &msg("List of backup media that have been written to since the most recent LVL0:"); @sorted = sort keys %tphash; foreach (@sorted) { print "Media: $_\n"; $cnt++; } &msg("Found $cnt tape(s)"); exit; } # -------------------------------------------------------------------- # -bi # -------------------------------------------------------------------- if ($arg eq "-bi") { &msg("-bi: Backups"); $sqlstmt = ' select \'X\', nvl(p.handle,\'?\'), nvl(p.media,\'?\'), to_char(p.completion_time,\'YYYY/MM/DD-HH24:MI:SS\'), decode(s.backup_type,\'L\',\'ARC\',\'I\',\'LVL1\',\'D\',\'LVL0\'), p.set_stamp from v\$backup_set s, v\$backup_piece p where p.set_count=s.set_count and p.deleted != \'YES\' order by s.completion_time ;'; $cnt=-1; &oraSQL($sqlstmt); foreach (@oraSQLout) { ## print; print if /^ORA/; @words = split; $verb = $words[0]; if ($verb eq "X") { $bkp_piece = $words[1]; $media_name = $words[2]; $end_date = $words[3]; $bkp_type = $words[4]; $cnt+=1; $b_pieces[$cnt] = $bkp_piece; $b_info{$bkp_piece}{"media_name"} = $media_name; $b_info{$bkp_piece}{"end_date"} = $end_date; $b_info{$bkp_piece}{"bkp_type"} = $bkp_type; } } if (uc($arg2) eq "SINCE") { $retry_cnt = 0; do { $invalid_date = "false"; print ("\n"); print ("Enter PIT (YYYY/MM/DD-HH24:MI:SS)\n"); print (" (ex: 2001/08/12-18:05:00): "); $pit = ; chop($pit); if (substr($pit,4,1) ne "/" || substr($pit,7,1) ne "/" || substr($pit,10,1) ne "-" || substr($pit,13,1) ne ":" || substr($pit,16,1) ne ":") { print "\nERROR: Invalid date format.\n"; $invalid_date = "true"; $retry_cnt += 1; } if ($retry_cnt == 3) { print " Unable to continue after $retry_cnt attempts.\n\n"; exit 1; } } until ($invalid_date ne "true"); } elsif (uc($arg2) eq "BETWEEN") { $retry_cnt = 0; do { $invalid_date = "false"; print ("\n"); print ("Enter end time (YYYY/MM/DD-HH24:MI:SS)\n"); print (" (ex: 2001/08/12-18:05:00): "); $e_time = ; chop($e_time); if (substr($e_time,4,1) ne "/" || substr($e_time,7,1) ne "/" || substr($e_time,10,1) ne "-" || substr($e_time,13,1) ne ":" || substr($e_time,16,1) ne ":") { print "\nERROR: Invalid date format.\n"; $invalid_date = "true"; $retry_cnt += 1; } if ($retry_cnt == 3) { print " Unable to continue after $retry_cnt attempts.\n\n"; exit 1; } } until ($invalid_date ne "true"); $retry_cnt = 0; do { $invalid_date = "false"; print ("\n"); print ("Enter start time (YYYY/MM/DD-HH24:MI:SS)\n"); print (" (ex: 2001/08/10-12:05:00): "); $s_time = ; chop($s_time); if (substr($s_time,4,1) ne "/" || substr($s_time,7,1) ne "/" || substr($s_time,10,1) ne "-" || substr($s_time,13,1) ne ":" || substr($s_time,16,1) ne ":") { print "\nERROR: Invalid date format.\n"; $invalid_date = "true"; $retry_cnt += 1; } if ($retry_cnt == 3) { print " Unable to continue after $retry_cnt attempts.\n\n"; exit 1; } } until ($invalid_date ne "true"); $retry_cnt = 0; if ($stime gt $e_time) { $temp = $s_time; $s_time = $e_time; $e_time = $temp; } } printf("\n"); $end_date = "Date/Time"; $bkp_type = "Type"; $media_name = "Tape#"; $bkp_piece = "Backup Piece"; printf ("%-20s %-8s %-10s %-30s \n",$end_date,$bkp_type,$media_name,$bkp_piece); for ($i=0;$i<=68;$i++) { printf ("-"); } printf("\n"); $cnt=-1; #$bt_found = "ARC"; #$print_cnt = 0; #$pit_cnt = -1; foreach $bkp_piece (@b_pieces) { $cnt+=1; $media_name = $b_info{$bkp_piece}{"media_name"}; $end_date = $b_info{$bkp_piece}{"end_date"}; $bkp_type = $b_info{$bkp_piece}{"bkp_type"}; if (uc($arg2) eq "ALL" || $arg2 eq "") { printf ("%-20s %-8s %-10s %-30s \n",$end_date,$bkp_type,$media_name,$bkp_piece); } elsif (uc($arg2) eq "SINCE") { if ($pit le $end_date && $pit gt ${b_info{$bkp_piece + 1}{"end_date"}}) { printf ("%-20s %-8s %-10s %-30s \n",$end_date,$bkp_type,$media_name,$bkp_piece); } } elsif (uc($arg2) eq "BETWEEN") { if ($end_date le $e_time && $end_date ge $s_time) { printf ("%-20s %-8s %-10s %-30s \n",$end_date,$bkp_type,$media_name,$bkp_piece); } } else { print "\nERROR: Invalid option.\n\n"; exit 1; } } print "\n"; exit; } # -------------------------------------------------------------------- # -v # -------------------------------------------------------------------- if ($arg eq "-v") { @banner = `$oh/bin/sqlplus -?`; foreach $line (@banner) { if ($line =~ "SQL") { @words = split(' ',$line); $oraver = $words[2]; } } print "\nVersion: $oraver\n"; $oramode=`file $oh/bin/oracle |grep 64`; if (length ($oramode)) { print "Oracle Binary: 64-bit\n"; } else { print "Oracle Binary: 32-bit\n"; } exit; } # -------------------------------------------------------------------- # pc # -------------------------------------------------------------------- if ($arg eq "-pc") { &msg("Accounts where username=password"); $sqlstmt = 'select \'X\', username from dba_users order by 2;'; print "\nUser accounts with username=password\n"; print "------------------------------------\n"; &oraSQL($sqlstmt); foreach (@oraSQLout) { print if /^ORA/; @words = split(); $verb = $words[0]; $user = $words[1]; if ($verb eq 'X') { @mySQLout = `sqlplus $user/$user< $num Sleeps and > $num Block Hits"); $sqlstmt = "select /*+ ordered */ \'X\', e.owner ||\'.\'|| e.segment_name segment_name, e.extent_id extent#, x.dbablk - e.block_id + 1 block#, x.tch, l.child#, l.sleeps from sys.v\\\$latch_children l, sys.x\\\$bh x, sys.dba_extents e where l.name = \'cache buffers chains\' and l.sleeps > $num and x.tch > $num and x.hladdr = l.addr and e.file_id = x.file# and x.dbablk between e.block_id and e.block_id + e.blocks - 1 order by 7 desc, 5 desc;"; ##print "sqlstmt=$sqlstmt\n"; &oraSQL("$sqlstmt"); print "\n"; print " Sleeps Hits Extent Block# Children Segment\n"; print "-------- -------- ------ -------- -------- ------------------------------\n"; @saveSQLout1 = @oraSQLout; foreach (@saveSQLout1) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $segment = $words[1]; $extent = $words[2]; $blocknum = $words[3]; $tch = $words[4]; $childnum = $words[5]; $sleeps = $words[6]; printf("%8s %8s %6s %8s %8s %-50s\n",$sleeps,$tch,$extent,$blocknum,$childnum,$segment); $foundit = 1; } } exit; } # -------------------------------------------------------------------- # pt # -------------------------------------------------------------------- if ($arg eq "-pt") { &msg("-pt: Hot Blocks - Top 25 Most Frequently Touched Non-SYS Blocks"); $sqlstmt = 'select /*+ ordered */ \'X\', e.owner ||\'.\'|| e.segment_name segment_name, e.extent_id extent#, x.dbablk - e.block_id + 1 block#, x.tch from sys.x\$bh x, sys.dba_extents e where e.file_id = x.file# and x.dbablk between e.block_id and e.block_id + e.blocks - 1 order by 5 desc;'; &oraSQL("$sqlstmt"); print "\n"; print " Touches Extent Block# Segment\n"; print "-------- -------- -------- ------------------------------\n"; @saveSQLout1 = @oraSQLout; foreach (@saveSQLout1) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $segment = $words[1]; $extent = $words[2]; $blocknum = $words[3]; $tch = $words[4]; next if $segment =~ /^SYS\./; printf("%8s %8s %8s %-50s\n",$tch,$extent,$blocknum,$segment); $count++; } last if $count >= 25; } exit; } # -------------------------------------------------------------------- # tq # -------------------------------------------------------------------- if ($arg eq "-tq") { &msg("-tq: Tablespace Defaults/Details"); $sqlstmt = 'select \'X\', TABLESPACE_NAME , INITIAL_EXTENT , nvl(NEXT_EXTENT,\'-1\') , MIN_EXTENTS , nvl(MAX_EXTENTS,\'-1\') , nvl(PCT_INCREASE,\'-1\') , MIN_EXTLEN , STATUS , CONTENTS , LOGGING , EXTENT_MANAGEMENT , ALLOCATION_TYPE , PLUGGED_IN , segment_space_management from dba_tablespaces order by 2;'; &oraSQL("$sqlstmt"); print "\n"; print " Extent Extent Extent Plugged\n"; print "Tablespace Status Init Next ExtMin MaxExt PctInc Min Contents Logging ExtMgmt-AllocType In ASSM\n"; print "-------------------- ------ ---------- ---------- -------- -------- ------ ---------- ---------- ---------- -------------------- ---------- ----------\n"; $count = 0; @saveSQLout1 = @oraSQLout; foreach (@saveSQLout1) { ##print; print if /^ORA/; @words = split(); $verb = shift @words; if ($verb eq "X") { $count++; $ts = shift @words; $extini = shift @words; $extnex = shift @words; $extmin = shift @words; $extmax = shift @words; $pctinc = shift @words; $extminln = shift @words; $status = shift @words; $contents = shift @words; $logging = shift @words; $extmgmt = shift @words; $alloctyp = shift @words; $plugged = shift @words; $ssm = shift @words; $extmax = "(Unlim.)" if $extmax == 2147483645; $extmax = "(N/A)" if $extmax == -1; $extminln = &formatNum($extminln); $extnex = &formatNum($extnex); $extini = &formatNum($extini); $extnex = "(N/A)" if $extnex < 1; $pctinc = "(N/A)" if $pctinc == -1; $extmgmt .= "-$alloctyp" if $alloctyp; ##&msg("DEBUG - alloctyp=$alloctyp ssm=$ssm"); printf("%-20s %-6s %10s %10s %8s %8s %6s %10s %-10s %-10s %-20s %-10s %-10s\n", $ts , $status , $extini , $extnex , $extmin , $extmax , $pctinc , $extminln , $contents , $logging , $extmgmt , $plugged, $ssm ); } } print "\n"; &msg("Found $count tablespaces"); exit; } # -------------------------------------------------------------------- # pm # -------------------------------------------------------------------- if ($arg eq "-pm") { @words = split(/\./,$arg2); $owner = uc $words[0]; $table = uc $words[1]; if ($owner eq "" || $table eq "") { print "$P | Usage: $P -ti TABLE-OWNER.TABLE-NAME\n"; exit 1; } &msg("-pm: Table Block Map for $owner.$table"); $sqlstmt = "select /*+ ordered */ \'X\', e.extent_id extent#, x.dbablk - e.block_id + 1 block#, x.tch touches from sys.dba_extents e, sys.x\\\$bh x where e.owner = \'$owner\' and e.segment_name = \'$table\' and e.segment_type = \'TABLE\' and e.file_id = x.file# and x.dbablk between e.block_id and (e.block_id + e.blocks - 1) order by 2, 3;"; $sqlstmt = "select /*+ ordered */ \'X\', e.extent_id, e.block_id, e.blocks, e.file_id from sys.dba_extents e where e.owner = \'$owner\' and e.segment_name = \'$table\' and e.segment_type = \'TABLE\' order by 2;"; &oraSQL("$sqlstmt"); print "\n"; print " Extent DF StartBlk Length\n"; print "-------- ---- -------- --------\n"; @saveSQLout1 = @oraSQLout; foreach (@saveSQLout1) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $extent = $words[1]; $blockstr = $words[2]; $blocks = $words[3]; $file = $words[4]; next if $segment =~ /^SYS\./; printf("%8s %4s %8s %8s %-30s\n",$extent,$file,$blockstr,$blocks); $count++; } last if $count >= 25; } $sqlstmt = "select \'X\', x.dbablk, x.dbarfil, sum(x.tch) from sys.dba_objects e, sys.x\\\$bh x where e.owner = \'$owner\' and e.object_name = \'$table\' and e.data_object_id = x.obj group by x.dbablk, x.dbarfil order by 2;"; &oraSQL("$sqlstmt"); print "\n"; print " Block DF Touches \n"; print "-------- ---- -------- ------------------------------\n"; @saveSQLout1 = @oraSQLout; foreach (@saveSQLout1) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $block = $words[1]; $file = $words[2]; $touches = $words[3]; next if $segment =~ /^SYS\./; printf("%8s %4s %8s %-30s\n",$block,$file,$touches); $count++; } last if $count >= 25; } exit; } # -------------------------------------------------------------------- # pw # -------------------------------------------------------------------- if ($arg eq "-pw") { &msg("Blocks Experiencing BUFFER BUSY WAITS"); $sqlstmt = 'select distinct \'X\', p1, p2 from v\$session_wait where event = \'buffer busy waits\';'; &oraSQL("$sqlstmt"); @saveSQLout1 = @oraSQLout; foreach (@saveSQLout1) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $filenum = $words[1]; $blocknum = $words[2]; &msg("Found BUFFER BUSY WAIT - filenum=$filenum blocknum=$blocknum"); $foundit = 1; # Find the table name &oraSQL("select \'X\', file_name, tablespace_name from dba_data_files where file_id = $filenum;"); @saveSQLout2 = @oraSQLout; foreach (@saveSQLout2) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $filename = $words[1]; $tsname = $words[2]; &msg(" Datafile=$filenum Tablespace=$tsname Filename=$filename"); } } # Find the table name # TEST ##$filenum = 6; $blocknum = 35707; $sql = "select /*+ RULE */ \'X\', owner, segment_name, segment_type, tablespace_name, block_id, blocks from dba_extents where file_id = $filenum and block_id <= $blocknum and $blocknum <= ((block_id + blocks) - 1);"; ##print "sql=$sql\n"; &oraSQL("$sql"); @saveSQLout3 = @oraSQLout; foreach (@saveSQLout3) { ##print; print if /^ORA/; @words = split(); $verb = $words[0]; if ($verb eq "X") { $owner = $words[1]; $segment = $words[2]; $type = $words[3]; $ts = $words[4]; $blockid = $words[5]; $blocks = $words[6]; &msg(" Segment=$owner.$segment Type=$type TS=$ts - block_id=$blockid blocks=$blocks"); } } } } if (!$foundit) { &msg("No BUFFER BUSY WAITS found"); } exit; } # -------------------------------------------------------------------- # -cv # -------------------------------------------------------------------- if ($arg eq "-cv") { &msg("Generating syntax to recompile Invalid Objects"); $sqlstmt = "select \'X\','alter ' || object_type || ' ' || owner || '.' || object_name || ' compile;' from dba_objects where status='INVALID';"; &oraSQL($sqlstmt); #$tbl_cnt=-1; print "\n"; foreach (@oraSQLout) { ## print; print if /^ORA/; if ($_ =~ "X") { s/X//; s/\n//; if (/PACKAGE BODY/) { s/PACKAGE BODY/PACKAGE/; s/;$/ body;/; } print "$_\n"; } } print "\n"; exit; } # -------------------------------------------------------------------- # -af # -------------------------------------------------------------------- if ($arg eq "-af") { &msg("-af: Archive Log Files (arc* files in archive log dir)"); open(EXT, "echo ' $os_conn archive log list ' | $os_scmd 2>&1 |") || die "Error running svrmgrl"; while() { ##print; @words = split; $verb = $words[0]; if (/Database log mode/) { $arclogmode = $words[4]; } if (/^Automatic archival/) { $arcauto = $words[2]; } if (/^Archive destination/) { $arcdirraw = $words[2]; } } close(EXT); # Fix - bb - svrmgrl lists arcdest2 if it exists - we don't # want that, so we will get the first disk dest from orastat -ad chop($arcdirnew = `orastat -ad | grep ' /' | head -1 | awk '{ print \$NF }'`); ##print "arcdirnew=$arcdirnew\n"; #---- 3.05 - only do this if arcdirnew is non-null if ($arcdirnew && $arcdirraw ne $arcdirnew) { &msg("Overriding arcdirraw=$arcdirraw with $arcdirnew"); $arcdirraw = $arcdirnew; } # Cut off last level of (example) /oracle/PD1/saparch/PD1arch #---- ONLY IF arcdirraw ends with arch $arcdir = $arcdirraw; if ($arcdir =~ /arch$/) { @words = split(/\//,$arcdirraw); $numlevels = $#words - 1; $arcdir = ""; for ($i = 1; $i <= $numlevels; $i++) { $arcdir = $arcdir . "/" . $words[$i]; } } chop $arcdir if $arcdir =~ /\/$/; &msg("arcdir: $arcdir (arcdirraw=$arcdirraw)"); opendir(ARCDIR,"$arcdir"); @filenames = readdir(ARCDIR); @filenamessorted = sort @filenames; closedir(ARCDIR); print "\n"; print "Archive Log File Name MTime Age(Secs) Size MTime-Formatted CTime-Formatted\n"; print "------------------------------------------------------ ---------- --------- --------- ------------------- -------------------\n"; $numlogs = 0; $totsize = 0; $age = -1; foreach $file (@filenamessorted) { next if ($file !~ /^arc/); $arcmtime = ( stat "$arcdir/$file" ) [9]; $arcsize = ( stat "$arcdir/$file" ) [7]; $arcctime = ( stat "$arcdir/$file" ) [10]; $arcmtime_fmt = &timeToText($arcmtime); $arcctime_fmt = &timeToText($arcctime); $age = time - $arcmtime; $oldest = $age if $age > $oldest; ##printf "%-54s %10s %9s %9s arcmtime_fmt=$arcmtime_fmt arcctime_fmt=$arcctime_fmt\n","$arcdir/$file",$arcmtime,$age,$arcsize,$arcctime; printf "%-54s %10s %9s %9s %s %s\n","$arcdir/$file",$arcmtime,$age,$arcsize,$arcmtime_fmt,$arcctime_fmt; $numlogs++; $totsize += $arcsize; } $totsize /= 1000000; $agedays = $age / (24*60*60); $agedays = sprintf("%8.3f",$agedays); $olddays = $oldest / (24*60*60); $olddays = sprintf("%8.3f",$olddays); print "\n"; &msg("Total number of archive logs: $numlogs"); &msg("Total size of archive logs: $totsize (MB)"); &msg("Most recent archive log age: $age (Seconds)"); &msg("Most recent archive log age: $agedays (Days)"); &msg("Oldest archive log age: $olddays (Days)"); exit; } # -------------------------------------------------------------------- # -af9i # -------------------------------------------------------------------- if ($arg eq "-af9i") { &msg("-af9i: Archive Log Files (arc* files in archive log dir)"); open(EXT, 'echo " connect / as sysdba archive log list " | sqlplus /NOLOG 2>&1 |') || die "Error running svrmgrl"; while() { ##print; @words = split; $verb = $words[0]; if (substr($_,0,22) eq "SQL> Database log mode") { $arclogmode = $words[4]; } if (substr($_,0,18) eq "Automatic archival") { $arcauto = $words[2]; } if (substr($_,0,19) eq "Archive destination") { $arcdirraw = $words[2]; } } close(EXT); # Fix - bb - svrmgrl lists arcdest2 if it exists - we don't # want that, so we will get the first disk dest from orastat -ad chop($arcdirnew = `orastat -ad | grep ' /' | head -1 | awk '{ print \$NF }'`); ##print "arcdirnew=$arcdirnew\n"; if ($arcdirraw ne $arcdirnew) { &msg("Overriding arcdirraw=$arcdirraw with $arcdirnew"); $arcdirraw = $arcdirnew; } # Cut off last level of (example) /oracle/PD1/saparch/PD1arch @words = split(/\//,$arcdirraw); $numlevels = $#words; $arcdir = ""; for ($i = 1; $i <= $numlevels; $i++) { $arcdir = $arcdir . "/" . $words[$i]; } &msg("arclogdir: $arcdir"); opendir(ARCDIR,"$arcdir"); @filenames = readdir(ARCDIR); @filenamessorted = sort @filenames; closedir(ARCDIR); print "\n"; print "Archive Log File Name MTime Age(Secs) Size\n"; print "------------------------------------------------------ ---------- --------- ---------\n"; $numlogs = 0; $totsize = 0; $age = -1; foreach $file (@filenamessorted) { next if ($file !~ /^arc/); $arcmtime = ( stat "$arcdir/$file" ) [9]; $arcsize = ( stat "$arcdir/$file" ) [7]; $arcctime = ( stat "$arcdir/$file" ) [10]; ($sec,$min,$hour,$mday,$mon,$year) = localtime($arcmtime); $arcmtime_fmt = "$year/$mon/$mday-$hour:$min:$sec"; ($sec,$min,$hour,$mday,$mon,$year) = localtime($arcctime); $arcctime_fmt = "$year/$mon/$mday-$hour:$min:$sec"; $age = time - $arcmtime; $oldest = $age if $age > $oldest; printf "%-54s %10s %9s %9s arcmtime_fmt=$arcmtime_fmt arcctime_fmt=$arcctime_fmt\n","$arcdir/$file",$arcmtime,$age,$arcsize,$arcctime; $numlogs++; $totsize += $arcsize; } $totsize /= 1000000; $agedays = $age / (24*60*60); $agedays = sprintf("%8.3f",$agedays); $olddays = $oldest / (24*60*60); $olddays = sprintf("%8.3f",$olddays); print "\n"; &msg("Total number of archive logs: $numlogs"); &msg("Total size of archive logs: $totsize (MB)"); &msg("Most recent archive log age: $age (Seconds)"); &msg("Most recent archive log age: $agedays (Days)"); &msg("Oldest archive log age: $olddays (Days)"); exit; } # -------------------------------------------------------------------- # Menu # -------------------------------------------------------------------- USAGE: print "orastat | Version $version Usage:\n"; print " -- View This Help File\n"; print " - Check for PMON Running, Show Oracle Version, Instance Status\n"; print " -ab List Archive Log RMAN Backups [Option Archive Log Sequence Number]\n"; print " -ad List Archive Destinations (v\$archive_dest)\n"; print " -af List Archive Log Directory Contents\n"; print " -al Show All Archived Logs \n"; print " -amm AMM (Automatic Memory Management) (sga_target) Stats\n"; print " -an Analyze Table COMPUTE STATISTICS - '$P -an TABLE-OWNER.TABLE-NAME'\n"; print " -ar Show Current DB Activity Rate\n"; print " -asm ASM Details & Status\n"; print " -asm_dg ASM Diskgroups\n"; print " -asm_dk ASM Disks\n"; print " -asm_fi ASM Files\n"; print " -asm_op ASM Operations\n"; print " -au Show DB Audit Status\n"; print " -av Archive Log Volume - [D/H] [# of days]\n"; print " -az Show Current DB Activity Rate - Log to $savedir/db_activity_rate_.txt\n"; print " -ba List Contents of dbamon.backup_age Table\n"; print " -bb List Summary of all RMAN backup pieces - from v\$backup_piece\n"; print " -bc List Contents of buffer pool\n"; print " -bd Datafile backup mode status\n"; print " -bi List RMAN backup inventory -- [ALL|SINCE|BETWEEN]\n"; print " -bm List Tablespaces and Datafiles in Backup Mode (from v\$backup)\n"; print " -bo Buffer Cache Overview (Many Reports)\n"; print " -bp List running RMAN backup sessions (if any)\n"; print " -br Backups: List all media written to since the last RMAN LVL0 backup\n"; print " -brm Backup Media: List all backup media\n"; print " -bs Create DDL to take datafiles that are in backup mode out of backup mode\n"; print " -c Configuration: View init.ora File\n"; print " -cb Controlfile Backup: Trace and Binary\n"; print " -cc Client Connections\n"; print " -cd Controlfile Details (Sections)\n"; print " -cdb List all DBs running al all nodes in SG cluster\n"; print " -ce Configuration: Edit 'vi' init.ora File\n"; print " -cf List Control Files\n"; print " -ck List Time of Last Checkpoint (from v\$datafile_headers)\n"; print " -cm Configuration: View Contents of v\$parameter with modifiable flags\n"; print " -cp Configuration: View Contents of v\$parameter\n"; print " -ct Coalesce TEMP tablespace\n"; print " -cv Generate syntax to recompile INVALID Objects\n"; print " -da List Datafiles - Autoextend details\n"; print " -dc List Datafiles in 'cp' commands to copy all datafiles elsewhere\n"; print " -dd Reproduce Object DDL (9i+ Only)\n"; print " -dd DDL Table: orastat -dd TABLE SCOTT DEPT\n"; print " -dd DDL Index: orastat -dd INDEX SCOTT DEPT_X\n"; print " -dd DDL Tablespace: orastat -dd TABLESPACE \"\" TSNAME\n"; print " -dd DDL User: orastat -dd USER \"\" SCOTT\n"; print " -dd DDL DBLink: orastat -dd USER \"\" LINKNAME\n"; print " -de List All Datafiles, Online Redo Logs and Control Files (For Destroying a DB)\n"; print " -df List Datafiles - Optional FSCHECK 2nd parm to bdf filesystem\n"; print " -df2 List Datafiles - from dba_data_files (for scripts)\n"; print " -df3 List Datafiles - from v\$datafile\n"; print " -df4 List Datafiles - which house S* tables with >= $arg2 () columns\n"; print " -dgl DataGuard - Log Apply Lag\n"; print " -dh List Datafiles and their 'Used Blocks' High-Water-Mark - Creates RESIZE commands\n"; print " -di Datafiles Contents (extents) by Block address - Must supply DF#\n"; print " -dn A Better and Faster version of -dh\n"; print " -dp Database properties (from DATABASE_PROPERTIES)\n"; print " -dst DST Patch checking\n"; print " -du List Datafiles where UNRECOVERABLE_CHANGE# is not null\n"; print " -ec Configuration: Edit 'vi' config.ora File\n"; print " -emth EM - Alert Thresholds\n"; print " -emac EM - Alerts - Current (DBA_OUTSTANDING_ALERTS)\n"; print " -emah EM - Alerts - Historical (DBA_ALERTS_HISTORY)\n"; print " -er Display contents of DBA_ERRORS\n"; print " -ev Select from v\$system_event\n"; print " -ex Select from plan_table\n"; print " -fm Display hours since file modification time - Requires ARG\n"; print " -fra Flash Recovery Area Status\n"; print " -fs Free Space in Each Datafile\n"; print " -ft List 'Fast Start' Transactions being rolled back\n"; print " -hd Hot Tables - With Datafile Name\n"; print " -ht Hot Tables\n"; print " -in List Indexes\n"; print " -iv List INVALID Objects\n"; print " -l List Archive Log Status\n"; print " -la Latch Details (from v\$latch)\n"; print " -lf List Redo Log Files\n"; print " -lg Longops: Long Operation Progress\n"; print " -lh Lock Holders/Waiter\n"; print " -li List Resource Limits (v\$resource_limit)\n"; print " -lk Locks - Current TX (Non-Row) Locks\n"; print " -ln List DB Links\n"; print " -lo List Current Table Locks\n"; print " -ls Listener Status\n"; print " -lv List LVOL's / Usage\n"; #rint " -lw List LVOL's / Usage - Create ln -s Commands\n"; print " -m View Last 20 Lines Of Alert Log\n"; print " -ma Cat entire Alert Log\n"; print " -mf Tail -90f Alert Log\n"; print " -mr Alert log - reformatted - Last 20 lines\n"; print " -mr a Alert log - reformatted - entire file\n"; print " -mr v Alert log - reformatted - 'vi' entire file\n"; print " -mt MTS Statistics\n"; print " -mv 'vi' (read-only mode) Of Alert Log\n"; print " -nf List Objects whose NEXT EXTENT will not fit in the tablespace\n"; print " -nl List NOLOGGING Tables and Indices\n"; print " -ob Objects - With Decimal and Hex Object ID\n"; print " -op OPS: View V\$PING - Lock Conversions\n"; print " -pb Performance: Current Data Block Buffer Hit Ratio - RIGHT NOW\n"; print " -pc Password Check: Check for accounts where username=password\n"; print " -pd Performance: View Data Block Buffer Hit Ratio\n"; print " -pf Performance: View Total Cumulative Free List Waits\n"; print " -ph Performance: Hot Blocks - Block With Latch Sleeps\n"; print " -pi Performance: View Histogram of Datafile I/O\n"; print " -pj Performance: I/O Distribution By Filesystem\n"; print " -pk Performance: I/O Distribution By Tablespace\n"; print " -pp Performance: I/O Service Times\n"; print " -pr List Profiles\n"; print " -ps OPS (Parallel Server) Status\n"; print " -pul Purge: Report from P_JOB_LOGGING\n"; print " -pw Performance: Show segment names for tables with buffer waits\n"; print " -qs SQL Statment Count\n"; print " -ra List Rollback Segment Activity\n"; print " -rac RAC Status (the same as orastat -ps)\n"; print " -rb List Rollback Segments\n"; print " -rc List And SHRINK All Rollback Segments\n"; print " -rd List And ALTER MAXEXTENTS UNLIMITED All Rollback Segments\n"; print " -rf View Timestamps from V\$RECOVER_FILE\n"; print " -rg View DBA_REGISTRY\n"; print " -rh List REDO Logs - History\n"; print " -rl List REDO Logs - Files\n"; print " -ro List Roles\n"; print " -rp RMAN Long Operation Progress\n"; print " -rs List REDO Logs - Status\n"; print " -ru Rollback Usage - By Session\n"; print " -sa Session Statistics - All Sessions\n"; print " -sal Session Data (All) - '$P -sal SESSION_NUMBER'\n"; print " -sb Standby DB - Show log gaps\n"; print " -sc Sessions - By Session CPU Time\n"; print " -sd Sessions - Details - Sessions, Running SQL and Waits\n"; print " -se Sessions Detail\n"; print " -sed Sessions Detail - Improved - SQL Running, Wait Class, Commit Count, etc.\n"; print " -ser Sessions Detail - Improved #2 - SQL Running, Wait Class, Commit Count, Rollback Count, etc.\n"; print " -ses Sessions Summary\n"; print " -sg List SGA Usage\n"; print " -sh Shared Pool Usage & Tuning Recommendations\n"; print " -sl SELECT * from table - name supplied as 2nd parameter\n"; print " -sn SNAPSHOT - Run systemstate trace 3 times (for Oracle diagnostics)\n"; print " -so List sorts by user\n"; print " -sp List StatsPack Snapshot Data\n"; print " -spf Display SPFILE (if any)\n"; print " -sq Run SQL - Pass SQL as argument in single quotes\n"; print " -sr View Running SQL - '$P -sr SESSION_NUMBER'\n"; print " -ss List default storage clause for all TABLESPACES\n"; print " -st System Statistics - from v\$sysstat\n"; print " -su System Utilization\n"; print " -sw Session Wait Statistics\n"; print " -sy List All Granted System Privileged\n"; print " -sz Session statistics for one session - 2nd parm is SID\n"; print " -ta List All Tables - From DBA_SEGMENTS (Name, TS, Size, Extents, Maxextents) - 2nd Arg 'ALL' to include SYS* tables\n"; print " -tb Count Tables - By Schema\n"; print " -tc Create SQL to count all rows in all permanent tables\n"; print " -td describe table - name of table supplied as 2nd parameter\n"; print " -ti Table Info - '$P -ti TABLE-OWNER.TABLE-NAME [-count]'\n"; print " -tj Datafile Space Allocated - By Filesystem\n"; print " -tm List Temporary Segments\n"; print " -tp List Objects (from DBA_SEGMENTS) By BLOCKS and BUFFER_POOL - Show buffer pool stats\n"; print " -tq Tablespaces - Details and Defaults\n"; print " -tr List Transactions\n"; print " -ts List Tablespaces\n"; print " -tt List 8i+ TEMPORARY Locally Managed Tablespaces\n"; print " -tu Temp space usage by user\n"; print " -tz List Tables - From DBA_TABLES - Shows ANALYZE data/timestamp\n"; print " -ua List USERS with incorrect default/temp tablespace - Creates SQL to ALTER USERS\n"; print " -ub List the byte count of data, by User\n"; print " -ud List Users With DBA role\n"; print " -ug List Users Table Grants (Much Output) - 2nd Parm is optional grantee name\n"; print " -un Display UNDO Statistics\n"; print " -unl Display UNDO Statistics - LONG\n"; print " -uns Display SMU UNDO Summary - Block Usage\n"; print " -up User Password Information\n"; print " -us List All Users\n"; print " -ut List the byte count of data, by User and Tablespace\n"; print " -v List Oracle version and whether it is 32-bit or 64-bit\n"; print " -vs List All Views\n"; print " -vw Count Views - By Schema\n"; print " -wr Wait Reasons - By User and Wait Type\n"; print " -ws Wait Stats - from v\$waitstat\n"; print " -zr List contents of DBAMON.STANDBY_REBUILD\n"; if ($company eq "thatcompany") { print "\n"; print "--------------------------------------------------------------------\n"; print "THATCOMPANY-Specific Commands:\n"; print " -cfbl List trace controlfile backup with create timestamp > [numeric timestamp]\n"; print "--------------------------------------------------------------------\n"; } exit 0;