Category Archives: System

Linux #24 : Remote Syslog Configuration

이번 내용은 Remote Syslog Server를 구축하는 방법입니다. 요즘은 더욱 강화된 rsyslog를 더 많이 사용하고 있는데, 그 건 다음시간에 다루도록 하겠습니다.
일단 일반 Syslog 서버를 Remote Syslog 서버로 바꾸기 위해서는 아래와 같은 설정이 필요합니다.

Remote Syslog Server
Change configuration file /etc/sysconfig/syslog

# vi /etc/sysconfig/syslog
..
SYSLOGD_OPTIONS="-m 0" => SYSLOGD_OPTIONS="-m 0 -r"
..
:wq!

-r means receiving log data from the other servers.

Restart Syslog daemon

# /etc/init.d/syslog restart or service syslog restart

그리곤, Target이 될 각 Server를 설정하면 됩니다.

Changing configuration file /etc/syslog.conf

# vi /etc/syslog.conf
..
kern.warining;*.err;authpriv.none @syslog
*.info;mail.none;authpriv.none;cron.none @syslog
authpriv.* @syslog
*.emerg @syslog
local7.* @syslog
..
:wq!

@syslog라고 입력을 했는데, 이 경우 /etc/hosts에 syslog의 IP가 정의 되어 있거나 /etc/resolv.conf에 base domain이 정의가 되어 있어야 겠죠.

# vi /etc/hosts
..
192.168.1.10 syslog
..

or

# vi /etc/resolv.conf
search techiess.com
nameserver 192.168.1.1
nameserver 192.168.1.2

그리고, 다시 Restart Syslog daemon 하면 완료가 됩니다.
또한, Log Processing, Parsing tool들을 사용하면 Log를 통합해서 모니터링 할 수 있습니다.

Syslog를 Remote로 전송하는 경우 TCP/UDP 514 Port를 사용하게 되는데 단점이 전송해야하는 Log의 양이 많아지는 경우는 Log의 Lost가 발생 할 수 있습니다.
따라서, Log를 전송해야만 하는 것들만 처리 될 수 있도록 Front Filtering을 고려하면 Network Traffic도 Saving하고 더욱 효율이 좋아질 것 입니다.

Syslog는 일반적으로 사용되는 Log tool인데, rsyslog, syslog-ng 등 좀 더 다양한 기능을 구현 할 수 있는 Log tool도 있습니다.
이런 것들은 다음 시간에 다루도록 하겠습니다.

Linux #21 : MySQL Log를 Syslog(Remote Syslog)로 관리

정말 오래간만에 하는 포스팅 인듯 하네요. = =;

MySQL의 Error log를 Remote Syslog를 통해서 관리를 해보고자 아래와 같이 Script를 만들어 보았습니다.
Syslog 수집 서버를 구성하고 수집 서버를 통해서 MySQL Error Log를 통합 관리 하기 위하여 사용하고 있습니다.
Remote Syslog 수집 서버에 개발해 놓은 Application에 Filtering 기능을 이용하여 MySQL과 관련 된 Critical Log를 검출하여
Alert를 발생시키는 구조입니다.

### MYSQL_LOG_TO_SYSLOG.SH
#!/bin/sh
# ================================================================
# -process
# Mysql Alert Log to Remote Syslog
# -process content
# Mysql Alert Log to Remote Syslog
# -how to use
# Mysql_Log_To_Syslog.sh
#
# -NOTE
#
# -created date
# 2010/05/17 Jeff Kim
#
# ================================================================
##################################################################
MYSQL_VAR=[MySQL Var Directory]
FACILITY=syslog
PRIORITY=info
HOSTNAME=`hostname`
SCRIPT_NAME="MYSQL ALERT LOG TO SYSLOG"

function Printmsg {
TYPE="$1"
TEXT="$2"
echo "`date \"+%Y-%m-%d %H:%M\"` [$1] $2" >> $TMP/message.log
echo "`date \"+%Y-%m-%d %H:%M\"` [$1] $2"
logger -p daemon.notice "[$1] $2"
}

function Endscript {
Printmsg "INFO" "End Script : $SCRIPT_NAME."
echo "################################################################################################"
exit
}

function Startscript {
SCRIPT_START="$INIT_SCRIPTS"
if [ -z "$SCRIPT_START" ];then
cat < ###############################################################################################
$DATE_TIME [INFO] ### $SCRIPT_NAME ###
EOF
fi

#if [ "$SCRIPT_START" != ""y"" ];then
# Endscript
#else
# Printmsg "INFO" "Pressed 'y' : $SCRIPT_NAME"
#fi
}

function Whoamiroot {
WHOAMI=`whoami`
if [ "$WHOAMI" != "root" ];then
Printmsg "ERROR" "Permission deny. Only root!"
Printmsg "INFO" "Forced-end this script."
Endscript
fi
}

Startscript

if [ "$HOSTNAME" = "" ];then
Printmsg "ERROR" "Please, Check Host Name.";Endscript
else
Printmsg "INFO" "nohup tail -f ${MYSQL_VAR}/${HOSTNAME}.err | logger -t MySQL -p ${FACILITY}.${PRIORITY} &"
nohup tail -f ${MYSQL_VAR}/${HOSTNAME}.err | logger -t MySQL -p ${FACILITY}.${PRIORITY} &
fi
Endscript

script가 실행되고 있고, remote syslog 서버에 Log를 보내는 설정이 되어 있다면 MySQL Error가 발생하는 즉시 Syslog와 Remote Syslog 서버에 MySQL 관련 Log가 기록이 됩니다. 그리고 이 로그를 다시 재처리하면 MySQL의 Log를 모니터링 할 수 있지요.

Linux #22 : IO Monitoring with Cacti #1

iostat command를 통해서 IO Status Data를 수집하는데 Cacti로 Graph를 그리기 위해서 아래와 같이 매일 1분단위로 Data를 수집합니다.
60 (Sec) / 1441 (1일). Crontab에 등록하여 그날 그날의 Data가 저장되도록 rotate를 합니다.

