./asmiostat.sh -s $ORACLE_SID -h $ORACLE_HOME -g DATA 1
每秒io监控
DiskPath - DiskName Gr Dsk Reads Writes AvRdTm AvWrTm KBRd KBWr AvRdSz AvWrSz RdEr WrEr /dev/raw/raw3 - DATA_0000 2 0 1085 0 1.1 0.0 97656 0 92165 0 0 0 /dev/raw/raw4 - DATA_0001 2 1 1064 22 1.2 1.8 0 0 0 0 0 0 /dev/raw/raw5 - DATA_0002 2 2 1084 0 1.0 0.0 0 0 0 0 0 0 Date: Thu Jul 2 15:29:01 CST 2020 Interval: 1 secs Disk Group: DATA DiskPath - DiskName Gr Dsk Reads Writes AvRdTm AvWrTm KBRd KBWr AvRdSz AvWrSz RdEr WrEr /dev/raw/raw3 - DATA_0000 2 0 1076 0 1.1 0.0 0 0 0 0 0 0 /dev/raw/raw4 - DATA_0001 2 1 1087 33 1.3 4.1 97656 976 91996 30303 0 0 /dev/raw/raw5 - DATA_0002 2 2 1086 1 0.9 1.1 97656 0 92081 0 0 0 Date: Thu Jul 2 15:29:02 CST 2020 Interval: 1 secs Disk Group: DATA DiskPath - DiskName Gr Dsk Reads Writes AvRdTm AvWrTm KBRd KBWr AvRdSz AvWrSz RdEr WrEr /dev/raw/raw3 - DATA_0000 2 0 1077 0 1.1 0.0 0 0 0 0 0 0 /dev/raw/raw4 - DATA_0001 2 1 1056 26 1.0 5.6 0 0 0 0 0 0 /dev/raw/raw5 - DATA_0002 2 2 1125 0 0.9 0.0 0 0 0 0 0 0 Date: Thu Jul 2 15:29:03 CST 2020 Interval: 1 secs Disk Group: DATA DiskPath - DiskName Gr Dsk Reads Writes AvRdTm AvWrTm KBRd KBWr AvRdSz AvWrSz RdEr WrEr /dev/raw/raw3 - DATA_0000 2 0 1169 0 1.3 0.0 97656 0 85543 0 0 0 /dev/raw/raw4 - DATA_0001 2 1 1039 10 0.9 36.8 0 0 0 0 0 0 /dev/raw/raw5 - DATA_0002 2 2 1085 0 0.9 0.0 0 0 0 0 0 0 Date: Thu Jul 2 15:29:04 CST 2020 Interval: 1 secs Disk Group: DATA DiskPath - DiskName Gr Dsk Reads Writes AvRdTm AvWrTm KBRd KBWr AvRdSz AvWrSz RdEr WrEr /dev/raw/raw3 - DATA_0000 2 0 1155 0 1.2 0.0 0 0 0 0 0 0 /dev/raw/raw4 - DATA_0001 2 1 1053 13 0.9 1.3 97656 0 94966 0 0 0 /dev/raw/raw5 - DATA_0002 2 2 1025 1 0.9 1.0 97656 0 97560 0 0 0 Date: Thu Jul 2 15:29:05 CST 2020 Interval: 1 secs Disk Group: DATA DiskPath - DiskName Gr Dsk Reads Writes AvRdTm AvWrTm KBRd KBWr AvRdSz AvWrSz RdEr WrEr /dev/raw/raw3 - DATA_0000 2 0 643 0 1.5 0.0 0 0 0 0 0 0 /dev/raw/raw4 - DATA_0001 2 1 816 10 1.6 80.3 0 0 0 0 0 0 /dev/raw/raw5 - DATA_0002 2 2 831 0 1.2 0.0 0 0 0 0 0 0
附脚本源码:
asmiostat.sh
#!/bin/ksh # # NAME # asmiostat.sh # # DESCRIPTION # iostat-like output for ASM # $ asmiostat.sh [-s ASM ORACLE_SID] [-h ASM ORACLE_HOME] [-g Diskgroup] # [-f disk path filter] [<interval>] [<count>] # # NOTES # Creates persistent SQL*Plus connection to the +ASM instance implemented # as a ksh co-process # # AUTHOR # Doug Utzig # # MODIFIED # dutzig 08/18/05 - original version # ORACLE_SID=+ASM NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1 NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS' endOfOutput="_EOP$$" typeset -u diskgroup typeset diskgroup_string="Disk Group: All diskgroups" typeset usage=" $0 [-s ASM ORACLE_SID] [-h ASM ORACLE_HOME] [-g diskgroup] [<interval>] [<count>] Output: DiskPath - Path to ASM disk DiskName - ASM disk name Gr - ASM disk group number Dsk - ASM disk number Reads - Reads Writes - Writes AvRdTm - Average read time (in msec) AvWrTm - Average write time (in msec) KBRd - Kilobytes read KBWr - Kilobytes written AvRdSz - Average read size (in bytes) AvWrSz - Average write size (in bytes) RdEr - Read errors WrEr - Write errors " while getopts ":s:h:g:f" option; do case $option in s) ORACLE_SID="$OPTARG" ;; h) ORACLE_HOME="$OPTARG" LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH ;; g) diskgroup="$OPTARG" diskgroup_string="Disk Group: $diskgroup" ;; f) print '-f option not implemented' ;; :) print "Option $OPTARG needs a value" print "$usage" exit 1 ;; \?) print "Invalid option $OPTARG" print "$usage" exit 1 ;; esac done shift OPTIND-1 typeset -i interval=${1:-10} count=${2:-0} index=0 # # Verify interval and count arguments are valid # (( interval <=0 || count<0 )) && { print 'Invalid parameter: <interval> must be > 0; <count> must be >= 0' print "$usage" exit 1 } # # Query to run against v$asm_disk_stat # if [[ -z $diskgroup ]]; then query="select group_number, disk_number, name, path, reads, writes, read_errs, write_errs, read_time, write_time, bytes_read, bytes_written from v\$asm_disk_stat where group_number>0 order by group_number, disk_number;" else query="select group_number, disk_number, name, path, reads, writes, read_errs, write_errs, read_time, write_time, bytes_read, bytes_written from v\$asm_disk_stat where group_number=(select group_number from v\$asm_diskgroup_stat where name=regexp_replace('$diskgroup','^\+','')) order by group_number, disk_number;" fi # # Check for version 10.2 or later # typeset version minversion=10.2 version=$($ORACLE_HOME/bin/exp </dev/null 2>&1 | grep "Export: " | sed -e 's/^Export: Release \([0-9][0-9]*\.[0-9][0-9]*\).*/\1/') if ! (print "$version<$minversion" | bc >/dev/null 2>&1); then print "$0 requires Oracle Database Release $minversion or later" exit 1 fi ############################################################################# # # Fatal error #---------------------------------------------------------------------------- function fatalError { print -u2 -- "Error: $1" exit 1 } ############################################################################# # # Drain all of the sqlplus output - stop when we see our well known string #---------------------------------------------------------------------------- function drainOutput { typeset dispose=${1:-'dispose'} output while :; do read -p output || fatalError 'Read from co-process failed [$0]' if [[ $QUERYDEBUG == ON ]]; then print $output; fi if [[ $output == $endOfOutput* ]]; then break; fi [[ $dispose != 'dispose' ]] && print -- $output done } ############################################################################# # # Ensure the instance is running and it is of type ASM #---------------------------------------------------------------------------- function verifyASMinstance { typeset asmcmdPath=$ORACLE_HOME/bin/asmcmd [[ ! -x $asmcmdPath ]] && fatalError "Invalid ORACLE_HOME $ORACLE_HOME: $asmcmdPath does not exist" $asmcmdPath pwd 2>/dev/null | grep -q '^\+$' || fatalError "$ORACLE_SID is not an ASM instance" } ############################################################################# # # Start the sqlplus coprocess #---------------------------------------------------------------------------- function startSqlplus { # start sqlplus, setup the env $ORACLE_HOME/bin/sqlplus -s '/ as sysdba' |& print -p 'whenever sqlerror exit failure' \ && print -p "set pagesize 9999 linesize 9999 feedback off heading off" \ && print -p "prompt $endOfOutput" \ || fatalError 'Write to co-process failed (startSqlplus)' drainOutput dispose } ############################################################################# ############################################################################# # MAIN #---------------------------------------------------------------------------- verifyASMinstance startSqlplus # # Loop as many times as requested or forever # while :; do print -p "$query" \ && print -p "prompt $endOfOutput" \ || fatalError 'Write to co-process failed (collectData)' stats=$(drainOutput keep) print -- "$stats\nEOL" index=index+1 (( count<index && count>0 )) && break sleep $interval done | \ awk ' BEGIN { firstSample=1 } /^EOL$/ { firstSample=0; firstLine=1 next } { path=$4 if (path ~ /^ *$/) next group[path]=$1; disk[path]=$2; name[path]=$3 reads[path]=$5; writes[path]=$6 readErrors[path]=$7; writeErrors[path]=$8 readTime[path]=$9; writeTime[path]=$10 readBytes[path]=$11; writeBytes[path]=$12 # reads and writes readsDiff[path]=reads[path]-readsPrev[path] writesDiff[path]=writes[path]-writesPrev[path] # read errors and write errors readErrorsDiff[path]=readErrors[path]-readErrorsPrev[path] writeErrorsDiff[path]=writeErrors[path]-writeErrorsPrev[path] # read time and write time readTimeDiff[path]=readTime[path]-readTimePrev[path] writeTimeDiff[path]=writeTime[path]-writeTimePrev[path] # average read time and average write time in msec (data provided in csec) avgReadTime[path]=0; avgWriteTime[path]=0 if ( readsDiff[path] ) avgReadTime[path]=(readTimeDiff[path]/readsDiff[path])*1000 if ( writesDiff[path]) avgWriteTime[path]=(writeTimeDiff[path]/writesDiff[path])*1000 # bytes and KB read and bytes and KB written readBytesDiff[path]=readBytes[path]-readBytesPrev[path] writeBytesDiff[path]=writeBytes[path]-writeBytesPrev[path] readKb[path]=readBytesDiff[path]/1024 writeKb[path]=writeBytesDiff[path]/1024 # average read size and average write size avgReadSize[path]=0; avgWriteSize[path]=0 if ( readsDiff[path] ) avgReadSize[path]=readBytesDiff[path]/readsDiff[path] if ( writesDiff[path] ) avgWriteSize[path]=writeBytesDiff[path]/writesDiff[path] if (!firstSample) { if (firstLine) { "date" | getline now; close("date") printf "\n" printf "Date: %s Interval: %d secs %s\n\n", now, '"$interval"', "'"$diskgroup_string"'" printf "%-40s %2s %3s %8s %8s %6s %6s %8s %8s %7s %7s %4s %4s\n", \ "DiskPath - DiskName","Gr","Dsk","Reads","Writes","AvRdTm",\ "AvWrTm","KBRd","KBWr","AvRdSz","AvWrSz", "RdEr", "WrEr" firstLine=0 } printf "%-40s %2s %3s