리눅스와 Rsync를 이용한 편리한 자동 스냅샷(snapshot) 백업


출처 : http://www.mikerubel.org/computers/rsync_snapshots/


--- 목차 ---

1. 요약
2. 목적
3. 백업을 위한 Rsync 사용
1) 기본
2) --delete 옵션 사용
3) 게을러져라 : cron 사용
4. Rsync 를 이용한 증분백업
1) 하드링크 살펴보기
2) cp -al 사용
3) 모든 걸 함께 밀어넣기
4) dump 나 tar 사용… 이제 구식이다.
5. 시스템 여분에 백업 격리
1) 쉬운(그러나 나쁜) 방법
2) 독립 파티션에 백업
3) 독립 디스크상의 파티션에 백업
4) 독립된 기계에 백업
6. 읽기전용 백업 생성
1) 나쁜 방법 : mount/umount
2) 좀 나은 방법 : 대부분 읽기전용으로 mount하기
3) 시도하지만 실제로 작업하지는 않는다 : 2.4 커널의 mount --bind
4) 내가 사용하는 방법 : localhost상에서 NFS 사용하기
7. 추가 : 시간별/일별/주별
1) 단계별 추가 스크립트
2) cron 가지고 실행하기
8. 알려진 버그와 문제점
9. 부록 : 실제 환경
1) make_snapshot.sh
2) daily_snapshot_rotate.sh
3) ls -l /snapshot/home 의 출력예
10. 참조


1. 요약

이 문서는 저자의 GNU/Linux의 경험을 바탕으로 유닉스 기반 시스템에서 자동순차 스냅샷 백업에 대해 설명하고 있다. 스냅샷 백업은 상위 상용 파일서버의 형태로 overhead의 공간이나 과정 없이 매일 다중 풀백업하는 형식을 만들어낸다. 모든 스냅샷들은 읽기전용이고 특별한 시스템 디렉토리에 한하여 이용자가 직접 접근이 가능하다. 2배 메모리보다 작은 크기로 스냅샷을 다양한 시간별, 일별, 주별로 저장 가능하다. 이런 방법은 특정 복사-쓰기 파일시스템을 사용하는 것이 1배 메모리보다 작게 처리할 수 있는 소유권한 기술을 운영하기에는 공간이 부족할때 사용하는데, 대부분의 리눅스 배포판에서 기본으로 인스톨되는 표준파일 유틸리티와 일반적인 rsync프로그램에서만 사용한다. 잘만 설정되면 하드디스트 부족, root 손상등을 막을 수 있고, 서로 이질적인 데스크탑 네트워크를 자동으로 백업할 수도 있다.

2. 목적

갑작스레 작업하던 파일이 지워지거나 덮어씌워진 적이 있는가? 하드디스크 부족으로 데이타를 날린 적이 있는가? 아니면 친구와 함께 공유하는 윈도우즈에서 xls 파일 숫자가 꼬여버리는 아웃룩 바이러스에 당해본 적 있는가?
매일 1시간마다 파일시스템을 완전히 이미지화해놓아서, 되돌리기 할 수 있는 /snapshot 디렉토리가 있다면 좋지 않을까? 그러면 며칠동안 매일의 스냅샷이 백업되어있을테니.. 주간 단위 스냅샷은 어떨까? 모든 이용자가 운영자의 도움없이 선택한 스냅샷 디렉토리에 접근하여 지워지거나 덮어써버린 파일을 복원할 수 있다면 어떨까? /snapshot 디렉토리가 CD-ROM 같이 읽기전용이라서 root를 제외한 나머지는 손댈 수 없다면 어떨까?

가장 환상적인 건, 좀 더 큰 여분의 하드디스크 하나만 가지고 이 모든 걸 자동으로 처리 가능할 경우일 것이다.

내가 속한 연구실에서는 이용자들에게 다양한 기능을 제공하는 NetApp 파일서버를 가지고 있는데, 그밖의 다른 것들을 너무 많이 제공하는 바람에 그 비싼 SUV만큼 비용이 들어가버린다. 작업이 많은 연구실에서는 유용하지만 집이나 작은 사무실 환경이라면 죽음일거다. 그렇다고 짧은 시간 사용하는 이용자라고 그런 기능이 없어야 한다는 건 아니고…

