증분 백업을 위한 Linux 백업 유틸리티

증분 백업을 위한 Linux 백업 유틸리티

저는 증분 백업 기능이 있으면서도 좀 더 정교한 방식을 갖춘 백업 유틸리티를 찾고 있습니다.

rsync를 시도했지만 내가 원하는 것을 수행할 수 없는 것 같거나, 수행 방법을 모르는 것 같습니다.

다음은 제가 달성하고자 하는 것의 예입니다. 다음 파일이 있습니다.

testdir
├── picture1
├── randomfile1
├── randomfile2
└── textfile1

백업 유틸리티를 실행하고 기본적으로 다른 디렉터리에 이러한 모든 파일의 아카이브(또는 tarball)를 만들고 싶습니다.

$ mystery-command testdir/ testbak
testbak
└── 2020-02-16--05-10-45--testdir.tar

이제 다음 날 구조가 다음과 같도록 파일을 추가한다고 가정해 보겠습니다.

testdir
├── picture1
├── randomfile1
├── randomfile2
├── randomfile3
└── textfile1

이제 미스터리 명령을 실행하면 오늘의 또 다른 타르볼이 표시됩니다.

$ mystery-command testdir/ testbak
testbak
├── 2020-02-16--05-10-45--testdir.tar
└── 2020-02-17--03-24-16--testdir.tar

picture1핵심은 다음과 같습니다. 백업 유틸리티가 randomfile1마지막 백업 이후 , ,이(가) 변경되지 않았다는 사실을 감지 randomfile2하고 새 파일/변경된 파일만 백업하기를 원합니다. 이 경우 다음과 같습니다.textfile1randomfile3

tester@raspberrypi:~ $ tar -tf testbak/2020-02-16--05-10-45--testdir.tar 
testdir/
testdir/randomfile1
testdir/textfile1
testdir/randomfile2
testdir/picture1
tester@raspberrypi:~ $ tar -tf testbak/2020-02-17--03-24-16--testdir.tar 
testdir/randomfile3

마지막 예를 들어, 다음날 내가 변경 textfile1하고 다음을 추가했다고 가정해 보겠습니다 picture2.picture3

$ mystery-command testdir/ testbak
testbak/
├── 2020-02-16--05-10-45--testdir.tar
├── 2020-02-17--03-24-16--testdir.tar
└── 2020-02-18--01-54-41--testdir.tar
tester@raspberrypi:~ $ tar -tf testbak/2020-02-16--05-10-45--testdir.tar 
testdir/
testdir/randomfile1
testdir/textfile1
testdir/randomfile2
testdir/picture1
tester@raspberrypi:~ $ tar -tf testbak/2020-02-17--03-24-16--testdir.tar 
testdir/randomfile3
tester@raspberrypi:~ $ tar -tf testbak/2020-02-18--01-54-41--testdir.tar 
testdir/textfile1
testdir/picture2
testdir/picture3

이 시스템을 사용하면 각 백업 사이의 증분 변경 사항(분명히 모든 초기 파일이 포함된 마스터 백업)만 백업하여 공간을 절약할 수 있으며, 예를 들어 2일 안에 변경하는 경우 증분 변경 사항도 백업합니다. 3일차에 동일한 내용을 다시 변경하면 2일차 변경사항이 포함된 파일을 계속 얻을 수 있지만 3일차가 변경되기 전에는 가능합니다.

나는 이것이 GitHub의 작동 방식과 약간 비슷하다고 생각합니다 :)

diff를 실행한 다음 결과에 따라 백업할 파일을 선택하는 스크립트를 만들 수 있다는 것을 알고 있습니다(또는 더 효율적으로 체크섬을 가져와 비교하는 것임). 하지만 이 작업을 쉽게 수행할 수 있는 유틸리티가 있는지 궁금합니다. 조금:)

답변1

rsync를 시도했지만 내가 원하는 것을 수행할 수 없는 것 같거나, 수행 방법을 모르는 것 같습니다.

diff를 실행한 다음 결과에 따라 백업할 파일을 선택하는 스크립트를 만들 수 있다는 것을 알고 있습니다(또는 더 효율적으로 체크섬을 가져와 비교하는 것임). 하지만 이 작업을 쉽게 수행할 수 있는 유틸리티가 있는지 궁금합니다. 조금:)