#!/bin/sh
# ================================================================
# -process
# Gathering IOstat data per day
# -process content
# Gathering IOstat data per day
# -how to use
# Gathering_iostat_per_day.sh
# in crontab (everyday 23:59)
# 59 23 * * * [File Location Directory]/Gathering_iostat_per_day.sh
#
# -NOTE
#
# -created date
# 2011/08/17 Jeff Kim
#
# ================================================================
BASE=[File Location Directory]
##################################################################

iostat -xt 60 1441 > $BASE/iostat_`date +%Y%m%d -d +1day` &
iostat -dt 60 1441 > BASE/iostat_tps_`date +%Y%m%d -d +1day` &

iostat에서 측정가능한 Parameter에 대한 iostat key를 만들었는데 아래와 같습니다. 개별 Parameter의 Data 추출시 이용하게 됩니다.
뒤에 나오게 되는 Script를 보시면 이 Key가 Cacti에서 Index로 사용됩니다.

$ more iostat_key.infodevice:
tps:
brs:
bws:
br:
bw:
rrqms:
wrqms:
rs:
ws:
rsecs:
wsecs:
rkbs:
wkbs:
avgrqsz:
avgqusz:
await:
svctm:
util:

또, 개별 Device에 대한 측정값이므로 device Key를 만들었고 아래와 같습니다. EMC Storage를 사용하고 있어서 emcpower[X]라는 device name이고 device에 따라 name이 다르므로 수정해야 합니다.

$ more device.infoemcpowerb
emcpowerd

예로 iostat -xt 를 찍어보면 아래와 같이 출력됩니다.

$ iostat -xt
Linux [Kernel Version] ([HostName]) 12/14/2011 _x86_64_ (8 CPU)

12/14/2011 11:26:15 AM
avg-cpu: %user %nice %system %iowait %steal %idle
1.66 0.00 0.50 0.94 0.00 96.90

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.06 1.90 13.29 1.16 187.92 24.52 14.71 0.11 7.49 1.90 2.74
cciss/c0d0 0.00 12.62 1.53 2.93 12.25 124.46 30.66 0.03 7.25 0.32 0.14
cciss/c0d1 0.00 42.27 44.05 1.87 352.42 353.05 15.36 1.17 25.50 0.08 0.38
emcpowerb 0.00 0.00 0.00 0.00 0.00 0.00 7.99 0.00 3.46 1.09 0.00
emcpowerd 0.00 0.00 26.70 6.14 374.29 49.09 12.89 0.52 8.66 29.06 95.42

Data가 수집되고 있고(위 script 내용대로라면 iostat_20111214, iostat_tps_20111214), device key(device.info)와 iostat key(iostat_key.info)가 존재한다면 아래의 script를 통해 필요한 값을 추출하고 이를 Cacti에서 Graph로 그릴 수 있도록 처리 가능합니다. Crontab에 등록하여 Data file이 갱신될 수 있도록 하고 수집 cycle은 1분으로 되어 있는데 조정하시면 됩니다.

$ more Monitoring_iostat_to_cacti.sh#!/bin/sh
# ================================================================
# -process
# Monitoring IOstat data to cacti
# -process content
# Monitoring IOstat data to cacti
# -how to use
# [File Location Directory]/Monitoring_iostat_to_cacti.sh bond0
# in crontab (every min)
# * * * * * [File Location Directory]/Monitoring_iostat_to_cacti.sh bond0
# -NOTE
#
# -created date
# 2011/08/19 Jeff Kim
#
# ================================================================
BASE=[File Location Directory]
DEVICES=`cat $BASE/device.info`
DATE=`date +%Y%m%d`
KEYS=`cat $BASE/iostat_key.info`
###################################################################

rm -f $BASE/tmp*
for device in $DEVICES
do
TMP1=`cat $BASE/iostat_tps_$DATE | grep $device | cat -n | /usr/bin/perl -ane 's/\s+/,/g;print "$_\n";' | tail -n 1 | tr ',' '\n'`
TMP2=`cat $BASE/iostat_$DATE | grep $device | cat -n | /usr/bin/perl -ane 's/\s+/,/g;print "$_\n";' | tail -n 1 | tr ',' '\n'`
num=0
for value in $TMP1
do
if [ $num -ge 1 ];then
echo $value >> $BASE/tmp_iostat_value
fi
num=`expr $num + 1`
done
num=0
for value in $TMP2
do
if [ $num -ge 2 ];then
echo $value >> $BASE/tmp_iostat_value
fi
num=`expr $num + 1`
done

num=1
for key in $KEYS
do
echo $key`cat $BASE/tmp_iostat_value | head -n $num | tail -n1 | awk -F"." '{print $1};'` >> $BASE/tmp_iostat_$device
num=`expr $num + 1`
done

cat $BASE/tmp_iostat_$device | tr '\n' ' ' > $BASE/iostat_`/sbin/ifconfig $1 | grep "inet addr:" | awk -F" " '{print $2};' | awk -F":" '{print $2};'`_$device
rm -f $BASE/tmp*
rsync -arv $BASE/iostat_`/sbin/ifconfig $1 | grep "inet addr:" | awk -F" " '{print $2};' | awk -F":" '{print $2};'`_$device [Cacti_Server_HostName]::[Rsync Community Name]
done

Script를 보면 rsync로 Cacti Server에 Data를 전송하고 있는데 Cacti Server에서 Data File을 체크하는게 SNMP EXEC등으로 받아가는 것 보다 간편해서 그렇게 하고 있습니다. 그럼, 어떤 file들을 보내게 되는냐 하면

$ more iostat_[IP_Address]_emcpowerd
device:emcpowerd tps:48 brs:289 bws:101 br:17368 bw:6096 rrqms:0 wrqms:0 rs:36 ws:12 rsecs:289 wsecs:101 rkbs:8 wkbs:71555 avgrqsz:2 avgqusz:20 await:100 svctm:100 util:100
$ more iostat_[IP_Address]_emcpowerh
device:emcpowerh tps:0 brs:0 bws:0 br:0 bw:0 rrqms:0 wrqms:0 rs:0 ws:0 rsecs:0 wsecs:0 rkbs:0 wkbs:63182 avgrqsz:0 avgqusz:0 await:100 svctm:100 util:100