이제부터 나의 80달러짜리 - 파일, 웹, 메일서버로 세팅된 - 리눅스 데스크탑에서 자동 순차 스냅샷 설정한 방법에 대해 살펴보고자 한다. 사용한 거라곤 1 페이지짜리 스크립트 2개와 적당한 표준 리눅스 유틸리티 몇가지이다.

3. 백업을 위해 rsync 사용

rsync 유틸리티는 GPL 소프트웨어중 잘 알려진 부분이다. 보통의 리눅스나 유닉스를 사용하는 사람이라면 이미 인스톨되어 있을거다. 아니라면 rsync.samba.org 에서 소스코드를 다운받을 수 있다. rsync의 독특한 점은 네트워크를 통해 동기화시킨 파일 트리라는 점이다. 하지만 단일시스템에서도 잘 굴러간다.

1) 기본

source라 불리우는 디렉토리가 있다고 치자. 그리고 destination이라는 디렉토리에 백업을 한다고 하면,




rsync -a source/ destination/

(참고 : -v(verbose) 옵션도 자주 사용하는데, 진행과정을 출력해준다.)

위와 동일한 명령은 다음과 같다.




cp -a source/* destination/

원격시스템에 ssh 를 사용한다면,




rsync -a -e ssh source/ 사용자계정명@호스트명:/경로/to/destination/

뒤에 / 붙이기

이 부분은 rsync에 대한 정식 article은 아니고 약간 빗겨간 얘기지만 / 사용에 대한 자세한 거부메시지는 어느정도 명확하게 알 수 있다. 보통은 뒤에 따라붙는 / 에 대한 고민 없이 실행하는데 익숙해진다. 예를 들어 a 와 b 라는 2 디렉토리가 있으면, "cp -a a b"와 같이 하면 "cp -a a/ b/"와 같은 거다. 그럼에도 불구하고, rsync 는 source문에서는 뒤에 붙는 / 를 요구하는데, 예를 들어 a 와 b 두 디렉토리에서 a 디렉토리 안의 foo 라는 파일이 있을때,




rsync -a a b===> b/a/foo 라고 만들어버린다.




rsync -a a/ b ===> b/foo 라고 만든다.

destination문에는 있든 없든 상관없다.

2) --delete 옵션 사용하기

하나의 파일이 source/ 와 destination/에 모두 있었고 source/에서는 지워버린다면, 다음번 rsync 할때는 destination/에서 지워지길 바랄 것이다. 그러나 기본값은 destination/에 복사본을 남겨두는 것이다. rsync시 source/에 없지만 destination/에 남아있는 파일을 지우려면 --delete 옵션을 사용한다.




rsync -a -delete source/ destination/

3) 게을러져라 : cron 사용하기

훌륭한 백업기법에 가장 방해되는 것중 하나가 바로 인간이다. 다행히 cron 으로 게으름을 대신할 수 있다.

예를들어 매일 4:20AM에 rsync 실행하도록 되어 있을 경우, root 가 cron 테이블을 편집할 때는,




crontab -e

그리고나서 아래 한줄을 추가해준다.




20 4 * * * rsync -a --delete source/ destination/

저장하고 "exit". 이렇게 하면 매일 4:20AM에 백업이 되고 결과를 root 에게 메일로 보내준다. 위의 예를 그래로 복사해 쓰지 마라. 경로명을 정확히 써야 한다.(ex> /usr/bin/rsync 와 /home/source/)

4. rsync 이용한 증분백업

큰 파일시스템의 풀백업은 시간과 프로세스를 많이 소비한다. 따라서 보통 풀백업은 1주 또는 1달에 한번 정도하고, 매일 바뀐 부분만 저장한다. 이런 백업을 "증분백업"이라고 하는데, dump 와 tar 유틸리티등이 사용된다.

그러나 테잎 같은 백업매체를 따로 사용하지 않을때는 rsync로 증분백업을 잘 수행할 수 있다.

가장 좋은 방법은 rsync -b --backup-dir= 조합을 사용하는 것이다.

1) 하드링크 살펴보기

보통 파일이름을 파일자체라고 생각하는데, 실제로 이름이란건 "하드링크(hard link)"가 걸려있는 상태이다. 하나의 파일은 하나이상의 하들이크를 갖는데, 예를 들어 디렉토리는 적어도 2개의 하드링크를 갖는다.(위치가 디렉토리안일때) 각가의 하위 디렉토리에서도 역시 하드링크를 가지고 있다. 만약 stat 유틸리티가 인스톨 되어 있다면 그 명령으로 파일이 얼마나 많은 하드링크를 가지고 있는 지 확인할 수 있다.




stat 파일명

디렉토리뿐 아니라 파일도 링크를 하나이상 만들 수 있다. 예를 들어 파일 a 에 b라는 링크를 만들때는,




ln a b

이제, a 와 b 2개의 이름이 동일한 파일을 가리키게 된다. 따라서 2개의 이름은 동일한 inode로 지정된다.




$ ls -i a
232177 a
$ ls -i b
232177 b

ln a b 이 cp a b 와 다른점.

1. 파일 내용은 한번만 저장되며, 동일내용이 2번 쓰여진 것이 아니다.

2. a 를 변경하면 b 도 변경된다.

3. a의 권한이나 소유권을 변경하면 b도 변경된다.

4. a 를 제3의 파일로 복사해버리면 덮어쓰기되는데, b도 역시 덮어쓰기가 된다.




주의 : rsync할때 반드시 덮어쓰기 전에 링크를 끊어라.
그러나 여전히 흥미로운 의문사항이 남는다. rm 해버리면 어떻게 될까? 실제로 파일이 지워지지는 않고 파일 링크가 지워진다. 파일 내용은 링크의 갯수가 0이 되기 전까지는 실제 지워지지 않는다.

2) cp -al 사용하기

바로 전 섹션에서 파일 하드링크가 복사와 비슷하다고 언급했다. 그러므로 표준 CNU 파일유틸리티인 cp 에 -l 옵션이 되는 걸 놀라워할 필요없다. -a(archive)는 현재 파일소유자, 시간, 접근권한등에 관한 것이다.

이와함께 cp -al 은 디렉토리 트리를 완전복사하고 실제 공간은 거의 차지하지 않는 상태를 만든다. 파일 추가나 삭제시 복사처리 이렇게 하면 디스크공간이나 처리시간을 거의 들이지 않고 복사가 완벽하게 이루어지게 한다.

2002.05.15추가본 : 팁 : GNU cp 가 인스톨되어있지 않으면 대신 find 와 cpio 를 사용할 수 있다.




cp -al a b ===> cd a && find . -print | cpio -dpl ../b.

3) 모든 걸 함께 밀어넣기

rsync와 cp -al 을 조합하면 다중 디스크 공간에 관계없이 다중 파일시스템 풀백업을 할 수 있다. 간단히 살펴보자면,




rm -rf backup.3
mv backup.2 backup.3
mv backup.1 backup.2
cp -al backup.0 backup.1
rsync -a --delete source_directory/ backup.0/

위의 명령들을 매일 한번씩 실행하게 되면 backup.0, backup.1, backup.2, backup.3 이 source_directory 에 오늘, 어제, 그제, 그그저께 내용들이 풀백업된다.

추가 저장소 = source_directory 현재 크기 + 지난 3일간 변경된 부분의 총 크기 -- dump 나 tar 로 풀백업에 매일 증분백업하는 것과 같은 공간이다.

4) dump 나 tar 사용… 이제 구식이다.

dump 와 tar 유틸리티는 실제 한번에 한 파일만 접근 가능한 테잎 매체에 쓰기 위해 설계된거다. 만약 이런 스타일의 증분백업을 하게 되면 rsync보다 퇴보하는 거다. 아래의 예가 그 차이점에 대해 명확히 보여줄거다.

특정시스템에서 월,화,수 저녁마다 백업을 하고, 오늘이 목요일이라고 치자. dump 나 tar 로 월요일에는 풀백업을 한다. 백업되는 모든 파일 시스템을 포함한다. 화요일 수요일에는 증분백업하여 전날에서 바뀐 부분만 한다. 이 시점에서 운영자는 또다른 풀dump 를 계획해야 한다.

이와 비교하여 rsync 를 이용하면, 수요일 백업이 풀백업이 된다. 실제 풀백업은 항상 최근 것이다. 화요일 디렉토리는 화요일과 수요일 사싱 변경된 파일들만 포함되고, 월요일 디렉토리는 월요일과 화요일 사이에 변경되는 파일들만 포함된다.

rsync 방식은 네트워크 기반 백업에 아주 좋다. 테잎에는 rsync할 수 없다.

5. 시스템 여분에 백업 격리

단일 라우트를 사용하고 같은 파일시스템의 다른 디렉토리에 백업한다면, 데이타 손실시에 백업도 함께 손실될 위험이 있다. 여기서는 간단한 방법으로 백업 데이타를 분리시켜 위험을 줄이는 방법을 알아보고자 한다.

1) 쉬운(그러나 나쁜) 방법

전 장에 우리는 동일한 파일시스템 내 다른 디렉토리를 가지고 있는 것을 /destination/ 라고 간주했다. 이 방식을 쉬운(그러나 나쁜) 방법이라고 부르자. 작동을 하긴 하는데, 몇가지 심각한 한계를 가지고 있다.

- 파일시스템에 손상되면 백업 역시 손상된다.
- 하드웨어 부족하게 되면 백업을 재현하기 어려워진다.
- 백업이 접근권한을 유지하게 되면 이용자나 어떤 프로그램, 바이러스 등이 백업에서 파일을 지울수도 있다. 그래서 백업은 읽기전용이어야 한다.
- 여유공간이 없는 경우에는 백업과정으로 시스템이 죽고 복구가 어렵다.
- root 계정이 손상되면, 쉬운(그러나 나쁜) 방법의 경우에는 보안에 취약하다.

그렇지만 보다 견고한 백업을 할 여러가지 쉬운 방법들이 있다.

2) 독립된 파티션 유지하기

백업 디렉토리가 독립된 파티션상에 있다면, 주요 파일시스템에 어떤 손상이 생겨도 백업에 영향을 미치지 않는다. 백업과정에서 디스크공간이 모자라면, 백업이 실패한다. 하지만 시스템 다른 부분에 손상을 주지 않는다. 더 중요한 것은, 독립된 파티션에 백업을 유지한다는 것은 읽기 전용으로 마운트를 유지할 수 있다는 점이다. 자세한 건 다음장에서…

3) 독립된 디스크상의 파티션 이용

백업 파티션이 독립된 하드디스크에 있다면 하드웨어 failure 에도 보호할 수 있다. 이건 정말 중요한 건데, 하드디스크가 매번 문제가 생겨도 데이타를 유지 가능하다.




주의점 : 어떻든 하드디스크 failure 가 발생하는 건 주의해야 한다. 가장 최근 백업으로 인해 변경사항을 잃어버릴 수도 있다. 가정이나 소규모 사무실 이용자를 위해 백업은 매일 이나 시간대별로 한다. 데이타 손실이 되버린 심각한 문제가 발생하는 상황에 대비하여 RAID 시스템이 적당하다.
RAID 는 리눅스에서 제대로 지원된다. 그리고 이 문서에 적힌 방식으로 RAID 시스템의 순환 스냅샷이 생성될 수 있다.

4) 독립된 서버의 디스크 이용하기

여분의 서버가 있으면, 백업서버로 전환해도 좋다. 독립조작이 가능하게 만들고 물리적으로도 독립된 공간(다른 방이나 다른 빌딩)에 두어라. 백업서버의 단일원격서비스를 최대한 줄이고, source 서버와 네트워크 인터페이스만 확보해서 연결해라.

source 서버에서 읽기전용 NFS를 거쳐 백업을 원하는 디렉토리를 보낸다. 백업서버는 전달된 네트워크 디렉토리를 마운트할 수 있고, 스냅샷 경로를 실행한다. 이런 방식을 선택하게 되면 아래와 같은 경우에만 원격으로 공격당할 수 있다.

- 원격 root 의 허점이 읽기전용 NFS 에서 발견될때
- source 서버는 이미 손상된 상태일때

꽤 괜찮은 방식이다. 하지만 편집광이거나 직업이 온라인이면 백업서버를 2개를 구축하고 적어도 하나는 오프라인으로 만들어라.

원격 백업서버를 사용하면서 정보가 보안이 어려울 경우, NFS 는 건너뛰고 대신 "rsync -e ssh" 를 사용해야 한다.




"rsync" 처리과정에서는 NFS 를 뛰어넘는 것 보다 서버모드에서
source 서버와 백업서버사이의 연결이 병목이 되면, NFS 사용 대신 rsync 서버같은 백업 머신 구축을 고민해봐야 한다. 이런 접근방식은 NFS보다 보안이 좋고, 스냅샷이 시스템 디렉토리처럼 마운트된게 보이지 않게 된다.
연구소나 사무실에서 윈도우즈 데스크탑을 사용한다면 백업을 유지하는 가장 쉬운 방법은 적당한 파일만 읽기전용으로 공유하고, 삼바를 사용하는 백업서버에 모든 파일을 마운트하는 것이다. 백업 작업은 마운트된 삼바를 일반 로컬 디렉토리 공유하듯 생각한다.

6. 가능하면 읽기전용으로 백업하기

이번 섹션에서는 백업 수정상태에서 이용자 프로세스를 보호하기 위해 새로 만드는 다른 방식에 대해 알아본다.

여러 이용자가 사용하는 공간에 읽기-쓰기로 마운트된 snapshot 백업 디렉토리가 유지되는 걸 피하고 싶어한다. 불행하게도 항상 읽기전용으로 마운트가 될 수 없고 백업 프로세스 자체가 쓰기 접근을 필요로 한다. 그래서 보통 여러 이용자가 이용하는 공간에서는 읽기 전용으로 마운트된 백업, 동시에 /root/snapshot 같은 사적 공간에서 root에 의해서만 접근되는 읽기-쓰기 로 마운트된 백업을 한다.

대부분 /snapshot 같은 읽기전용으로 마운트된 백업 파티션을 유지하려고 하지만, 스냅샷이 형성되는 동안의 아주 짧은 기간동은에 /root/snapshot같이 읽기-쓰기로 유마운트나 리마운트가 된다. 충격받지는 마시고…

1) 나쁜 방법 : mount / umount

파일시스템은 바쁘거나 몇몇 프로세스가 사용중이면 유마운트되지 않는다. 만약 백업의 읽기전용 복사본을 유마운트하고 어디서나 읽기-쓰기로 마운트할 생각이라면 백업을 보호할 생각은 버려라.

2) 좀 나은 방법 : 대부분 읽기전용으로 mount하기

좀 괜찮지만 그래도 그다지 안전치 못한 방법이 읽기-쓰기 디렉토리를 리마운트하는 거다:




mount -o remount, rw /snapshot
[ run backup process ]
mount -o remount, ro /snapshot

이 방식에는 새로운 문제가 있는데, 백업할 동안 사용자 프로세스가 백업디렉토리에 쓰기작업을 할 수 있다는 사실이다. 따라서 어떤 프로세스가 쓰기작업을 위해 백업파일을 열어놓고 있으면, 리마운트된 읽기전용 백업을 방해하고 백업이 정확하지 못한 약점이 있다.

3) 시도하지만 실제로 작업하지는 않는다 : 2.4 커널의 mount --bind

2.4 시리즈 리눅스 커널로 시작하면 서로 다른 2개의 장소에서 동시에 파일시스템 마운트가 가능하다. "오호라~! 그렇다면 /snapshot 에서 읽기전용 백업 마운트하고 동시에 /root/snapshot 에서 읽기-쓰기 백업 마운트하면 되겠구나"라고 생각하면 오산~!

백업 파티션이 /dev/hdb1 에 있다고 하고, 아래와 같은 명령어를 실행하면,




mount /dev/hdb1 /root/snapshot
mount --bind -o ro /root/snapshot /snapshot

그러면 (적어도 2.4.9 리눅스커널상에서는) mount 는 /root/snapshot 에 읽기-쓰기로, /snapshot 에 읽기전용으로 마운트된 것 처럼 /dev/hdb1 을 보고는 하지만 실제는 그렇지 않다. 시스템을 시험에 들게 하지 마라..




적어도 내 시스템에서는 읽기-쓰기 vs 읽기전용은 마운트의 지점이 아닌 파일시스템의 적절성 문제인 것 같다. 그래서 매번 나는 마운트 상태를 변경하는데, 이렇게 하면 /etc/mtab 이나 /proc/mounts 에 변경사항이 적히지는 않아도 마운트된 파일시스템이 매번 상태에 영향을 준다.

예를 들어, 두번째 mount 호출은 읽기전용으로 마운트가 양쪽다 되고, 백업 프로세스ㅤㅌㅡㅌ 실행되지 않을 것이다. 지워버려~!

4) 내가 사용하는 방법 : localhost상에서 NFS 사용하기

좀 복잡해도 리눅스가 서로 다른 장소에서 서로 다른 접근권한을 가진 mount --bind를 지원하는 한, 이 방법이 최고인 것 같다. 오직 root만 접근 가능한 백업이 저장되어있는 파티션(/root/snapshot 같이)을 마운트해라. 그리고나서 NFS를 거쳐 읽기전용으로 동일한 시스템으로만 출력한다. /etc/exports 에 아래 한줄 추가하면 된다.




/root/snapshot 127.0.0.1(secure, ro,no_root_squash)

그리고나서 /etc/rc.d/init.d/의 nfs 와 portmap 을 시작한다. 마지막으로 출력된 디렉토리를 /snapshot처럼 읽기전용으로 마운트한다.




mount -o ro 127.0.0.1:/root/snapshot /snapshot

그리고나서 모든 작업을 확인한다.




mount
..
/dev/hdb1 on /root/snapshot type ext3 (rw)
127.0.0.1:/root/snapshot on /snapshot type nfs (ro,addr=127.0.0.1)

이렇게하면 root만이 /root/snapshot에 접근하여 백업에 쓰기가 가능하다. 다른 사용자들은 /snapshot 디렉토리를 읽기전용으로 본다. 추가로 /root/snapshot 을 대부분 읽기전용으로 마운트시킬 수 있고, 백업이 발생하는 동안에만 읽기-쓰기로 리마운트가능하다.

7. 추가 : 시간별, 일별, 주별 스냅샷

약간 옆길로 새서, 다중단계 순환 스냅샷도 만들 수 있는데, 예를 들어 최근 3일단위 스냅샷뿐만아니라 최근 4시간단위 스냅샷을 동시에 유지할 수 있고, 주별, 월별도 가능하다. 어떻든 요구사항과 가능한 공간 여하에 달려있다.

1) 단계별 추가 스크립트

가장 쉬운 방법이다. 매 4시간마다 실행되고 시간별로 스냅샷을 순환시키는 스크립트를 돌린다. 또하나의 스크립트는 매일 1번 일별 스냅샷을 순환시키는 스크립트다. 더 높은 단계 스냅샷 때문에 rsync를 사용할 필요도 없다. 그냥 적절한 시간대별로 "cp -al"하면 된다.

2) cron 가지고 실행하기

자동 스냅샷을 운영하려면 root의 crontab 파일에 아래와 같이 추가한다.




0 */4 * * * /usr/local/bin/make_snapshot.sh
0 13 * * * /usr/local/bin/daily_snapshot_rotate.sh