rsync차이점을 기반으로 복제하는 프로그램입니다. 기본적으로 최종 수정 시간이나 크기에 차이가 있는 경우에만 복사되지만 -c.

여기서 문제는 tar백업하고 있다는 것입니다. 그렇지 않으면 이 일이 더 쉬워질 것입니다. 나는 당신이 왜 그런 짓을 했는지조차 모릅니다. 압축하면 의미가 있을 수 있지만 그렇게 하지도 않습니다.

이것증분 백업에 관한 Wikipedia 기사rsync다음과 같은 예제 명령이 있습니다 .

rsync -va \
  --link-dest="$dst/2020-02-16--05-10-45--testdir/" \
  "$src/testdir/" \
  "$dst/2020-02-17--03-24-16--testdir/"

파일이 소스에서 변경되지 않은 경우 이전 백업의 파일을 하드 링크하는 것입니다. --copy-dest복사하려는 경우 ( $dst원격에 있거나 더 빠른 드라이브에 있을 때 여전히 더 빠릅니다).

btrfs와 같은 하위 볼륨이 있는 파일 시스템을 사용하는 경우 rsync 전에 이전 백업에서 스냅샷을 생성할 수도 있습니다. 스냅샷은 즉각적이며 추가 공간을 차지하지 않습니다[1].

btrfs subvolume snapshot \
  "$dst/2020-02-16--05-10-45--testdir" \
  "$dst/2020-02-17--03-24-16--testdir"

또는 참조 링크를 지원하는 파일 시스템을 사용하는 경우에도 이 작업을 수행할 수 있습니다. 참조 링크는 새 inode를 생성하지만 소스 파일과 동일한 블록을 참조하여 COW 지원을 활성화함으로써 수행됩니다. 데이터를 읽고 쓰지 않으며, 추가 공간도 필요하지 않기 때문에 여전히 일반 복사보다 속도가 빠릅니다[1].

cp --reflink -av \
  "$dst/2020-02-16--05-10-45--testdir" \
  "$dst/2020-02-17--03-24-16--testdir"

어쨌든, 그런 작업을 수행한 후에는 일반 rsync복사 diff를 수행할 수 있습니다.

rsync -va \
  "$src/testdir/" \
  "$dst/2020-02-17--03-24-16--testdir/"

--delete그러나 이렇게 하면 rsync가 소스에 더 이상 존재하지 않는 파일을 대상에서 제거하게 된다는 점을 추가할 수 있습니다 .

또 다른 유용한 옵션은 -i또는 입니다 --itemize-changes. rsync가 수행하는 변경 사항을 설명하는 간결하고 기계가 읽을 수 있는 출력을 생성합니다. 나는 보통 해당 옵션을 추가하고 다음과 같이 파이프합니다.

rsync -Pai --delete \
  "$src/testdir/" \
  "$dst/2020-02-17--03-24-16--testdir/" \
|& tee -a "$dst/2020-02-17--03-24-16--testdir.log"

간단한 파일을 통해 변경 사항을 기록합니다 grep. |&stdout과 stderr을 파이프하는 것입니다 .

는 and 의 약자입니다 -P. 부분적으로 전송된 파일을 보관하지만 더 중요한 것은 각 파일의 진행 상황을 보고하는 것입니다.--partial--progress--partial--progress

tar를 사용하여 변경 사항을 보관하는 것과 어떻게 비교됩니까?

위의 해결 방법을 사용하면 디렉터리에 모든 내용이 포함된 것처럼 보입니다. 이 경우에도 백업 횟수/빈도에 관계없이 변경만 수행하는 일반 tar 아카이브와 거의 동일한 공간을 차지합니다. 이는 하드 링크, 리퍼러 링크 및 스냅샷이 작동하는 방식 때문입니다. 백업을 생성할 때 대역폭 사용량은 동일합니다.