이 Data file은 crontab에 설정된 내용대로 매분(혹은 매 5분) 단위로 갱신되고 Local 및 Cacti server에 전송이 되겠죠. Cacti Server에서 이 Data값을 이용해서 Graph를 그리면 됩니다. 나머지 부분은 Linux #23 : IO Monitoring with Cacti #2 에서 설명하도록 하겠습니다.

Linux #20 : RedHat Linux Kernel Crash Analysis

지난 시간에는 NetDump를 통한 Crash Dump에 대해서 적었었죠.
(그 이후 몇 달만에 이 글을 쓰는지 모르겠네요. 정리는 한 참 전에 해 놓고.. 나름 바쁘다는 핑계로 = =;)
Dump를 뜨는 것도 중요하죠. Console화면을 놓치는 경우 Linux에서 발생한 Kernel Panic과 같은 Error를 Dump File이 없이 확인 하는 게 어렵기 때문에.
그럼, 그걸 분석하는 방법을 배워야 겠죠.

그래서 RedHat Crash Utility라는게 존재 합니다. 이 Tool을 사용하기 위해서는 3개지의 전제 조건이 필요합니다.

  • Kernel Object File : A vmlinux Kernel Object file이 있어야하고, 일반적으로는 /boot, /lib/modules에서 존재합니다.
  • Kernel Crash Dump : Diskdump, Netdump, Kdump 등에 의해서 Dump된 Filename이 vmcore 혹은 vmcore.incomplete가 있어야하며 일반적으로 /var/crash에 저장됩니다.
  • Linux Kernel Version : Red Hat Linux 6.0 이하가 아니면 됩니다.

** 여기서 사용한 Version은 RHEL 4 U5 x86_64입니다.

Install Crash Utility의 설치
설치는 간단하게 RPM Package로 가능합니다. 설치된 crash file의 경로는 /usr/bin/crash.

$ rpm -ivh crash-4.0-3.9.x86_64.rpm
warning: crash-4.0-3.9.x86_64.rpm: V3 DSA signature: NOKEY, key ID 443e1821
Preparing... ########################################### [100%]
1:crash ########################################### [100%]

또한, Kernel을 Debug하기 위한 Kernel-debuginfo RPM Package가 필요하다.

# rpm -ivh kernel-debuginfo-2.6.9-55.EL.x86_64.rpm
Preparing... ########################################### [100%]
1:kernel-debuginfo ########################################### [100%]
# ls -l /usr/lib/debug/lib/modules/
total 16
drwxr-xr-x 3 root root 4096 Apr 25 17:55 2.6.9-55.EL
drwxr-xr-x 3 root root 4096 Apr 25 17:55 2.6.9-55.ELlargesmp
drwxr-xr-x 3 root root 4096 Apr 25 17:56 2.6.9-55.ELsmp
drwxr-xr-x 3 root root 4096 Apr 25 17:56 2.6.9-55.ELxenU
# ls -l /usr/lib/debug/lib/modules/2.6.9-55.EL
total 38320
drwxr-xr-x 9 root root 4096 Mar 21 15:24 kernel
-rwxr-xr-x 1 root root 39190296 Apr 20 2007 vmlinux

위에서 언급 한 것 처럼 System Crash(Kernal Panic)에 의해 저장되는 file은 vmcore이고, 해당 file은 /var/crash에 저장된다.
Dump를 통해서 저장 된 vmcore file을 확인 해 보자.

# strings vmcore | fgrep -m1 'Linux '
Linux version 2.6.9-55.ELsmp ([email protected]) (gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)) #1 SMP Fri Apr 20 16:36:54 EDT 2007

이제 모든 준비가 완료 되었으니, crash를 실행 해 봅시다. 아래와 같이 실행합니다.

# crash [Module vmlinux의 위치] [vmcore file의 위치]

# crash /usr/lib/debug/lib/modules/2.6.9-55.ELsmp/vmlinux /var/crash/[IP Address]-2011-03-16-22\:28/vmcore

crash 4.0-3.9
Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006 IBM Corporation
Copyright (C) 1999-2006 Hewlett-Packard Co
Copyright (C) 2005 Fujitsu Limited
Copyright (C) 2005 NEC Corporation
Copyright (C) 1999, 2002 Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions. Enter "help copying" to see the conditions.
This program has absolutely no warranty. Enter "help warranty" for details.

GNU gdb 6.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...

KERNEL: /usr/lib/debug/lib/modules/2.6.9-55.ELsmp/vmlinux
DUMPFILE: /var/crash/[IP Address]-2011-03-16-22:28/vmcore
CPUS: 8
DATE: Sat Mar 19 13:24:07 2011
UPTIME: 9 days, 17:24:48
LOAD AVERAGE: 0.25, 0.28, 0.22
TASKS: 190
NODENAME: [HostName]
RELEASE: 2.6.9-55.ELsmp
VERSION: #1 SMP Fri Apr 20 16:36:54 EDT 2007
MACHINE: x86_64 (2666 Mhz)
MEMORY: 8.7 GB
PANIC: ""
PID: 0
COMMAND: "swapper"
TASK: 10037e627f0 (1 of 8) [THREAD_INFO: 100069a6000]
CPU: 6
STATE: TASK_RUNNING (PANIC)

crash>

얼마전에 절 괴롭혔던 HP DL360G5 장비의 Memory 관련 Error 입니다. Physical Memory Check를 해도 Error가 검출되지 않아
결국 Server와 Memory를 교체하고 그 뒤로 동일한 Error는 발생하지 않았습니다.

Crash의 명령어를 통해 좀 더 다양하게 확인 가능합니다.. 명령어는 아래와 같이 help 로 확인 할 수 있습니다.

crash> help

* files mod runq union
alias foreach mount search vm
ascii fuser net set vtop
bt gdb p sig waitq
btop help ps struct whatis
dev irq pte swap wr
dis kmem ptob sym q
eval list ptov sys
exit log rd task
extend mach repeat timer

crash version: 4.0-3.9 gdb version: 6.1
For help on any command above, enter "help ".
For help on input options, enter "help input".
For help on output options, enter "help output".

Linux #18 : NetDump를 통한 Crash Dump

Linux Kernel의 Crash Dump를 취득하기 위해서는 DiskDump, NetDump, Kdump가 있는데, kdump는 RHEL5에서 부터 구현되는 기능으로 여기서는 NetDump에 대해서 다루도록 하겠습니다.