make_snapshot.sh 는 매 4시간마다 실행되는 거고,

daily_snapshot_rotate.sh 는 매일 13:00 에 실행하기 위한 쉘이다. 구체적은 코딩은 부록참조.

매 4시간마다 자세한 백업내용을 담은 cron 프로세스를 메일로 받는게 괴로우면, 아래같이 /dev/null에 make_snapshot.sh 의 출력값을 보내도록한다.




0 */4 * * * /usr/local/bin/make_snapshot.sh > /dev/null 2>&1

다만 이렇게 해놓았을 경우엔 make_snapshot.sh가 어떤 이유로 실행하지 않으면 에러가 생겼다는 걸 알아내기 힘들다는 건 알아둬라. 아예 3번째 스크립트를 짜서 비정상적인 행동 발생을 체크하도록 해도 좋을 거다. (나는 아직 개발 않했지만)

8. 버그

알려진바로는 스냅샷 시스템은 오래된 소유자/권한으로 구성되어 있어, 파일의 소유권이나 접근권한이 변경되면 새로운 소유권/권한이 예전 스냅샷에도 적용된다. 그냥 소유권/권한만 변경하면, rsync가 변경되는 파일 우선순위를 깨지 않기 때문이다. 이건 내가 발견 못한 건데, J.W.Schultz에게 감사한다.

