개요

Linux 나 기타 Unix 은 file 의 자세한 정보를 얻어올 수 있는 stat 라는 POSIX 표준 함수가 있다.


리눅스 에서 man -s 2 stat 를 실행하면 stat 함수의 프로토 타입과 사용에 필요한 헤더를 볼 수 있다.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>


int stat(const char *path, struct stat *buf);          
CPP


struct stat 구조를 살펴 보면 다음과 같이 다양한 메타 데이타를 포함하고 있다. 이 중에 가장 마지막에 있는 세 가지 항목  st_atime, st_mtime, st_ctime 을 눈여겨 보자.

 struct stat {
               dev_t     st_dev;     /* ID of device containing file */
               ino_t     st_ino;     /* inode number */
               mode_t    st_mode;    /* protection */
               nlink_t   st_nlink;   /* number of hard links */
               uid_t     st_uid;     /* user ID of owner */
               gid_t     st_gid;     /* group ID of owner */
               dev_t     st_rdev;    /* device ID (if special file) */
               off_t     st_size;    /* total size, in bytes */
               blksize_t st_blksize; /* blocksize for file system I/O */
               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
               time_t    st_atime;   /* time of last access */
               time_t    st_mtime;   /* time of last modification */
               time_t    st_ctime;   /* time of last status change */
           };
CPP
  • st_atime: 파일에 접근한 최종 시간. mknod, execve, pipe, read 함수를 실행했을 때 변경된다.
  • st_mtime : 파일이 변경된 시간. mknod, truncate, utime, write 함수를  실행했을 경우 변경된다.
  • st_ctime: 상태 변경 시간으로 소유자나 그룹, 링크, mode 등 inode 관련 정보가 변경된 시간이다.


웹 서버등은 File IO 가 굉장히 많이 일어나고 IO 중 대부분은 contents 를 읽어서 클라이언트에게 보내주기 위해 File 에 대해 수행하는 read 연산이다.

POSIX 표준에 의해 read 연산도 파일이나 디렉터리의 메타 데이타중 st_atime(access time)  을 변경하게 되며 이는 IO 성능에 나쁜 영향을 주게 되므로 다음과 같은 개선 방법이 출시되었다.

realatime

RHEL/CentOS 6 부터는 atime 보다 똑똑한 relatime (Relative Access Time) 이라는 mount 옵션을 제공하고 있으며  이 경우 다음의 상황에서만 atime 이 기록된다.

  1. 마지막 변경 시간(mtime) 보다 atime 이 예전일 경우(즉 파일이 변경되었을 경우 atime 갱신)
  2. 파일의 status 가 변경되었을 경우

RHEL 의 매뉴얼에 의하면 리눅스는 kernel 2.6.30 부터 realtime 이 기본 옵션이 되었으므로 noatime 으로 mount 하더라도 realtime 에 비해 큰 성능 향상은 없다고 한다.  (https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/main-fs.html)

noatime 

access 가 발생해도 이를 기록하지 않는다면 FIle IO 의 성능이 많이 향상될 수 있다.

이런 기능을 noatime(no access time) 이라고 하며  mount chattr 의 명령으로 파일 시스템 전체, 또는 개별 파일마다 access time 기록 여부를 설정할 수 있다.


noatime 설정

#1 mount 시 noatime 옵션 지정

웹 서버의 컨텍츠가 있는 디스크등을 마운트 할 때 -o noatime 옵션을 추가하면 atime 을  기록하지 않는다. 영구적으로 하려면 /etc/fstab 에 다음과 같이 noatime 을 추가하자.

/dev/mapper/vg_linux-lv_home /var                   ext4    defaults,noatime        1 2
CODE


#2 chattr 로 파일/디렉터리마다 지정

file 의 attributes 를 설정하는 chattr 명령어를 사용하면 atime 옵션으로 마운트된 file system 에서 특정 파일/디렉터리만 noatime 을 적용할 수 있다.

chattr 에 +A 를 설정하면 atime 을 기록하지 않는다. 정상 설정 여부 확인은 lsattr 의 결과값중 A 필드가 설정되었는지 확인해 보면 된다.

# lsattr -d /var/www/html/
-------------e- /var/www/html/
 
# chattr +A /var/www/html 
# lsattr -d /var/www/html/
-------A-----e- /var/www/html/
CODE


테스트

파일의 상태를 볼 수 있는 stat 의 명령어는 포맷을 지정할 수 있는 -c 옵션이 있다. 지정할 수 있는 포맷중  %x 는 access  time, %y 는 modification time, %z 는 change time이다.

파일의 atime 을 확인한 후에 read() 를 수행하는 명령어(cat, vi등)를 수행한 후에 atime 을 확인하여 변경되지 않았으면 정상 적용된 것이다.

$ stat -c "%x %y %z" .bashrc 
2014-07-04 12:23:29.541389721 +0900 2012-05-11 03:45:52.000000000 +0900 2014-01-02 19:09:39.105285429 +0900
 
$ cat .bashrc
 
$ stat -c "%x %y %z" .bashrc
CODE


Ref