NetDump는 Crash Dump를 Network를 통해서 NetDump Server로 설정된 Server에 저장하게 됩니다. Local Disk에 저장하게 되는 DiskDump의 경우 별도의 File System을 준비 해 줘야 하는 불편함이 있으므로, NetDump가 훨씬 유용하게 사용할 수 있을 듯 합니다.

그럼, 먼저 NetDump Server를 설정하는 방법을 확인 하도록 하겠습니다.

NetDump Server가 설치되어 있는지를 먼저 확인 합니다.

# rpm -q netdump-server
netdump-server-0.7.16-10

설치되어 있지 않다면, Yum이나 Up2date 또는 RPM을 직접 받아서 설치를 합니다.
설치 후 Reboot시 항상 자동으로 기동이 되도록 chkconfig를 통해서 등록을 합니다.

# chkconfig netdump-server on
# service netdump-server start
or
# /etc/init.d/netdump-server start

혹시 netdump 계정에 대한 Password가 설정되어 있지 않다면 설정을 해 둡니다.

NetDump Server에서 Crash Dump는 /var/crash에 저장이 됩니다.

그럼, NetDump Client를 각 서버에 설치를 하고 Server와 통신할 수 있도록 설정을 합니다.
역시 Client가 설치되어 있는지를 먼저 확인하고,

# rpm -q netdump
netdump-0.7.16-2

/etc/sysconfig/netdump를 변경 해 줍니다. 여러 설정들이 있지만 여기서는 NetDump Server의 IP정보 입력과 인증을 위한 DSA 공개키를 등록 하거나, Secure한 Network 상에 모든 서버들이 존재한다면 DSA 공개키 등록없이 사용하는 설정을 공유 하도록 하겠습니다.

NetDump Server의 IP 정보 입력

# vi /etc/sysconfig/netdump
..
NETDUMPADDR=10.37.100.1

DSA 공개키의 등록

# service netdump propagate
or
# /etc/init.d/netdump propagate
[email protected]'s password:

DSA 공개키 등록없이 접근 가능하게 하는 방법

Cleint에서
# vi /etc/sysconfig/netdump
..
NETDUMPKEYEXCHANGE=none
..

Server에서
# vi /etc/netdump.conf
secure=0

후 각각 Restart

그리고, NetDump Server와 동일하게 Client도 기동을 해 줍니다.

# chkconfig netdump on
# service netdump start
or
# /etc/init.d/netdump start
initializing netdump [ OK ]
initializing netconsole [ OK ]

Message from XXXXX@XXXXXX at Mon Mar 21 15:17:24 2011 ...
XXXXXXX kernel: [...network console startup...]

Dump가 시작이 되면, 위에서 설명한 것 처럼 NetDump Server의 /var/crash/YYYY-MM-DD-hh:mm과 같이 Directory가 만들어지고 그 안에 vmcore-incomplete가 작성되고, Dump가 완성되면 vmcore file이 생성됩니다.

# ll 10.37.100.31-2011-03-16-22\:28/
total 15351800
-rw------- 1 netdump netdump 10075 Mar 19 13:33 log
-rw------- 1 netdump netdump 9395240960 Mar 19 13:29 vmcore
-rw------- 1 netdump netdump 9395240960 Mar 19 13:33 vmcore-incomplete

Crash Dump는 문제가 발생하였을 시에 발생하게 됨으로 netdump start 이후에는 vmcore, vmcore-incomplete file은 없고, log에
[…network console startup…] 라는 Message를 확인 할 수 있을 것입니다.

이걸로 NetDump로 Crash Dump를 취득가능하게 되고, 취득 된 Crash Dump는 이후에 Crash와 Kernel-debuginfo RPM을 설치하여 분석 가능하게 됩니다.

Linux #15 : LVM에서 Logical Volume의 Resizing

지난 시간에 LVM에서의 Logical Volume 생성에 대해서 배웠는데 LVM에서 생성된 File System은 VG의 Size 한도 안에서 확장이 가능하고, File System에 따라서 별도의 Format 작업이 없이 확장 가능하기도 하다. 필자는 IBM AIX를 다룰 때 JFS2를 사용 했었는데, 이 Volume이 Onlice상에서 확장 가능한 Volume이었고, Oracle에서 Raw Device를 사용할 경우 해당 Raw Device에 대해 LVM으로 구성하여 복잡한 작업없이 Logical Volume을 확장 했던 적이 있었다.

Logical Volume의 확장은 정상적으로 동작 했을 경우에는 문제가 되지 않지만, 문제가 발생했을 경우에는 모든 Data를 손실할 경우도 있으므로 작업 전에 반드시 Data를 Backup 할 것을 권유하고 싶다.

LVM의 Logical Volume을 확장하기 위해서 “lvextend”라는 command가 사용된다.
지난 시간에 작성한 Logical Volume인 “/dev/vg001/MyTechies”를 참조 해 보자.

$ lvdisplay /dev/vg001/MyTechies
--- Logical volume ---
LV Name /dev/vg001/MyTechies
VG Name vg001
LV UUID j7037M-1uii-KO6a-ov6t-ub6C-Pm42-DPeGEj
LV Write Access read/write
LV Status available
# open 0
LV Size 40.00 GB
Current LE 1280
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0

아래와 같이 확장시킬 File System(/dev/vg001/MyTechies)은 Online 상태에 있으며, /home/lvm2test에 mount 되어 있다.


$ mount
/dev/sda2 on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/sda6 on /home type ext3 (rw,nodev)
/dev/sda1 on /boot type ext3 (rw,noexec,nosuid,nodev)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
/dev/mapper/vg001-MyTechies on /home/lvm2test type ext3 (rw)

$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 31G 3.4G 26G 12% /
/dev/sda6 43G 889M 40G 3% /home
/dev/sda1 99M 17M 77M 18% /boot
tmpfs 1006M 0 1006M 0% /dev/shm
/dev/mapper/vg001-MyTechies
40G 177M 38G 1% /home/lvm2test

lvextend를 통해서 10G를 확장 시켜 보면


$ lvextend -L +10G /dev/vg001/MyTechies
Extending logical volume MyTechies to 50.00 GB
Logical volume MyTechies successfully resized