확실히 리눅스 커널 2.4.4와 2.4.9사이엔 몇가지 버그가 있는데 타임스탬프 업데이트하기 위한 mv가 원인이 된다. 그래서 스냅샷 디렉토리 상에 타임스탬프가 부정확해진다. 이 점에 대해선 Claude Felizardo에게 감사한다. 그는 아래 스크립트로 제대로 실행하도록 해주었다.




MV=my_mv;

function my_mv() {
REF=/tmp/makesnapshot-mymv-$$;
touch -r $1 $2;
/bin/mv $1 $2;
touch -r $REF $2;
/bin/rm $REF;
}

9. 부록 : 실제 환경설정




내가 나의 진짜 백업환경설정을 공개하는건 보안상 위험이 있다. 그러니 이 정보 가지고 내 사이트 크랙하지 마라, 부탁..^^ 나는 보안전문가가 아니므로, 나의 셋업엔 취약점이 있다. 여러분 도움으로 고치게 되면 더욱 고맙고…

나는 실제 매 4시간마다 스냅샷과 매일 스냅샷을 위한 2가지 스크립트를 사용한다. 여기에는 /home의 백업 관련된 스크립트 부분이 적혀있다.

/snapshot을 읽기전용 /root/snapshot로 출력하는 NFS-to-localhost 기법을 사용한다. 시스템은 매달 멈추지않고 실행한다.