장점은 다음과 같습니다.

  • rsync는 백업의 차이점만 전송하기 때문에 rsync를 사용하면 백업을 복원하는 것이 쉽고 빠릅니다.
  • 필요한 경우 검색하고 수정하기가 더 쉽습니다.
  • 파일 삭제는 새 백업에 파일이 없음으로 자연스럽게 인코딩될 수 있습니다. tar 아카이브로 작업할 때 파일 삭제 foo, 태그 지정 foo.DELETED또는 복잡한 작업 수행과 같은 해킹 방법에 의존해야 합니다. 예를 들어 이중성을 사용한 적은 없지만 해당 문서를 보면 새 tar에 같은 이름의 빈 파일을 추가하고 해당 파일의 원래 서명을 별도의 .sigtar 파일에 저장하여 삭제를 인코딩하는 것으로 보입니다. 파일 삭제와 실제 빈 파일의 변경 사항을 구별하기 위해 원래 서명을 빈 파일의 서명과 비교하는 것 같습니다.

여전히 서로 다른(추가 또는 수정된) 파일만 저장하도록 각 백업을 설정하려는 경우 --link-dest위의 해결 방법을 사용한 후 다음과 같은 방법을 사용하여 하드 링크를 제거할 수 있습니다.

find $new_backup -type f ! -links 1 -delete

[1] 엄밀히 말하면 파일 이름 등과 같은 중복 메타데이터 형태로 추가 공간을 사용합니다. 그러나 누구라도 이것을 사소한 것으로 생각할 것이라고 생각합니다.

답변2

증분 모드가 존재 하지만 tar작업을 수행할 수 있는 좀 더 포괄적인 도구가 있습니다.

증분 백업을 지원할 뿐만 아니라 전체 백업이 필요한 일정을 쉽게 구성할 수도 있습니다. 예를 들어 duplicity: duplicity --full-if-older-than 1M은 전체 백업이 실행되는지 확인합니다. 또한 특정 파일로 시간을 거슬러 올라가는 기능도 지원합니다. 일반 tar를 사용하면 올바른 파일이 포함된 파일을 찾을 때까지 모든 델타 파일을 반복해야 합니다.

또한 다양한 백엔드(예: SFTP, Blob 저장소 등)에 대한 암호화 및 업로드를 지원합니다. 분명히 암호화하는 경우 키를 보조 백업에 백업하는 것을 잊지 마십시오!

또 다른 중요한 측면은 예를 들어 를 사용하여 백업의 무결성을 확인하여 복원할 수 있다는 것입니다 duplicity verify.

나는 Git 기반 백업 전략에 대해 부정적인 조언을 하고 싶습니다. 대규모 복원에는 시간이 많이 걸립니다.

답변3

그리고 왜 너 자신에 대해 생각하지 않니 git?

한 번의 전체 백업과 두 번의 증분 백업 후에 설명하는 전략은 진행할수록 복잡해집니다. 실수하기도 쉽고,할 수 있는변화에 따라 효율성이 매우 비효율적이 될 수 있습니다. 때때로 새로운 전체 백업을 수행하는 순환이 있어야 합니다. 그런 다음 이전 백업을 유지하시겠습니까?


주어진피복재"testdir" 디렉토리에는 다음과 같은 내용이 포함되어 있습니다.프로젝트(파일 및 하위 디렉터리) - git기본적으로 .git데이터에 대한 숨겨진 하위 디렉터리를 만듭니다 . 이는 로컬이며 추가입니다.버전 관리특징. 백업의 경우 미디어에 보관/복사하거나 네트워크를 통해 복제할 수 있습니다.

이것개정 관리요청하지 않고 얻는 것은 git diff 저장소의 부작용입니다.

모든 분기/분기 등을 생략할 수 있습니다. 이는 "마스터"라는 분기가 있음을 의미합니다.

커밋하기(실제로 git 아카이브/저장소에 쓰기) 전에 프로필에 대한 최소 사용자를 구성해야 합니다. 그런 다음 먼저 하위 디렉터리(아마도 tmpfs)에서 연구하고 테스트해야 합니다. 때때로 Git은 tar만큼 까다로울 수 있습니다.

어쨌든, 댓글에서 알 수 있듯이 백업은 쉽고, 어려운 부분은 복원입니다.


git의 단점은 오버헤드가 거의 없고 피해가 너무 많다는 것입니다.