정상적으로 확장이 되었다는 Message를 확인 할 수 있고, “lvdisplay”로 확인을 하면,


$ lvdisplay /dev/vg001/MyTechies
--- Logical volume ---
LV Name /dev/vg001/MyTechies
VG Name vg001
LV UUID j7037M-1uii-KO6a-ov6t-ub6C-Pm42-DPeGEj
LV Write Access read/write
LV Status available
# open 1
LV Size 50.00 GB
Current LE 1600
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0

LV Size가 40.00 GB에서 50.00 GB로 확장 된 것을 확인 할 수 있다. 그리고, “resize2fs”를 통해서 File System을 확장 해 주면 된다.
여기서 File System을 축소 할 경우에는 해당 File System의 Unmount가 반드시 필요하지만, 확장시에는 Online상태에서 Resize가 가능하다.

$ resize2fs /dev/vg001/MyTechies
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/vg001/MyTechies is mounted on /home/lvm2test; on-line resizing required
Performing an on-line resize of /dev/vg001/MyTechies to 13107200 (4k) blocks.
The filesystem on /dev/vg001/MyTechies is now 13107200 blocks long.

$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 31G 3.4G 26G 12% /
/dev/sda6 43G 889M 40G 3% /home
/dev/sda1 99M 17M 77M 18% /boot
tmpfs 1006M 0 1006M 0% /dev/shm
/dev/mapper/vg001-MyTechies
50G 180M 47G 1% /home/lvm2test

또한 정상적으로 확장 된 것을 확인 할 수 있다.
그럼, 이제 축소를 시켜보자. File System의 축소는 위에서 이야기 했던 것 처럼 먼저 Umount가 선행 되어야 한다.

$ umount /home/lvm2test/

또한, 축소를 할 경우에는 File System의 Size를 변경 시킨 후 행할 필요가 있다. 이는 Defragment와 동일한 개념으로 생각하면 된다.
먼저 “e2fsck”를 이용하여 File System의 정합성을 체크하고, “resize2fs”로 Size를 축소하면 된다.

$ e2fsck -f /dev/vg001/MyTechies
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vg001/MyTechies: 12/6553600 files (8.3% non-contiguous), 251734/13107200 blocks

$ resize2fs /dev/vg001/MyTechies 40G => Size를 40G로 축소
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/vg001/MyTechies to 10485760 (4k) blocks.
The filesystem on /dev/vg001/MyTechies is now 10485760 blocks long.

그런 다음 resize2fs를 통해 축소된 Size와 동일하게 Logical Volume Size도 축소를 시켜주면 된다.
이때 “lvreduce” command가 사용된다.

$ lvreduce -L 40G /dev/vg001/MyTechies
WARNING: Reducing active logical volume to 40.00 GB
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce MyTechies? [y/n]: y => Y를 입력
Reducing logical volume MyTechies to 40.00 GB
Logical volume MyTechies successfully resized

$ lvdisplay /dev/vg001/MyTechies
--- Logical volume ---
LV Name /dev/vg001/MyTechies
VG Name vg001
LV UUID 4i5MxQ-qxNA-JzR1-HC3V-I041-hwvz-Q31rva
LV Write Access read/write
LV Status available
# open 0
LV Size 40.00 GB
Current LE 1280
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0

축소 작업에서는 확장할 때 보다 문제가 발생할 가능성이 많으므로, 중요한 Data는 반드시 Backup 먼저 한 후 작업을 하길 바랍니다.

Linux #14 : LVM에서 Logical Volume 생성하기

지난 시간에 LVM의 구성확인을 위한 Command에 대해서 확인을 했고, 이번엔 Logical Volume을 생성하기위한 방법에 대해서 설명하도록 하겠습니다.

LVM은 지난시간에 설명 한 것과 같이 PV(Physical Volume), VG(Volume Group), LV(Logical Volume) 순으로 구성된다고 했는데, LV를 생성하기 위해선 먼저 PV를 만들고 VG를 구성한 뒤 VG 위에 LV를 생성하면 됩니다.

일단 PV를 구성하기 위해서는 PV를 구성하기 위한 Device를 확인해야 하는데 이때는 Linux File System에 대한 지식이 좀 필요하겠네요. SCSI Device를 LVM 용도로 추가 하였고, /dev/sdb Device라면 “fdisk”와 같은 명령어로 확인이 가능하겠죠.

$ fdisk -l /dev/sdb
Disk /dev/sdb: 85.8 GB, 85899345920 bytes
255 heads, 63 sectors/track, 10443 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk /dev/sdb doesn't contain a valid partition table

PV를 생성하기 위해서는 “pvcreate” 명령어를 사용하면 된다.

$ pvcreate -v /dev/sdb
Set up physical volume for "/dev/sdb" with 167772160 available sectors
Zeroing start of device /dev/sdb
Physical volume "/dev/sdb" successfully created

위와 같이 PV 생성하였고, 생성 된 PV는 “pvscan”으로 확인 가능합니다.

$ pvscan
PV /dev/sdb lvm2 [80.00 GB]
Total: 1 [80.00 GB] / in use: 0 [0 ] / in no VG: 1 [80.00 GB]

그럼 이제 VG 생성이 가능하게 되는데 “vgcreate”를 사용하여 생성하면 됩니다.

vgcreate [VGNAME] [DEVICE]
$ vgcreate -v vg001 /dev/sdb
Wiping cache of LVM-capable devices
Adding physical volume '/dev/sdb' to volume group 'vg001'
Archiving volume group "vg001" metadata (seqno 0).
Creating volume group backup "/etc/lvm/backup/vg001" (seqno 1).
Volume group "vg001" successfully created

또, 생성 된 VG에 대해서 “vgdisplay”로 확인 하면,

$ vgdisplay
--- Volume group ---
VG Name vg001
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size 80.00 GB
PE Size 4.00 MB
Total PE 20479
Alloc PE / Size 0 / 0
Free PE / Size 20479 / 80.00 GB
VG UUID C8n1rc-3p2U-0TD2-NS0N-XtOJ-zgKs-clDWPy