1) make_snapshot.sh




n/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility
# ----------------------------------------------------------------------
# RCS info: $Id: make_snapshot.sh,v 1.6 2002/04/06 04:20:00 mrubel Exp $
# ----------------------------------------------------------------------
# this needs to be a lot more general, but the basic idea is it makes
# rotating backup-snapshots of /home whenever called
# ----------------------------------------------------------------------
# ------------- system commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;

MOUNT=/bin/mount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;
TOUCH=/bin/touch;

RSYNC=/usr/bin/rsync;
# ------------- file locations -----------------------------------------
MOUNT_DEVICE=/dev/hdb1;
SNAPSHOT_RW=/root/snapshot;
EXCLUDES=/usr/local/etc/backup_exclude;

# ------------- the script itself --------------------------------------
# make sure we're running as root
if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting…"; exit; } fi

# attempt to remount the RW mount point as RW; else abort
$MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite";
exit;
}
fi;

# rotating snapshots of /home (fixme: this should be more general)
# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then
$RM -rf $SNAPSHOT_RW/home/hourly.3 ;
fi ;

# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/hourly.2 ] ; then
$MV $SNAPSHOT_RW/home/hourly.2 $SNAPSHOT_RW/home/hourly.3 ;
fi;
if [ -d $SNAPSHOT_RW/home/hourly.1 ] ; then
$MV $SNAPSHOT_RW/home/hourly.1 $SNAPSHOT_RW/home/hourly.2 ;
fi;

