--- mytop.orig 2013-03-21 21:26:04 UTC +++ mytop @@ -189,22 +189,24 @@ if ($HAS_COLOR) } else { - *RESET = sub { }; - *YELLOW = sub { }; - *RED = sub { }; - *GREEN = sub { }; - *BLUE = sub { }; - *WHITE = sub { }; - *BOLD = sub { }; + *RESET = sub { }; + *YELLOW = sub { }; + *RED = sub { }; + *GREEN = sub { }; + *BLUE = sub { }; + *WHITE = sub { }; + *BOLD = sub { }; + *MAGENTA = sub { }; } -my $RESET = RESET() || ''; -my $YELLOW = YELLOW() || ''; -my $RED = RED() || ''; -my $GREEN = GREEN() || ''; -my $BLUE = BLUE() || ''; -my $WHITE = WHITE() || ''; -my $BOLD = BOLD() || ''; +my $RESET = RESET() || ''; +my $YELLOW = YELLOW() || ''; +my $RED = RED() || ''; +my $GREEN = GREEN() || ''; +my $BLUE = BLUE() || ''; +my $WHITE = WHITE() || ''; +my $BOLD = BOLD() || ''; +my $MAGENTA = MAGENTA() || ''; ## Connect @@ -372,6 +374,10 @@ while (1) require Data::Dumper; print Data::Dumper::Dumper([\%config]); ReadKey(0); + + if (-M $0) { # Restart application, if modified (for debugging) + exec('perl', $0, @ARGV); + } } ## m - mode swtich to qps @@ -380,7 +386,7 @@ while (1) { $config{mode} = 'qps'; Clear() unless $config{batchmode}; - print "Queries Per Second [hit q to exit this mode]\n"; + print "Queries Per Second [hit q to exit, hit t for top mode]\n"; next; } @@ -803,8 +809,15 @@ sub GetData() ## Queries per second... - my $avg_queries_per_sec = sprintf("%.2f", $STATUS{Questions} / $STATUS{Uptime}); - my $num_queries = $STATUS{Questions}; + my ($num_queries, $old_num_queries); + if(defined($STATUS{Queries})) { + $num_queries = $STATUS{Queries}; + $old_num_queries = $OLD_STATUS{Queries}; + } else { + $num_queries = $STATUS{Questions}; + $old_num_queries = $OLD_STATUS{Questions}; + } + my $avg_queries_per_sec = sprintf("%.2f", $num_queries / $STATUS{Uptime}); my @t = localtime(time); @@ -822,26 +835,26 @@ sub GetData() $lines_left--; - printf " Queries: %-5s qps: %4.0f Slow: %7s Se/In/Up/De(%%): %02.0f/%02.0f/%02.0f/%02.0f \n", - make_short( $STATUS{Questions} ), # q total - $STATUS{Questions} / $STATUS{Uptime}, # qps, average + printf " Queries: %-6s qps: %4.0f Slow: %7s Se/In/Up/De(%%): %02.0f/%02.0f/%02.0f/%02.0f \n", + make_short( $num_queries ), # q total + $num_queries / $STATUS{Uptime}, # qps, average make_short( $STATUS{Slow_queries} ), # slow # hmm. a Qcache hit is really a select and should be counted. - 100 * ($STATUS{Com_select} + ($STATUS{Qcache_hits}||0) ) / $STATUS{Questions}, - 100 * ($STATUS{Com_insert} + $STATUS{Com_replace} ) / $STATUS{Questions}, - 100 * ($STATUS{Com_update} ) / $STATUS{Questions}, - 100 * $STATUS{Com_delete} / $STATUS{Questions}; + 100 * ($STATUS{Com_select} + ($STATUS{Qcache_hits}||0) ) / $num_queries, + 100 * ($STATUS{Com_insert} + $STATUS{Com_replace} ) / $num_queries, + 100 * ($STATUS{Com_update} ) / $num_queries, + 100 * $STATUS{Com_delete} / $num_queries; $lines_left--; if ($t_delta) { - my $q_diff = ( $STATUS{Questions} - $OLD_STATUS{Questions} ); -# print("q_diff: $STATUS{Questions} - $OLD_STATUS{Questions} / $t_delta = $q_diff\n"); + my $q_diff = ( $num_queries - $old_num_queries ); +# print("q_diff: $num_queries - $old_num_queries / $t_delta = $q_diff\n"); printf(" qps now: %4.0f Slow qps: %3.1f Threads: %4.0f (%4.0f/%4.0f) %02.0f/%02.0f/%02.0f/%02.0f \n", - ( $STATUS{Questions} - $OLD_STATUS{Questions} ) / $t_delta, + ( $num_queries - $old_num_queries ) / $t_delta, ( # slow now (qps) ($STATUS{Slow_queries} ) ? ( $STATUS{Slow_queries} - $OLD_STATUS{Slow_queries} ) / $t_delta : @@ -851,7 +864,7 @@ sub GetData() $STATUS{Threads_running}, $STATUS{Threads_cached}, - (100 * ($STATUS{Com_select} - $OLD_STATUS{Com_select} + + (100 * ($STATUS{Com_select} - $OLD_STATUS{Com_select} + ($STATUS{Qcache_hits}||0) - ($OLD_STATUS{Qcache_hits}||0) ) ) / ($q_diff ), (100 * ($STATUS{Com_insert} - $OLD_STATUS{Com_insert} + @@ -869,11 +882,11 @@ sub GetData() if ($have_query_cache and $STATUS{Com_select} and $query_cache_hits) { - printf(" Cache Hits: %-5s Hits/s: %4.1f Hits now: %5.1f Ratio: %4.1f%% Ratio now: %4.1f%% \n", + printf(" Cache Hits: %-5s Hits/s: %4.1f Hits now: %5.1f Ratio: %4.1f%% Ratio now: %4.1f%% \n", make_short($STATUS{Qcache_hits}), # cache hits $STATUS{Qcache_hits} / $STATUS{Uptime}, # hits / sec ($t_delta) ? ($STATUS{Qcache_hits} - $OLD_STATUS{Qcache_hits}) / $t_delta : 0, # now / s - # ratio: + # ratio: 100 * ($STATUS{Qcache_hits}) / ($STATUS{Qcache_hits} + $STATUS{Com_select} ), ($t_delta) ? # ratio now 100 * ($STATUS{Qcache_hits} - $OLD_STATUS{Qcache_hits} ) / @@ -892,7 +905,42 @@ sub GetData() make_short(($STATUS{Bytes_received} - $OLD_STATUS{Bytes_received}) / $t_delta ), make_short(($STATUS{Bytes_sent} - $OLD_STATUS{Bytes_sent}) / $t_delta )) if ($t_delta); - print "\n\n"; + print "\n"; + + my @master_status = Hashes("show master status"); + if (@master_status) + { + foreach my $m (@master_status) { + print " Master: $m->{File}/$m->{Position} ", + "do: ", GREEN(), "$m->{Binlog_Do_DB} ", RESET(), + "ign: ", MAGENTA(), $m->{Binlog_Ignore_DB}, RESET(), "\n"; + #$line_prefix = ' ' x length($line_prefix); + $lines_left--; + } + } + + my @slave_status = Hashes("show slave status"); + if (@slave_status) + { + my $line_prefix = " Slave: "; + foreach my $s (@slave_status) { + print $line_prefix, BOLD(), + ($s->{Slave_IO_Running} eq 'Yes' + && $s->{Slave_SQL_Running} eq 'Yes' + && $s->{Last_Errno} == 0 + ? ($s->{Seconds_Behind_Master} > 60 ? BOLD('WARN') : GREEN('OK ')) : RED('ERR ') + ), RESET(), + " Delay: ", + defined($s->{Seconds_Behind_Master}) ? sprintf('%03d:%02d', int($s->{Seconds_Behind_Master} / 60), $s->{Seconds_Behind_Master} % 60) : '---:--', + " $s->{Master_User}\@$s->{Master_Host}: ", + "$s->{Master_Log_File}/$s->{Read_Master_Log_Pos} ", + "\n"; + #$line_prefix = ' ' x length($line_prefix); + $lines_left--; + } + } + + print "\n"; $lines_left--; } @@ -907,32 +955,22 @@ sub GetData() ## Threads ## - #my $sz = $width - 52; - my @sz = (9, 9, 15, 10, 9, 6); - my $used = scalar(@sz) + Sum(@sz); - my $free = $width - $used; - - print BOLD(); - - printf "%8s %9s %15s %10s %9s %6s %-${free}s\n", - 'Id','User','Host/IP','DB','Time', 'Cmd', 'Query or State'; - - print RESET(); - - ## Id User Host DB - printf "%9s %9s %15s %10s %9s %6s %-${free}s\n", - '--','----','-------','--','----', '---', '----------'; - $lines_left -= 2; my $proc_cmd = "show full processlist"; my @data = Hashes($proc_cmd); + my $max_id = 0; + foreach my $thread (@data) { last if not $lines_left; + if ($max_id < $thread->{Id}) { + $max_id = $thread->{Id}; + } + ## Drop Domain Name, unless it looks like an IP address. If ## it's an IP, we'll strip the port number because it's rarely ## interesting. @@ -955,8 +993,11 @@ sub GetData() { $thread->{Host} =~ s/:\d+$//; my $host = gethostbyaddr(inet_aton($thread->{Host}), AF_INET); - $host =~ s/^([^.]+).*/$1/; - $thread->{Host} = $host; + if ($host) + { + $host =~ s/^([^.]+).*/$1/; + $thread->{Host} = $host; + } } ## Fix possible undefs @@ -993,6 +1034,23 @@ sub GetData() } + #my $sz = $width - 52; + my $max_id_size = length $max_id; + my @sz = ($max_id_size, 9, 15, 10, 9, 6); + my $used = scalar(@sz) + Sum(@sz); + my $free = $width - $used; + + print BOLD(); + + printf "%${max_id_size}s %9s %15s %10s %9s %6s %-${free}s\n", + 'Id','User','Host/IP','DB','Time', 'Cmd', 'Query or State'; + + print RESET(); + + ## Id User Host DB + printf "%${max_id_size}s %9s %15s %10s %9s %6s %-${free}s\n", + '--','----','-------','--','----', '---', '----------'; + ## Sort by idle time (closest thing to CPU usage I can think of). my @sorted; @@ -1047,7 +1105,7 @@ sub GetData() print GREEN() if $thread->{Command} eq 'Connect'; } - printf "%9d %9.9s %15.15s %10.10s %9d %6.6s %-${free}.${free}s\n", + printf "%${max_id_size}d %9.9s %15.15s %10.10s %9d %6.6s %-${free}.${free}s\n", $thread->{Id}, $thread->{User}, $thread->{Host}, $thread->{db}, $thread->{Time}, $thread->{Command}, $smInfo; @@ -1102,8 +1160,8 @@ sub GetInnoDBStatus() my @data = Hashes("SHOW INNODB STATUS"); open P, "|$config{pager}" or die "$!"; - print keys %{$data[0]}; - print $data[0]->{Status},"\n"; + print P keys %{$data[0]}; + print P $data[0]->{Status},"\n"; close P; }