tar 를 사용한 증분 복사본(Incremental Dumps) 만들기.

이런 저런 문서를 참고했지만, 가장 도움이 된 건 역시 Gnu tar 공식 문서.


굳이 압축을 하지 않을 예정이라면, tar 로 묶나, 그냥 rsync 로 복사를 하나 큰 차이는 없을 듯 하다. rsync 도 exclude-from 이 있으므로, tar 와 사용은 크게 다르지 않을텐데, 이 글에선 tar 만 정리해보기로 한다.

Backup

사용법:

tar --create \
 	--listed-incremental="$SNAPSHOT" \
	--file="$BACKUP_FILE" \
	--exclude-from="$EXCLUDE_LIST" \
	--files-from="$BACKUP_LIST" \
	--no-check-device

얼마 전 프로그래밍 책을 보니, 상수일 경우 대문자로 쓰는게 일반화 되어 있다고 한다. 따라서 그 규칙을 따랐다.

‘증분’ 기능을 따르려면 --listed-incremental 을 사용해야 한다. $SNAPSHOT 에는 적절한 파일명을 주면 된다.
이 파일은 일종의 ‘정보’ 파일로, 어떤 파일들이 복사가 되었는지에 대해 기록되어 있다.

일단, 부수 선택사항을 모두 빼고 알짜면 놓고 보면 이런 식이다.

$ tar --create \
           --file=archive.1.tar \
           --listed-incremental=/var/log/usr.snar \
           /usr

/usr 을 tar 로 묶되, 파일명은 archrive.1.tar 로 하고, 증분 방식을 사용하며, 그 정보(snapshot)는 usr.snar 에 기록하라, 이게 저 명령의 처음이자 끝이다.

‘증분’ 이라 했으므로, 첫 작업 이후 두번째, 세번째.. 가 필요할텐데, 맨 첫 작업은 일반 복사와 다름이 없다. 이것을 Level-0 작업이라 부르고, snapshot 은 새로 생성 된다.

이후 첫 작업은 level-1 이 되며, snapshot 은 갱신된다. 즉, 이미 스냅샷이 있는 경우는 level 이 증가되며 증분 복사되고 아울러 스냅샷 파일이 갱신된다. 스냅샷이 없는 경우 완전한 복사가 이뤄지고, 스냅샷이 새로 생성된다.

그럼 첫번째 증분 복사는 어떻게 해야 하려나? 위와 똑같은데, 파일명만 바꿔주면 된다.

$ tar --create \
           --file=archive.2.tar \
           --listed-incremental=/var/log/usr.snar \
           /usr

이 명령은, 최초 파일(Level-0)과 비교하여, 바뀐 부분(추가/삭제)만 archive.2.tar 에 복사한다. 추가된 파일은 당연히 복사되고, 삭제 정보가 기록되는 듯 하다.

즉, 계속 증분하여 복사하려면, 파일명이 달라져야 한다는 사실을 잊지 말아야 한다. 만약 같은 파일명을 준다면, 원 파일을 덮어 쓰게 되어 원하지 않는 결과를 얻게 된다.
(스크립트로 이 작업을 실행한다면, 파일명을 날짜등으로 처리하여 실행 때마다 달라지게 한다.)

Restore

복원은 생성한 순서대로 실행한다. archive.1.tar, archive.2.tar, archive.3.tar … archive.n.tar 순으로 만들었다면, 역시 그 순서대로 복원한다.

$ tar --extract \
           --listed-incremental=/dev/null \
           --file archive.1.tar
$ tar --extract \
           --listed-incremental=/dev/null \
           --file archive.2.tar
$ tar --extract \
           --listed-incremental=/dev/null \
           --file archive.3.tar
......
$ tar --extract \
           --listed-incremental=/dev/null \
           --file archive.n.tar

복원할 때도 --listed-incremental 은 넣어줘야 한다. 그렇지 않으면 증분 방식인지 아닌지 확인할 수가 없기 때문이다. 단, 이 때는 snapshot 파일은 불필요하고, 그냥 ‘아무 내용’이나 넣어주면 된다고 하는데, 통상 /dev/null 을 사용한다고 한다.

그런데.. ‘지워진 파일’에 대한 정보는 어떻게 기록이 되는지 알 수가 없네.
어쨌든, 최종 복원된 결과에 보면, 지워진 파일은 당연히 보이지 않는다.

Include/Exclude

증분에서도 마찬가지로, include, exclude 를 사용할 수 있다. 결합하면 이런 형태가 된다.

tar --create \
 	--listed-incremental="$SNAPSHOT" \
	--file="$BACKUP_FILE" \
	--exclude-from="$EXCLUDE_LIST" \
	--files-from="$BACKUP_LIST"

증분이 안되는 듯 할 때?

그런데, 간혹 추가/수정된 파일만 복사되는게 아니고, 전체가 모두 tar 로 옮겨지는 경우가 있다. 왜 이런 지는 알 수가 없다. gnu tar 문서엔 이런 내용이 있긴 한데..

Apart from using NFS, there are a number of cases where relying on device numbers can cause spurious redumping of unmodified files. For example, this occurs when archiving LVM snapshot volumes. To avoid this, use `–no-check-device’ option

Gnu tar

아직 이 옵션을 주고 시험을 해보지는 못했다. 며칠 뒤 결과가 나오면, 내용을 정리해보도록 한다.

아무튼, 이렇게 하면 spurious(이런 단어 첨 봤다. 가짜, 의사(疑似)라는 뜻.) redumping 을 방지할 수 있다고 한다.
그리하여, 최종 완성된 명령어는 다음과 같다. (이 글 맨 위도 있던 바로 그!)

tar --create \
 	--listed-incremental="$SNAPSHOT" \
	--file="$BACKUP_FILE" \
	--exclude-from="$EXCLUDE_LIST" \
	--files-from="$BACKUP_LIST" \
	--no-check-device

그냥 이렇게 사용하기 보다는, 스크립트를 만들어, 주기로 보관하는 기능을 사용하는게 일반화 되어 있다.

파일명은 날짜에 따라 바뀌게끔 하고, 매일 증분하여 복사를 하고, 일주일 단위로 새 스냅샷을 만드는 식으로. 즉, 일주일의 첫 날엔 전체 복사(예를 들어 월요일), 그 다음 날(화요일)부터는 증분으로 진행하다가 일요일까지 증분을 마치고, 다시 월요일이 되면 새롭게 전체 복사, 다시 증분 복사.. 이런 식이다.

물론, 전체 복사를 시작할 때는 이전에 생성한 파일들은 다른 곳으로 옮기든가, 아니면 날짜 별로 지우든가(2주 지나면 삭제 등등)하는 식으로 스크립트를 만들면 되겠다.

안녕하세요. 글 남겨주셔서 고맙습니다.