장점은 다음과 같습니다.레퍼토리내용과 파일 이름. 차이점에 따라 필요한 것만 저장합니다(적어도 텍스트 파일의 경우).


내 디렉토리에는 3개의 파일이 있습니다. 그 후에는 git init260K 디렉토리 가 git add .있습니다 .git commit.git

그런 다음 나는 cp -r .git /tmp/abpic.git(백업을 저장하기에 좋은 장소입니다 :). 내 것은 rm154K jpg이고변화텍스트 파일. 나도 rm -r .git.

  ]# ls
    atext  btext

  ]# git --git-dir=/tmp/abpic.git/ ls-files
    atext
    btext
    pic154k.jpg

파일을 복원하기 전에 정확한 차이점을 얻을 수 있습니다.

]# git --git-dir=/tmp/abpic.git/ status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   atext
        deleted:    pic154k.jpg

no changes added to commit (use "git add" and/or "git commit -a")

git restore여기서는 프롬프트를 따르고 싶습니다 .

뒤쪽에 git --git-dir=/tmp/abpic.git/ restore \*:

]# ls -st
total 164
  4 atext  156 pic154k.jpg    4 btext

JPEG가 돌아왔고 텍스트 파일 btext아니요업데이트되었습니다(타임스탬프 보존). 의 수정사항을 atext덮어씁니다.

저장소와 (작업) 디렉토리를 재결합하려면 간단히 다시 복사하면 됩니다.

]# cp -r /tmp/abpic.git/ .git
]# git status
On branch master
nothing to commit, working tree clean

현재 디렉토리의 파일은 .git아카이브( 뒤 restore)와 동일합니다. 새로운 변경 사항이 표시되며 계획 없이 추가하고 커밋할 수 있습니다. 백업을 위해 다른 매체에 간단히 저장할 수 있습니다.


status파일을 수정한 후 또는 다음을 사용할 수 있습니다 diff.

]# echo more >>btext 

]# git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   btext

no changes added to commit (use "git add" and/or "git commit -a")

]# git diff
diff --git a/btext b/btext
index 96b5d76..a4a6c5b 100644
--- a/btext
+++ b/btext
@@ -1,2 +1,3 @@
 This is file b
 second line
+more
#]

git"btext" 파일에서 "+more"를 아는 것과 마찬가지로 해당 줄만 증분적으로 저장됩니다.

git add .(또는 git add btext) 이후 status명령은 빨간색에서 녹색으로 전환되고 commit정보를 제공합니다.

]# git add .
]# git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   btext

]# git commit -m 'btext: more'
[master fad0453] btext: more
 1 file changed, 1 insertion(+)

실제로 어떤 방식으로든 내용을 이해할 수 있습니다.

]# git ls-tree @
100644 blob 321e55a5dc61e25fe34e7c79f388101bd1ae4bbf    atext
100644 blob a4a6c5bd3359d84705e5fd01884caa8abd1736d0    btext
100644 blob 2d550ffe96aa4347e465109831ac52b7897b9f0d    pic154k.jpg

그런 다음 처음 4개의 16진수 해시 번호

]# git cat-file blob a4a6
This is file b
second line
more

커밋을 통해 시간을 되돌리려면 다음을 수행하세요.

]# git ls-tree @^
100644 blob 321e55a5dc61e25fe34e7c79f388101bd1ae4bbf    atext
100644 blob 96b5d76c5ee3ccb7e02be421e21c4fb8b96ca2f0    btext
100644 blob 2d550ffe96aa4347e465109831ac52b7897b9f0d    pic154k.jpg

]# git cat-file blob 96b5
This is file b
second line

btext의 blob에는 마지막 커밋 전에 다른 해시가 있고 다른 blob에는 동일한 해시가 있습니다.

개요는 다음과 같습니다.

]# git log
commit fad04538f7f8ddae1f630b648d1fe85c1fafa1b4 (HEAD -> master)
Author: Your Name <[email protected]>
Date:   Sun Feb 16 10:51:51 2020 +0000

    btext: more

commit 0bfc1837e20988f1b80f8b7070c5cdd2de346dc7
Author: Your Name <[email protected]>
Date:   Sun Feb 16 08:45:16 2020 +0000

    added 3 files with 'add .'

