로그인
Sign in

Linux 커널 2.6 이상에서는 File System 사용을 모니터링 하기 위해 block_dump라는 파라미터를 사용할 수 있다.

용도는 File System 사용 모니터링이지만, 조금 응용해보면 프로세스 별 Disk I/O 양을 확인할 수 있다. ^^


우선 이 기능을 사용하기 위해서는 아래와 같이 block_dump 커널 파라미터를 1로 수정한다.

기능을 끄려면 동일한 방법으로 block_dump 값을 0으로 바꾸기만 하면 된다.

# sysctl vm.block_dump=1
or
# echo 1 > /proc/sys/vm/block_dump


block_dump 값이 활성화 되면 Linux 커널은 아래와 같이 File System 이벤트를 시스템 로그에 기록한다.

kjournald(587): WRITE block 248048 on sda1
kjournald(587): WRITE block 248056 on sda1

...


이 값을 잘 활용하면 프로세스 별로 Disk I/O가 얼마나 일어나는지 알 수 있다.

친절하게도 "High Performance MySQL"의 저자이기도 한 Baron Schwartz가 이 데이터를 잘 분석해서 보여주는 Perl Script를 짜 놓았다.

(기특하기도 하지~ ㅎ)

wget http://aspersa.googlecode.com/svn/trunk/iodump


스크립트 파일을 열어보면 간단한 사용법이 있는데, IO를 확인하고 싶은 시간동안 돌려 두고, Ctrl + C로 인터럽트를 걸면 된다.

while 루프가 돌면서 dmesg로 계속 로그 내용을 수집하고 인터럽트가 걸리면 iodump Perl Script가 잘 정리해서 보여주는 구조다.

출력은 Block 단위로 나오는데, Linux 시스템에서는 4KB의 Block을 사용하므로 프로세스가 얼마나 많은 데이터를 Read Write 했는지 알 수 있다.

아래 예제에서는 MySQL 프로세스가 21.6MB (5549 * 4KB) 정도의 Write 작업을 한 것을 확인할 수 있다. ^^

# while true; do sleep 1; dmesg -c; done | perl iodump
# Caught SIGINT.
TASK PID TOTAL READ WRITE DIRTY DEVICES
mysqld 3928 5549 0 5549 0 sda3
kjournald 1823 24 0 24 0 sda3


결과가 조금 아쉬워서 원하는 프로세스만 vmstat 형태로 나오게 Script 처리해 본 결과~

이제 좀 쓸만해진 것 같다. ^^

TIME TASK PID TOTAL READ(Blk) WRITE(Blk) DIRTY DEVICES
10:25:00 mysqld 4124 5 0 5 0 sda3
10:25:01 mysqld 9980 11 7 4 0 sda3
10:25:01 mysqld 3896 1 1 0 0 sda3
10:25:02 mysqld 3899 144 0 144 0 sda3
10:25:02 mysqld 3835 1 0 1 0 sda3
10:25:03 - - - - - - -
10:25:04 mysqld 9980 6 2 4 0 sda3
10:25:04 mysqld 3835 1 0 1 0 sda3
10:25:05 mysqld 9980 1 1 0 0 sda3
10:25:06 - - - - - - -
10:25:07 - - - - - - -
10:25:08 mysqld 3832 6 6 0 0 sda3
10:25:08 mysqld 9980 2 2 0 0 sda3
10:25:09 mysqld 10342 22 22 0 0 sda3
10:25:09 mysqld 10092 17 17 0 0 sda1
10:25:09 mysqld 10116 1 1 0 0 sda3

TIME TASK PID TOTAL READ(Blk) WRITE(Blk) DIRTY DEVICES
10:25:10 mysqld 10342 41 34 7 0 sda3
10:25:10 mysqld 10370 4 0 4 0 sda3
10:25:10 mysqld 10371 3 0 3 0 sda3
10:25:10 mysqld 10350 2 0 2 0 sda3
10:25:11 - - - - - - -
10:25:12 mysqld 10388 1872 0 1872 0 sda3
10:25:12 mysqld 10368 803 0 803 0 sda3
10:25:13 mysqld 10388 1729 0 1729 0 sda3
10:25:13 mysqld 10368 965 0 965 0 sda3
10:25:14 mysqld 10388 2037 0 2037 0 sda3
10:25:14 mysqld 10368 670 0 670 0 sda3
10:25:15 mysqld 10388 1756 0 1756 0 sda3
10:25:16 mysqld 10368 530 0 530 0 sda3
10:25:17 mysqld 10388 1845 0 1845 0 sda3
10:25:17 mysqld 10368 849 0 849 0 sda3
10:25:19 mysqld 10388 2717 0 2717 0 sda3
10:25:20 - - - - - - -

제비게릴라

2014.01.17
17:03:06
(*.236.3.232)

#!/usr/bin/env perl
# This program is part of Aspersa (http://code.google.com/p/aspersa/)

=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 AUTHOR

Baron Schwartz

=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);
   }
}

List of Articles
번호 제목 글쓴이 날짜 조회 수
공지 자주 사용하는 명령어 제비게릴라 2019-06-27 179
212 apache2 2.4.33 소스 설치 제비게릴라 2018-10-15 41
211 oom-killer 시에 종료 순서 정하기.. 제비게릴라 2018-05-11 49
210 centos 7의 kernel.sem 설정 방법 제비게릴라 2018-05-02 128
209 ubuntu 멀티 인터페이스 설정 작업 제비게릴라 2018-02-27 11
208 yum update 시 중단 되었을때 조치 법 제비게릴라 2017-01-15 677
207 파일 사이즈 비교 제비게릴라 2016-04-29 24
206 rpm 패키징 방법 file 제비게릴라 2016-04-29 229
205 heartbeat 설정 방법 제비게릴라 2015-10-19 374
204 oracle 계정으로 ssh 접속시 Key 인증 방식의 로그인 오류 발생 조치 제비게릴라 2015-10-06 52
203 리눅스 date 명령 : 어제(과거) , 내일(미래) 날짜, 시간 구하기 제비게릴라 2015-03-20 106
202 redhat 커널 버전 리스트 제비게릴라 2015-02-10 65
201 문자열 추출 쉘 스크립트... 제비게릴라 2014-09-25 62
200 Partition 1 does not start on physical sector boundary. 메세지 삭제... 제비게릴라 2014-08-28 154
199 vi 치환 명령 제비게릴라 2014-03-12 173
» 프로세스 별 Disk I/O 확인 방법 (block_dump) [1] 제비게릴라 2013-07-16 854
197 logger 옵션... 제비게릴라 2013-05-27 369
196 vsftpd 시간 맞추기... 제비게릴라 2013-05-27 330
195 Linux Kernel Tuning 제비게릴라 2013-03-21 446
194 자동으로 멀티패스 잡았을시 블랙리스트 추가하기.. 제비게릴라 2012-12-06 1387
193 Nmon Analyser v33g – Excel 2010 64 bits file 하록 2012-08-07 551