여기서 확인 해 볼 필요가 있는 건 지난 시간에 설명을 했던 PE (Physical Extent)에 관한 것인데, LV를 생성할 때 할당되는 Block에 관한 것으로 VG에서 PE Size를 설정하는 것이 가능하기 때문이다. 1개의 LV에 할당 가능한 최대의 PE수는 65535 Block이기 때문에 PE Size의 크기에 따라 LV의 최대 Size가 변하게 된다. 그러나, 너무 크다면 LV의 Size의 조절범위가 커지기 때문에 불필요한 용량이 늘어날 수도 있기 때문에 주의가 필요하다. Default PE Size는 4MB(4096KB)로 아래와 같은 Option을 추가하는 것으로 PE Size의 변경이 가능하다. 일단 VG를 만든 이후에는 변경을 못하게 됨으로 VG 생성 전에 적절한 Sizing을 통해 PE Size를 결정 해 줄 필요가 있다.

$ vgcreate -v -s32m vg001 /dev/sdb
Wiping cache of LVM-capable devices
Adding physical volume '/dev/sdb' to volume group 'vg001'
Archiving volume group "vg001" metadata (seqno 0).
Creating volume group backup "/etc/lvm/backup/vg001" (seqno 1).
Volume group "vg001" successfully created

$ vgdisplay
--- Volume group ---
VG Name vg001
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size 79.97 GB
PE Size 32.00 MB
Total PE 2559
Alloc PE / Size 0 / 0
Free PE / Size 2559 / 79.97 GB
VG UUID ZVQ1xJ-8vdF-5C2C-fBgS-fX3h-8yZG-r5dcjM

4MB 일 때와 32MB 일때의 PE 갯수가 변한 건 확일 할 수 있죠, 32MB일때는 VG Size가 79.97 GB인것도 다르죠.
VG까지 생성 했다면 이제 드디어 LV의 생성이 가능하게 됩니다. LV의 생성은 “lvcreate”를 이용하면 되고

lvcreate -n[LV NAME] -L[LV SIze] [VG]
$ lvcreate -v -nMyTechies -L40G vg001
Setting logging type to disk
Finding volume group "vg001"
Archiving volume group "vg001" metadata (seqno 3).
Creating logical volume MyTechies
Creating volume group backup "/etc/lvm/backup/vg001" (seqno 4).
Found volume group "vg001"
Creating vg001-MyTechies
Loading vg001-MyTechies table
Resuming vg001-MyTechies (253:0)
Clearing start of logical volume "MyTechies"
Creating volume group backup "/etc/lvm/backup/vg001" (seqno 4).
Logical volume "MyTechies" created

그리고, “lvdisplay”로 확인 가능합니다.

$ lvdisplay
--- Logical volume ---
LV Name /dev/vg001/MyTechies
VG Name vg001
LV UUID j7037M-1uii-KO6a-ov6t-ub6C-Pm42-DPeGEj
LV Write Access read/write
LV Status available
# open 0
LV Size 40.00 GB
Current LE 1280
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0

LV를 생성하게 되면 LV에 대한 Device명은 /dev/[VG Name]/[LV Name]이 됩니다. 위에서 보면 /dev/vg001/MyTechies를 확인 할 수 있습니다. 그리고, “vgdisplay” 통해 확인 하면,

$ vgdisplay
--- Volume group ---
VG Name vg001
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 4
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size 79.97 GB
PE Size 32.00 MB
Total PE 2559
Alloc PE / Size 1280 / 40.00 GB
Free PE / Size 1279 / 39.97 GB
VG UUID ZVQ1xJ-8vdF-5C2C-fBgS-fX3h-8yZG-r5dcjM

생성 된 LV 만큼, LV에 대한 정보면 Allocated 된 Size 정보, 남은 용량등을 확인 할 수 있습니다. 이 이후에는 LV를 format하고 mount를 하여 사용하면 되겠죠. Format은 mkfs, mkfs.ext3 Filesystem에 따라 해 주시면 되고,

$ mkfs.ext3 /dev/vg001/MyTechies
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
5242880 inodes, 10485760 blocks
524288 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
320 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

Mount를 작업을 거치면 사용가능하게 됩니다.

다음 시간에는 LVM에서 생성된 LV의 ReSizing에 대해서 설명을 하도록 하겠습니다.

Linux #13 : LVM (Logical Volume Manager)의 구성 확인

Logical Volume Manager인 LVM을 통해서 Volume을 생성하고, 확인 하는 방법에 대해서 정리 해 보려고 한다.
LVM은 여러개의 Partition을 한 개의 Disk(File system)으로 사용하기 위한 Disk 관리 기능이다. LVM을 사용하면 아래와 같은 장점이 있다.

1. 여러개의 Disk를 1개의 File System로 구성 가능
2. Partition Size의 변경이 용이
3. Snapshot과 같은 기능의 사용이 가능

우선 Physical Volume(PV) 정보를 확인 할 필요가 있고, 아래와 같이 “pvdisplay”로 확인 가능하다.

$ pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name VolGroup00
PV Size 111.69 GB / not usable 1018.00 KB
Allocatable yes (but full)
PE Size (KByte) 32768
Total PE 3574
Free PE 0
Allocated PE 3574
PV UUID dz7rf6-xEaU-WPEY-RRbg-7Gd5-CbJA-L2NFQy

Physical Volume은 Physical Device를 의미하며 LVM의 관리정보가 추가 된 Partition을 표시 해 주고 있다.
PE Size, Total PE, Free PE, Allocated PE, PE라는 용어가 있는데, 이는 Physical Extent로 저장영역의 최소단위이다.
이후에 만들어지게 될 Logical Volume은 이 PE를 필요한 만큼 배분하여 가상적인 Partition을 작성하는 걸 의미하고, 위 정보에 의하며 PE Size는 32MBytes로, 총수는 3574개이고, Free는 없으며, 모든 PE가 사용되고 있다고 볼 수 있다.

Physical Volume의 다음 단계는 VG(Volume Group)가 되는데, VG는 Physical Volume을 구성하는 가상의 저장장치를 의미한다. Volume Group을 생성하는 것으로 여러개의 Physical Volume을 한개의 큰 File system(Disk)로 System 에서 인식하는게 가능하게 된다. Volume Group에 대한 정보는 “vgdisplay”를 통해서 확인 가능하다.