# step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
# if that exists
if [ -d $SNAPSHOT_RW/home/hourly.0 ] ; then
$CP -al $SNAPSHOT_RW/home/hourly.0 $SNAPSHOT_RW/home/hourly.1 ;
fi;

# step 4: rsync from the system into the latest snapshot (notice that
# rsync behaves like cp --remove-destination by default, so the destination
# is unlinked first. If it were not so, this would copy over the other
# snapshot(s) too!
$RSYNC
-va --delete --delete-excluded
--exclude-from="$EXCLUDES"
/home/ $SNAPSHOT_RW/home/hourly.0 ;

# step 5: update the mtime of hourly.0 to reflect the snapshot time
$TOUCH $SNAPSHOT_RW/home/hourly.0 ;

# and thats it for home.
# now remount the RW snapshot mountpoint as readonly

$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
exit;
} fi;


이렇게 적고나서 rsync 호출을 추가한다. 웹브라우저 캐시같은 쓸데없는거 백업하는걸 막는다.

2) daily_snapshot_rotate.sh




#!/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility: daily snapshots
# ----------------------------------------------------------------------
# RCS info: $Id: daily_snapshot_rotate.sh,v 1.2 2002/03/25 21:53:27 mrubel Exp $
# ----------------------------------------------------------------------
# intended to be run daily as a cron job when hourly.3 contains the
# midnight (or whenever you want) snapshot; say, 13:00 for 4-hour snapshots.
# ----------------------------------------------------------------------
# ------------- system commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;
MOUNT=/bin/mount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;