타임스탬프가 있는 tar 파일을 수동으로 추가하는 대신 메시지와 날짜(및 작성자)를 사용하여 커밋합니다. 이러한 커밋에는 파일 목록과 콘텐츠가 논리적으로 첨부됩니다.

Simple은 gitSimple보다 20% 더 복잡 tar하지만 결정적으로 50% 더 많은 기능을 얻을 수 있습니다.


OP의 세 번째 변경 사항을 만들고 싶습니다. 하나의 파일과 두 개의 새로운 "그림" 파일을 변경합니다. 나는 해냈지만 지금은 다음과 같습니다.

]# git log
commit deca7be7de8571a222d9fb9c0d1287e1d4d3160c (HEAD -> master)
Author: Your Name <[email protected]>
Date:   Sun Feb 16 17:56:18 2020 +0000

    didn't add the pics before :(

commit b0355a07476c8d8103ce937ddc372575f0fb8ebf
Author: Your Name <[email protected]>
Date:   Sun Feb 16 17:54:03 2020 +0000

    Two new picture files
    Had to change btext...

commit fad04538f7f8ddae1f630b648d1fe85c1fafa1b4
Author: Your Name <[email protected]>
Date:   Sun Feb 16 10:51:51 2020 +0000

    btext: more

commit 0bfc1837e20988f1b80f8b7070c5cdd2de346dc7
Author: Your Name <[email protected]>
Date:   Sun Feb 16 08:45:16 2020 +0000

    added 3 files with 'add .'
]# 

그렇다면 오후 6시 직전에 두 개의 제출물에서 "너의 이름"이라는 사람은 정확히 무엇을 했습니까?

마지막 커밋 세부정보는 다음과 같습니다.

]# git show
commit deca7be7de8571a222d9fb9c0d1287e1d4d3160c (HEAD -> master)
Author: Your Name <[email protected]>
Date:   Sun Feb 16 17:56:18 2020 +0000

    didn't add the pics before :(

diff --git a/picture2 b/picture2
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/picture2
@@ -0,0 +1 @@
+1
diff --git a/picture3 b/picture3
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/picture3
@@ -0,0 +1 @@
+2
]# 

그리고 두 번째 이미지를 알리는 메시지가 있는 두 번째 커밋을 확인하세요.

]# git show @^
commit b0355a07476c8d8103ce937ddc372575f0fb8ebf
Author: Your Name <[email protected]>
Date:   Sun Feb 16 17:54:03 2020 +0000

    Two new picture files
    Had to change btext...

diff --git a/btext b/btext
index a4a6c5b..de7291e 100644
--- a/btext
+++ b/btext
@@ -1,3 +1 @@
-This is file b
-second line
-more
+Completely changed file b
]# 

git commit -a바로가기를 시도했는데 git add .두 파일이새로운(추적되지 않음) 빨간색으로 표시되어 있지만 git status앞서 말했듯이 git은 tar나 unix보다 까다롭지 않습니다.


"당신의 데뷔작은 당신에게 필요한 것만 알지만 나는 당신이 원하는 것을 알고 있습니다."(또는 그 반대입니다. 요점은 항상 동일하지는 않다는 것입니다)

답변4

고쳐 쓰다:

여기에서 몇 가지 고려 사항을 참조하세요. 전체 시스템 백업을 위해 tar를 사용할 수 있습니까?

이 답변에 따르면 tar를 사용하여 증분 백업을 복원하는 것은 오류가 발생하기 쉬우므로 피해야 합니다. 필요할 때 데이터를 복구할 수 있다는 확신이 없다면 다음 방법을 사용하지 마십시오.


문서에 따르면 -g/--listed-incremental 옵션을 사용하여 증분 tar 파일을 생성할 수 있습니다.

tar -cg data.inc -f DATE-data.tar /path/to/data

그럼 다음번에도 비슷한 일을 해보세요

tar -cg data.inc -f NEWDATE-data.tar /path/to/data

여기서 data.inc는 델타 메타데이터이고 DATE-data.tar는 델타 아카이브입니다.

관련 정보