$ vgdisplay
--- Volume group ---
VG Name VolGroup00
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 4
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 3
Open LV 3
Max PV 0
Cur PV 1
Act PV 1
VG Size 111.69 GB
PE Size 32.00 MB
Total PE 3574
Alloc PE / Size 3574 / 111.69 GB
Free PE / Size 0 / 0
VG UUID qKtkYK-FaRH-zUfi-0ECP-A5J7-f1W4-7ffYSa

Volume Group이 구성된 이후엔 마지막 단계인 Logical Volume(LV)이 구성되는데, Logical Volume은 Volume Group상에서 생성된 가상 Partition이고, 이는 “lvdisplay”로 확인 가능하다.

$ lvdisplay
--- Logical volume ---
LV Name /dev/VolGroup00/LogVol02
VG Name VolGroup00
LV UUID S6gx2z-GcWu-9hmx-kHK3-YcpT-RsSy-a9yzcJ
LV Write Access read/write
LV Status available
# open 1
LV Size 107.69 GB
Current LE 3446
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:3

--- Logical volume ---
LV Name /dev/VolGroup00/LogVol01
VG Name VolGroup00
LV UUID fPqNNh-hJTA-N6cU-Ndzh-CRMP-rylz-hK56ay
LV Write Access read/write
LV Status available
# open 1
LV Size 2.00 GB
Current LE 64
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:4

--- Logical volume ---
LV Name /dev/VolGroup00/LogVol00
VG Name VolGroup00
LV UUID W00Fr8-AaxC-nloz-nXmO-j1Ma-qaRY-yOmuQJ
LV Write Access read/write
LV Status available
# open 1
LV Size 2.00 GB
Current LE 64
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:5

따라서, 정리를 해 보면 어떤 Device가 추가 되면 Physical Device에서 Physical Volume을 생성하고, PV에서 Volume Group을 할당하고, Volume Group상에서 Logical Volume이 존재하게 된다는 것이고, 이는 Physical Device -> PV Create -> VG Create -> LV Create를 통해서 순차적으로 생성가능하게 된다.

LVM에서의 File System 생성은 Linux #14 : LVM에서 Logical Volume 생성하기에서 설명하도록 하겠다.

Linux #2 : About Memory on Linux

System에 장애가 발생 했을 시, 문제를 잘 파악하는게 중요한 Point가 되고,
장애의 원인을 정확하게 파악하고 있다면, 무엇을, 누가, 어떻게 해야 하는지가 명확 해 집니다.
그렇지 못하다면, 인적, 금전적 Resource가 낭비되는 건 당연하구요.

System 상에서 장애 원인을 파악하기 어려운 부분 중의 하나가 Memory인데, 이는 OS 관련 문제 중
20% ~ 30%를 차지하고 있을 정도죠. Memory Trouble은 어려 복잡한 문제가 혼합되어 일어나는데
그 문제는 Application, Middle-Ware, OS, Hardware와 관련되어 더욱더 해결하기 어려워지죠.

일단 Memory를 확인 하기 위한 Command부터 숙지 할 필요가 있을 듯 하네요.
대표적으로 free, vmstat, sar, top, ps가 되죠.

우선,

free : 간단하게 메모리를 파악할 수 있으나, 보기 애매한 부분이 있죠.
vmstat : Memory 상황 및 CPU 사용률도 같이 파악 할 수 있으나, Option이 다양하지 않아 특정
Period에 고부하가 발생 했을 시에는 적합하지 않을 수 있어요.
sar : 위 나열된 Command 중에 가장 취득정보가 많으나,  약간 부적절한 부분도 있어 Memory 감시
관점에서는 vmstat보다 좀 떨어집니다.
top : real time으로 볼수 있는 tool인데, 여러가지 기능이 있고 Log 기록도 가능하죠
( - b batch mode 시)
ps : top과 같이 real time으로 볼 수 있는 tool이고, 여러 Option이 있는데 습관에 따라 쓰는 것
만 쓰게 된다는 예를 들면 "ps ax", "ps aux", "ps -elf" 등이죠.

그럼,  실제 사용 시를 확인 해 볼까요?

# free
total       used       free     shared    buffers     cached
Mem:       4046504    3453500     593004          0     111468    1755760
-/+ buffers/cache:    1586272    2460232
Swap:      4192912    1178400    3014512

각 부분의 의미를 간단하게 설명 하자면

[Mem] total : Total Physical Memory size
[Mem] used : Total Physical Memory size - Free memory size
[Mem] free : 현재 사용되고 있지 않은 여유 Memory
[Mem] shared : 항상 0이고, 현재 사용되고 있지 않음.
[Mem] buffers : File등의 Meta data를 Cache하고 있는 Physical Memory size
[Mem] cached : File의 Real Data를 Cache하고 있는 Physical Memory size
[-/+ buffers/cache] used- : buffers, cached를 포함하고 있지 않은 used size
[-/+ buffers/cache] free+ : buffers, cached를 포함한 free size
[Swap] total : Total Swap size
[Swap] used : Total Swap size - Free size
[Swap] free : 사용하고 있지 않은 Swap size

여기서 [Mem] Free는 “남아있는 Memory Size”가 아닌, 어떠한 용도로도 사용되고 있지 않은
Physical Memory Size
라고 생각하면 되고, 이는 [Mem] Free가 적다  -> 남아 있는 Memory size가
적다 -> 이용가능한 Memory size가 부족하다와 같은 발생을 막기 위함입니다. 따라서, 단순하게
Physical Memory를 추가해도 언젠가는 [Mem] Free가 이전과 같아 지지요.

결론적으로 System 전체의 Memory 사용량의 감시는 [Mem] Free을 판단 기준으로 하는 것이 아니라, 사용가능한 Physical Memory Size로 계산 할 필요가 있죠.

System의 이용가능한 Memory size의 계산은 Linux의 Page Cache에 대해서 이해 할 필요가 있는데,
Linux는 HDD등의 Storage에 저장되어 있는 Data에 대해서 Read / Write 시에 확보 했던 Memory를
Page Cache라는 형태로 보존 합니다.