# ------------- file locations -----------------------------------------
MOUNT_DEVICE=/dev/hdb1;
SNAPSHOT_RW=/root/snapshot;

# ------------- the script itself --------------------------------------
# make sure we're running as root
if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting…"; exit; } fi

# attempt to remount the RW mount point as RW; else abort
$MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite";
exit;
}
fi;

# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/daily.2 ] ; then
$RM -rf $SNAPSHOT_RW/home/daily.2 ;
fi ;

# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/daily.1 ] ; then
$MV $SNAPSHOT_RW/home/daily.1 $SNAPSHOT_RW/home/daily.2 ;
fi;
if [ -d $SNAPSHOT_RW/home/daily.0 ] ; then
$MV $SNAPSHOT_RW/home/daily.0 $SNAPSHOT_RW/home/daily.1;
fi;

# step 3: make a hard-link-only (except for dirs) copy of
# hourly.3, assuming that exists, into daily.0
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then
$CP -al $SNAPSHOT_RW/home/hourly.3 $SNAPSHOT_RW/home/daily.0 ;
fi;

# note: do *not* update the mtime of daily.0; it will reflect
# when hourly.3 was made, which should be correct.

# now remount the RW snapshot mountpoint as readonly

$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
exit;
} fi;


3) ls -l /snapshot/home 출력예




