Monitoring Disk IO per process
From Zarafa wiki
Ynypokizek (Talk | contribs) |
Ddebyttere (Talk | contribs) m (Reverted edits by Ynypokizek (talk) to last revision by Msartor) |
||
| Line 1: | Line 1: | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
== Monitoring disk IO per process == | == Monitoring disk IO per process == | ||
| - | + | <BR> | |
| - | + | <font color=red>'''This article is a community contribution and may include unsupported configurations.''' </font> | |
| - | + | <BR><BR> | |
Newer Linux kernels have per-process I/O accounting and you can use the iotop tool to find out what’s performing I/O, but in some cases you'll want to find the source of an I/O problem in an older kernel. This article will describe a way to do I/O accounting per process on older kernels. | Newer Linux kernels have per-process I/O accounting and you can use the iotop tool to find out what’s performing I/O, but in some cases you'll want to find the source of an I/O problem in an older kernel. This article will describe a way to do I/O accounting per process on older kernels. | ||
| Line 16: | Line 8: | ||
'''First get this script and name it: iodump''' | '''First get this script and name it: iodump''' | ||
| - | + | <pre> | |
#!/usr/bin/env perl | #!/usr/bin/env perl | ||
| Line 58: | Line 50: | ||
my $oktorun = 1; | my $oktorun = 1; | ||
my $line; | my $line; | ||
| - | while ( $oktorun & | + | while ( $oktorun && (defined ($line = <>)) ) { |
my ( $task, $pid, $activity, $where, $device ); | my ( $task, $pid, $activity, $where, $device ); | ||
( $task, $pid, $activity, $where, $device ) | ( $task, $pid, $activity, $where, $device ) | ||
| Line 77: | Line 69: | ||
qw(TASK PID TOTAL READ WRITE DIRTY DEVICES)); | qw(TASK PID TOTAL READ WRITE DIRTY DEVICES)); | ||
foreach my $task ( | foreach my $task ( | ||
| - | reverse sort { $a->{activity} | + | reverse sort { $a->{activity} <=> $b->{activity} } values %tasks |
) { | ) { | ||
printf("%-15s %10d %10d %10d %10d %10d %s\n", | printf("%-15s %10d %10d %10d %10d %10d %s\n", | ||
| Line 99: | Line 91: | ||
} | } | ||
} | } | ||
| - | + | </pre> | |
'''Then turn on kernel messages about I/O:''' | '''Then turn on kernel messages about I/O:''' | ||
| - | + | <pre> | |
echo 1 > /proc/sys/vm/block_dump | echo 1 > /proc/sys/vm/block_dump | ||
| - | + | </pre> | |
'''This makes the kernel start writing messages about every I/O operation that takes place. Now all you have to do is get those messages and feed them into the iodump script:''' | '''This makes the kernel start writing messages about every I/O operation that takes place. Now all you have to do is get those messages and feed them into the iodump script:''' | ||
| - | + | <pre> | |
while true; do sleep 1; dmesg -c; done | perl iodump | while true; do sleep 1; dmesg -c; done | perl iodump | ||
| - | + | </pre> | |
'''Wait a little while, then cancel the script. The results should look something like the following:''' | '''Wait a little while, then cancel the script. The results should look something like the following:''' | ||
| - | + | <pre> | |
# while true; do sleep 1; dmesg -c; done | perl iodump | # while true; do sleep 1; dmesg -c; done | perl iodump | ||
^C# Caught SIGINT. | ^C# Caught SIGINT. | ||
| Line 130: | Line 122: | ||
firefox 28307 1 1 0 0 sda4 | firefox 28307 1 1 0 0 sda4 | ||
firefox 28451 1 1 0 0 sda4 | firefox 28451 1 1 0 0 sda4 | ||
| - | + | </pre> | |
'''When finished, turn off kernel messages about I/O:''' | '''When finished, turn off kernel messages about I/O:''' | ||
| - | + | <pre> | |
echo 0 > /proc/sys/vm/block_dump | echo 0 > /proc/sys/vm/block_dump | ||
| - | + | </pre> | |
Latest revision as of 09:11, 24 November 2010
Monitoring disk IO per process
This article is a community contribution and may include unsupported configurations.
Newer Linux kernels have per-process I/O accounting and you can use the iotop tool to find out what’s performing I/O, but in some cases you'll want to find the source of an I/O problem in an older kernel. This article will describe a way to do I/O accounting per process on older kernels.
First get this script and name it: iodump
#!/usr/bin/env perl
=pod
=head1 NAME
iodump - Compute per-PID I/O stats for Linux when iotop/pidstat/iopp are not available.
=head1 SYNOPSIS
Prepare the system:
dmesg -c
/etc/init.d/klogd stop
echo 1 > /proc/sys/vm/block_dump
Start the reporting:
while true; do sleep 1; dmesg -c; done | perl iodump
CTRL-C
Stop the system from dumping these messages:
echo 0 > /proc/sys/vm/block_dump
/etc/init.d/klogd start
=head1 LICENSE
This software is released to the public domain, with no guarantees whatsoever.
=cut
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use sigtrap qw(handler finish untrapped normal-signals);
my %tasks;
my $oktorun = 1;
my $line;
while ( $oktorun && (defined ($line = <>)) ) {
my ( $task, $pid, $activity, $where, $device );
( $task, $pid, $activity, $where, $device )
= $line =~ m/(\S+)\((\d+)\): (READ|WRITE) block (\d+) on (\S+)/;
if ( !$task ) {
( $task, $pid, $activity, $where, $device )
= $line =~ m/(\S+)\((\d+)\): (dirtied) inode \(.*?\) (\d+) on (\S+)/;
}
if ( $task ) {
my $s = $tasks{$pid} ||= { pid => $pid, task => $task };
++$s->{lc $activity};
++$s->{activity};
++$s->{devices}->{$device};
}
}
printf("%-15s %10s %10s %10s %10s %10s %s\n",
qw(TASK PID TOTAL READ WRITE DIRTY DEVICES));
foreach my $task (
reverse sort { $a->{activity} <=> $b->{activity} } values %tasks
) {
printf("%-15s %10d %10d %10d %10d %10d %s\n",
$task->{task}, $task->{pid},
($task->{'activity'} || 0),
($task->{'read'} || 0),
($task->{'write'} || 0),
($task->{'dirty'} || 0),
join(', ', keys %{$task->{devices}}));
}
sub finish {
my ( $signal ) = @_;
if ( $oktorun ) {
print STDERR "# Caught SIG$signal.\n";
$oktorun = 0;
}
else {
print STDERR "# Exiting on SIG$signal.\n";
exit(1);
}
}
Then turn on kernel messages about I/O:
echo 1 > /proc/sys/vm/block_dump
This makes the kernel start writing messages about every I/O operation that takes place. Now all you have to do is get those messages and feed them into the iodump script:
while true; do sleep 1; dmesg -c; done | perl iodump
Wait a little while, then cancel the script. The results should look something like the following:
# while true; do sleep 1; dmesg -c; done | perl iodump ^C# Caught SIGINT. TASK PID TOTAL READ WRITE DIRTY DEVICES firefox 4450 4538 251 4287 0 sda4, sda3 kjournald 2100 551 0 551 0 sda4 firefox 28452 185 185 0 0 sda4 kjournald 782 59 0 59 0 sda3 pdflush 31 30 0 30 0 sda4, sda3 syslogd 2485 2 0 2 0 sda3 firefox 28414 2 2 0 0 sda4, sda3 firefox 28413 1 1 0 0 sda4 firefox 28410 1 1 0 0 sda4 firefox 28307 1 1 0 0 sda4 firefox 28451 1 1 0 0 sda4
When finished, turn off kernel messages about I/O:
echo 0 > /proc/sys/vm/block_dump