CPU는 Storage의 Data를 직접 Read 할 수 없어서 Storage Data는 우선 Memory에 Load를 합니다.
이렇게 Read한 Data를 Page Cache로서 재이용합니다. 일단 Load 해 두면 Page Cache는 Read/Write를 Storage에서 Read 해 올 필요가 없으므로 고속처리가 가능하죠.

Page Cache는 새로 Storage Data를 Read/Write로 인해 Memory를 추가 할 필요가 없는 한, Memory를 release 하지 않으므로, 일반적으로 System이 가동하고 있는 것 만으로도 [Mem] Free는 Page Cache로서 계속 활용되고 어느 정도까지 계속 줄어들게 되죠. 서버마다 다르긴 한데, 어떤 건 150MB까지 또 어떤건 202MB 제 경험상 동일한 Application이 계속 돌고 추가 되지 않는 한 항상 같은 Free Memory size를 유지하게 됩니다. 따라서, [Mem] Free가 50MB가 계속 유지된다고 해서 반드시 걱정 할 필요가 없는 거지요.

이 Page Cache는 사용중이 아닌 Storage와 Data Sync 되어 있으면 바로 Release 할 수 있고, Page Cache에 대한 Write가 있을 경우엔 일시적으로 Unsynchronized 상태가 되지만, Storage와의 Sync는 정기적으로 이루어지고 있어 시간이 지나면 Release 가능한 상태가 됩니다. 즉, Page Cache는 “System이 다른 용도로 재이용 가능한” Memory를 포함하고 있죠.

이용 가능한 Physical Memory Size를 free command를 통해 계산 하는 방법

free command에도 어느정도는 Page Cache를 의식하여 개량되어 있고, 그것이 used – 와 free +입니다.

Buffers와 Cached는 Page Cache이고, 정확하게는 Buffers는 Cached에 SwapCached를 추가한 것이 Page Cache의 Total이지만, free command에서는 SwapCached가 표현되지 않죠. 그림을 보면, Buffers와 Cached를 합친 것을 used에서 뺀(used-), free를 더한 (free+)로 보다 현실적인 Physical Memory size와 이용가능한 Physical Memory size를 출력하고 있죠. 따라서, 이 두 수치를 참고하면 됩니다.

그렇다고 해서, System이 이용가능한 Memory size를 파악하기엔 부족하죠. 앞에서, Page Cache를 다른 용도로 재이용하기에는 “Storage와 Sync하고 있음”이라는 조건이 있었죠. Buffers와 cached에는 당연히 “Storage와 Unsynchronized” Page Cache가 포함되어 있죠. 그래서, free+는 실제 이용가능한 Memory size보다 좀 더 부풀려져 있게 되고, 아래와 같이 표현 가능하죠.

free < 실제 사용가능한 Memory size < free+

 

Physical Memory Status 확인 방법

그럼, Storage와의 Sync 정보까지 포함한 Memory 사용상태 감시를 위해서는 ActiveInactive를 감시하면 됩니다.

Active와 Inactive는 vmstat -a cat /proc/meminfo를 통해 취득 가능하죠.

# vmstat -a
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
0  0 1178400 534328 805388 2502796    0    0   161   159    0    0  7  2 89  1  0

$ cat /proc/meminfo
MemTotal:      4046504 kB
MemFree:        424364 kB
Buffers:        117508 kB
Cached:        1845500 kB
SwapCached:     726764 kB
Active:        2610468 kB
Inactive:       803068 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:      4046504 kB
LowFree:        424364 kB
SwapTotal:     4192912 kB
SwapFree:      3014512 kB
Dirty:            9800 kB
Writeback:           0 kB
AnonPages:     1448396 kB
Mapped:          24508 kB
Slab:           152152 kB
PageTables:      27492 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   6216164 kB
Committed_AS:  4136824 kB
VmallocTotal: 34359738367 kB
VmallocUsed:    264576 kB
VmallocChunk: 34359473651 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

 

Active는 Page Cache나 Anonymous Page 중 최근 이용 했거나 아직 Storage와 Unsynchronized인 Release 할 수 없는 Page이고, Inactive는 Page Cache나 Anonymous Page 중 마지막으로 Access 된 이후 어느 정도 시간이 지나 Storage와의 Sync가 완료되어 바로 Release 할 수 있는 Page이죠. 따라서, /proc/meminfo의 MemFree와 Inactive를 더한 것이 정확한 이용 가능 Memory size가 됩니다.
아참 여기서 Anonymous Page란 주로 User Process가 이용하고 있는 Page로, ps 등으로 취득가능한 RSS로 표시되는 값입니다. 실제, Shared Memory가 Page Cache에 포함되어 있거나 해서, 정확하게 파악하는 것은 상당히 번거로운 일이죠.

실제 이용 가능한 Memory size ≒MemFree + Inactive

 Additional information : Kernel Tuning to control the Page Cache

Page Cache가 항상 남아있어 이를 Release 하고 싶은 경우 drop_caches 를 사용하면 되죠. drop caches는 지금 사용되고 있지 않은 Storage와 Unsynchronized Page Cache나 Slab Cache를 MemFree로 Release 합니다.
즉, MemFree ≒ 이용 가능한 Memory가 되죠.

아참 여기서 Slab Cache란 Directory의 Meta Data 정보를 수용하는 dentry나 File의 Meta Data 정보를 수용하는 inode 구조체등을 Cache하고 있는 Kernel내의 Memory 영역입니다. 이는 Page Cache와 별도로 Kernel 안에 확보되어 있고, Storage와 Sync되어 있으면 Release도 언제든지 가능합니다.

아래는 사용방법 입니다.

1. Default 상태로
# echo 0 > /proc/sys/vm/drop_caches
2. Page Cache만 Release
# echo 1 > /proc/sys/vm/drop_caches
3. Slab Cache를 Release
# echo 2 > /proc/sys/vm/drop_caches
4. Page Cache와 Slab Cache를 Release
# echo 3 > /proc/sys/vm/drop_caches

위 drop_caches에 설정 한 parameter는 지속되지 않으므로 필요에 따라 실행해야 합니다.

이 글은 아래 Link의 글을 참조하였습니다.
http://www.atmarkit.co.jp/flinux/rensai/tantei01/bangai01a.html