total 28
drwxr-xr-x 12 root root 4096 Mar 28 00:00 daily.0
drwxr-xr-x 12 root root 4096 Mar 27 00:00 daily.1
drwxr-xr-x 12 root root 4096 Mar 26 00:00 daily.2
drwxr-xr-x 12 root root 4096 Mar 28 16:00 hourly.0
drwxr-xr-x 12 root root 4096 Mar 28 12:00 hourly.1
drwxr-xr-x 12 root root 4096 Mar 28 08:00 hourly.2
drwxr-xr-x 12 root root 4096 Mar 28 04:00 hourly.3

/snapshot/home/의 하위 디렉토리 각각의 내용들은 스냅샷이 생성되는 시간에 /home에 완전한 이미지가 존재하게 된다. 디렉토리 접근권한에 "w"가 있어도 root 이외엔 아무도 이 디렉토리에 쓸 수 없다. 읽기전용으로 마운트된다.

10. 참고

- Rsync main site : rsync.samba.org

- rdiff-backup : www.stanford.edu/~bescoto/rdiff-backup
: Ben Escoto의 원격 증분백업 유틸리티

- The GNU fileutils package : www.gnu.org/software/fileutils/fileutils.html

- dirvish : www.pegasys.ws/dirvish 

리눅스와 Rsync를 이용한 편리한 자동 스냅샷(snapshot) 백업

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다