Raspberry Pi를 사용하여 자체 백업을 만들 수 있습니까?


78

이 질문 은 외부 컴퓨터를 사용하여 RPi 백업을 ​​만드는 방법에 대한 질문에 대한 답변입니다.

현재 사용중인 SD 카드의 백업 이미지를 만들어 USB 저장 장치의 파일로 복사 할 수 있는지 궁금합니다. 이게 가능해? 그렇지 않은 경우 다른 컴퓨터를 사용하지 않고 RPi 백업을 ​​만들 수있는 방법이 있습니까?


2
물론, / tmp, / run, / proc, / sys, / dev 및 / mnt는 건너 뜁니다. 이미지를 만들 필요가 없으며 이미지를 만들거나 업데이트 할 수있는 백업이 필요합니다. 그래서 사용하지 않는 dd조사, rsync.
goldilocks

1
@goldilocks 당신이 염두에두고 백업 및 복원 프로세스를 설명하는 더 완전한 답변 으로이 의견을 살려 주시면 좋겠습니다.
Eric Wilson

완료-시간을 찾기까지 며칠이 걸렸습니다.
goldilocks

1
대상 볼륨이 충분히 큰 경우 파일 시스템을 읽기 전용으로 다시 마운트하고 dd적절한 블록 크기 로 복사하는 것이 "새"복사에 가장 빠를 것입니다. 플래시 / SD 미디어에 파일 별 복사를 수행하는 것은 좋지 않습니다.
Chris Stratton

답변:


86

다음 rsync은 Pi 백업에 사용하는 소개 입니다. 초기 백업이 생성되면이 방법으로 최신 상태를 유지하는 것이 전체 이미지를 지속적으로 리핑하는 것보다 훨씬 빠릅니다. 로컬 하드 드라이브 나 네트워크를 통해이 작업을 수행 할 수 있습니다.

실제로 파일 시스템에있는 일부 항목은 런타임에만 존재하기 때문에 실행중인 시스템의 전체 사본을 백업으로 원하지 않습니다. 백업에서 것을 포함하고 나중에 이미지를 재현하는 데 사용 할 수 있습니다 당신을 위해 문제를 만들 수 있습니다.

다른 예외도 있습니다. 제외 할 rsync( glob ) 패턴 목록을 승인 할 수 있으며 파일에서 읽을 수 있으므로 먼저 해당 파일에 포함 된 내용을 살펴 보겠습니다. 항목은 형식이 /directory/*아니며 형식이 아닙니다 /directory. 왜냐하면 우리는 그것들이 존재하기를 원하기 때문입니다. 그러나 우리는 그 안에 아무것도 복사하고 싶지 않습니다.

/proc/*
/sys/*

이들은 실제로 디스크에 존재하지 않습니다. 그것들은 커널에 대한 인터페이스이며, 메모리에서 커널을 생성하고 유지합니다 . 이것을 복사 한 다음 다시 시스템에 복사하여 부팅하면, 커널은 인터페이스의 마운트 지점으로 커널을 사용하기 때문에 (최상의) 의미가 없습니다. 데이터가 들어있는 디렉토리에서 시도하십시오. 그것은 작동하고 아무런 해를 끼치 지 않지만 디렉토리에있는 것들에 액세스 할 수 없습니다.]

/sys/proc마운트 지점이 존재 하는 것이 중요 합니다. 그러나 그들은 아무것도 포함해서는 안됩니다. 다음:

/dev/*

dev디렉토리는 확실히 같은 것이 아니다 proc하고 sys있지만 우리의 목적을 위해. 당신이 당신의 백업 또는 무언가에 동일한 장치 노드를 가질 수 있도록 이것을 저장해야한다고 생각한다면, 잘못되었습니다 . 귀찮게하지 마십시오. 복사하지 마십시오 dev. 옛날 옛적에 리눅스는 그런 식으로 작동했지만 더 이상 작동하지 않습니다.

/boot/*

이것은 Raspbian과 같은 Pi 관련 배포판을 가장 많이 사용하는 특별한 경우입니다. 실제로 첫 번째 vfat 파티션의 마운트 지점입니다. 우리는 그것을 별도로 처리 할 것입니다. 무엇을하든 여기에 포함시키지 않아도됩니다. 다시 말하지만 마운트 지점이기 때문입니다.

/tmp/*
/run/*

/run일반적으로 디스크에도없고 메모리에도 있습니다. 아마도 /tmp너무 될 수 있습니다 (이것은 약간의 SD 카드 작업을 저장합니다). 어쨌든 이름에서 알 수 있듯이 영구 데이터를 저장하기위한 장소는 아닙니다. 이를 사용하는 응용 프로그램은 부팅 할 때마다 삭제 될 수 있습니다.

/mnt/*
/media/*

파일 시스템에서 해당 장치의 위치를 ​​제외하지 않으면 하드 드라이브 또는 USB 스틱에 백업하려는 경우 장치가 장치에 /mnt있거나 /media자동 마운트가 후자를 사용하는 경우 특히 중요 합니다. 공간이 부족해질 때까지 드라이브의 내용을 자체적으로 백업하는 루프를 만듭니다. 내가 생각하는 rsync 수도 벙어리 무언가를 발견하지만, 전제 테스트를 피하려고 똑똑합니다.

실제 백업으로 : 로컬로 마운트 된 하드 드라이브, USB 등에 백업 할 디렉토리를 만듭니다 (예 : "pi_backup"). ssh네트워크 마운트 파일 시스템을 사용하거나 (아래 참조) 원격 위치에 교대로 백업 할 수 있지만 처음 시간이 걸릴 수 있습니다.

제외 할 목록이 포함 된 파일이 /rsync-exclude.txt1 이고 드라이브가 /mnt/usbhd인 경우 실제 백업을 수행하려면 다음을 수행하십시오.

rsync -aHv --delete --exclude-from=/rsync-exclude.txt / /mnt/usbhd/pi_backup/

에 슬래시가pi_backup/ 있습니다.

이것은 시간이 걸리고 많은 출력을 생성합니다 (대신 로그에서 검사하려면을 추가하십시오 > rsync.log). --delete처음에는 의미가 없지만 백업을 업데이트 된 상태로 유지하려면 사용하십시오. 그러면 나중에 Pi에서 삭제 한 항목도 백업에서 제거됩니다. a및 디렉토리에 세트 재귀 모든 파일이 일치하는 속성을 확인합니다. 하드 링크-H 를 유지하는 것입니다 2 , 장황한 것이므로 일부 출력을 얻습니다 (그렇지 않으면 조용합니다). 자세한 내용 을 참조하십시오 .vrsyncman rsync

--exclude-from파일을 건너 뛸 수있는 바로 가기가 있습니다 . 복사하고 싶지 않은 모든 것들이 /tmp별도의 파일 시스템에 있다고 확신하면 다음을 사용할 수 있습니다.

rsync -axHv --delete-during / /mnt/usbhd/pi_backup/

-x삽입되었습니다. 이것은 짧은 형식으로 파일 시스템 경계를 넘지 않도록 --one-file-system지시 rsync합니다. 개인적으로 나는을 선호 --exclude-from하지만 기본 Raspbian과 같이 --one-file-system잘 작동합니다. -xtra 조심 하고 싶다면 둘 다 사용할 수 있습니다 . : D

그것은 완전한 백업이 아닙니다. 아무 것도 넣지 않은 상태 boot에서 백업을 사용하여 컴퓨터에 카드를 넣고 실행하여 시스템을 복원하는 것으로 충분하다면 충분합니다 .

rsync -av --delete-during /mnt/usbhd/pi_backup/ /mnt/sdcard_partition2/

새 이미지가있는 카드를 사용하여이 작업을 수행 할 수도 있습니다 (기본 이미지와 동일하다고 가정). 이미지를 만들어야하는 경우 (대부분의 이미지를 덮어 쓰기 때문에) 비효율적입니다. 이러한 이미지가있는 USB 어댑터를 통해 다른 SD 카드를 연결하고 위의 방법을 사용하여 중복 카드를 유지할 수도 있습니다.

을 포함하여 /boot(예를 들어, 커스텀 커널) 에 물건을 넣었다면 , /boot/config.txt너무 백업하지 않아도됩니다 (꽤 간단합니다. 별도로 수행하면 복원 할 때 해당 항목이 첫 번째 파티션으로 이동합니다.

Raspbian 스타일 이미지 를 생성 한 다음 백업 할 수 있는 경우 여기를 참조하십시오 . 다만 오히려 다루는 것보다 - 당신은 빈 Raspbian 스타일의 카드를 만들 비슷한 방법을 사용할 수 있습니다 .img당신은 실제 장치 (예를 처리 할 것, 파일 /dev/sdb당신이해야 할 모든이와 파티션 테이블을 만드는 것입니다,)을 의미 fdisk하고 형식 /dev/sdb1sdb2(또는 무엇이든) mkfs.

그러나 전체 이미지를 복사하는 것이 더 쉽습니다! 왜 이것을 귀찮게합니까?

그렇게 어렵지 않습니다. 10 분 안에 빈 카드 (마지막 링크에 따라 포맷 된)로 복구했습니다. 그렇습니다. 단순히 사용 dd하는 것이 더 간단합니다 (혼동하는 단어와 같은 것을 발견하면 ...)하지만 100 %마다 수행해야하기 때문에 백업을 업데이트 할 때마다 꽤 오래 걸립니다. 을 사용 rsync하면 백업이 존재하면 업데이트 속도가 훨씬 빨라지므로 매일 cron을 통해 고통없이 발생하도록 설정할 수 있습니다. 네트워크를 통해서도. 6 시간마다. 자주할수록 시간이 덜 걸립니다.

rsync 통하다 ssh

예를 들면 다음과 같습니다.

rsync [options] --rsh="ssh [ssh options]" root@[the pi ip]:/ /backup/rpi/

"옵션"은 예를 들어 -av --delete --exclude-from=/rsync-exclude.txt"ssh 옵션"은 일반적으로 사용하는 모든 것입니다 (있는 경우). 을 통해 당신은 루트 액세스 권한이 있어야합니다 ssh시스템 백업의 목적 (설정이 작업을 수행 할 수 PermitRootLogin=yes있는 /etc/ssh/sshd_config서버를 다시 시작).


1 이 파일을 보관해야합니다. #또는로 시작하는 줄에 주석을 넣을 수 있습니다 ;. 여기에는 실제 rsync명령 이 포함될 수 있으며 나중에 복사하여 붙여 넣을 수 있으므로 매번 기억할 필요는 없습니다.

2 지적한 크리스 덕분 rsync에이 작업은 자동으로 수행되지 않습니다.


미역취 속의 일종. 그것은 rysync를 잘 사용하는 것처럼 보입니다. 우리를 위해 스크립트에 넣을 기회가 있습니까?
전체주의

모든 마운트 포인트를 수동으로 제외하는 대신 왜 그렇지 mkdir /tmp/backupable && mount --bind / /tmp/backupable않습니까? 또한 마운트 된 무언가에 의해 "그림자"로 표시되는 곳에 저장된 데이터를 백업 할 수 있다는 장점이 있습니다.
n.st

@ n.st 좋은 생각 (lol)! 사용 --exclude-from하는 것이 더 좋은 아이디어 라고 생각하지만 질문에 대한 제안을 편집했습니다 . 시간이 있다면, 이것을 별도의 답변으로 써서 내 투표권을 가질 수 있습니다. 이 대답은 오랫동안 감겨 있습니다.
금발 미녀는

1
@IgorGanapolsky 의도는 이미지를 만들지 않는 것입니다 ( "하지만 전체 이미지를 복사하는 것이 더 쉽습니다! 왜 이것을 귀찮게합니까?" 부분 참조). 한 번 생성하면 유지 관리가 쉽고 빠를뿐만 아니라 일반적으로이 방법이 더 유연합니다. 나중에 사용하여 만들려면 .img할 수 있습니다. 이것 과 이것들은 그것들이 어떻게 구성되고 만들어 질 수 있는지 설명하는데 도움 될 것입니다.
goldilocks

1
"완전한 백업이 아닙니다 ..."로 시작하는 단락을 참조하십시오 . 기본적으로 정반대입니다. 이것은 사람들이 일반적으로 혼동하는 개념에 도움이 될 수 있습니다 .
goldilocks

24

회원이 만든 Raspberry Community의 작업 스크립트.

코드를 원하는대로 재사용하고 조정할 수 있습니다.

#!/bin/bash

# Setting up directories
SUBDIR=raspberrypi_backups
DIR=/hdd/$SUBDIR

echo "Starting RaspberryPI backup process!"

# First check if pv package is installed, if not, install it first
PACKAGESTATUS=`dpkg -s pv | grep Status`;

if [[ $PACKAGESTATUS == S* ]]
   then
      echo "Package 'pv' is installed."
   else
      echo "Package 'pv' is NOT installed."
      echo "Installing package 'pv'. Please wait..."
      apt-get -y install pv
fi

# Check if backup directory exists
if [ ! -d "$DIR" ];
   then
      echo "Backup directory $DIR doesn't exist, creating it now!"
      mkdir $DIR
fi

# Create a filename with datestamp for our current backup (without .img suffix)
OFILE="$DIR/backup_$(date +%Y%m%d_%H%M%S)"

# Create final filename, with suffix
OFILEFINAL=$OFILE.img

# First sync disks
sync; sync

# Shut down some services before starting backup process
echo "Stopping some services before backup."
service apache2 stop
service mysql stop
service cron stop

# Begin the backup process, should take about 1 hour from 8Gb SD card to HDD
echo "Backing up SD card to USB HDD."
echo "This will take some time depending on your SD card size and read performance. Please wait..."
SDSIZE=`blockdev --getsize64 /dev/mmcblk0`;
pv -tpreb /dev/mmcblk0 -s $SDSIZE | dd of=$OFILE bs=1M conv=sync,noerror iflag=fullblock

# Wait for DD to finish and catch result
RESULT=$?

# Start services again that where shutdown before backup process
echo "Start the stopped services again."
service apache2 start
service mysql start
service cron start

# If command has completed successfully, delete previous backups and exit
if [ $RESULT = 0 ];
   then
      echo "Successful backup, previous backup files will be deleted."
      rm -f $DIR/backup_*.tar.gz
      mv $OFILE $OFILEFINAL
      echo "Backup is being tarred. Please wait..."
      tar zcf $OFILEFINAL.tar.gz $OFILEFINAL
      rm -rf $OFILEFINAL
      echo "RaspberryPI backup process completed! FILE: $OFILEFINAL.tar.gz"
      exit 0
# Else remove attempted backup file
   else
      echo "Backup failed! Previous backup files untouched."
      echo "Please check there is sufficient space on the HDD."
      rm -f $OFILE
      echo "RaspberryPI backup process failed!"
      exit 1
fi

콘텐츠를 완성하는 데 도움이되도록 원래 포럼에 의견을 추가하거나 자신의 버전을 게시하십시오. 조금 줘 조금주세요.

* AndersW를 돌려 주셔서 감사합니다. (GIT 스크립트를 보려면 클릭하십시오)


2
pi가 백업되는 동안 파일 시스템 (파일 삭제, 새 파일 추가)이 변경되면 어떻게됩니까?
keiki

2
rsync로 실행되는 동안 여러 디스크를 백업했으며 이러한 파일 백업에서 필요한 것을 정확하게 얻을 수있었습니다. 그러나 일반적으로 파일 시스템이 마운트되어있는 동안 (*) 유닉스 파일 시스템은 모든 비트를 제자리에 정확하게 복사 할 수 없습니다. 시스템을 마운트하는 동안 만들어진 복사본을 "더티 복사본"이라고도합니다. 더티 카피의 품질을 향상시키기 위해 여러 가지 조치를 취할 수 있지만 (위의 스크립트와 마찬가지로 cron 및 mysql을 종료 함) 완벽하지는 않습니다. 건배! *-이것에 대해 틀 렸습니다. 파일 시스템에 따라 다릅니다.
Tai Viinikka

1
데비안 권장 백업 유틸리티 를보고 Pi에 포트가 있는지 확인할 수 있습니다. rsnapshot프로모션 소리
Piotr Kula

1
@TaiViinikka 완벽한 사본이 필요하지 않습니다. 원본 기본 이미지에 (빠르고 쉽게) 다시 넣을 수 있는 부분 복사본이 필요합니다 . rsync가는 길입니다. 내일 시간이 있으면 답을 추가하겠습니다. rsnapshot조사 할 가치도 있습니다.
goldilocks

3
위의 ppumkins 답변을 기반으로 'dd'스크립트를 원래 스레드의 최신 주석과 동기화하고 약간의 개선 사항을 직접 추가했습니다. 최종 결과는 < github.com/aweijnitz/pi_backup >에서 확인할 수 있습니다 . 언제든지 개선 사항을 추가하고 풀 요청을 보내 주시기 바랍니다.
AndersW

14

나는 파이의 백업을 위해 rsync에서 @goldilocks 응답을 채택했습니다. ext4Pi에 마운트 된 HDD 의 파티션으로 백업합니다 . HDD가 마운트되지 않은 경우 rsync는 마운트 디렉토리에 복사합니다 (SD 카드가 가득 찰 때까지). HDD가 rw모드로 마운트되지 않은 경우 심각한 오류 메시지가 생성됩니다. 이 중 어느 것도 바람직하지 않으므로 rw진행하기 전에 파티션이 모드 로 마운트되어 있는지 확인합니다 .

참고 2015-03-03 하드 링크를 정확하게 복사하기 위해 답변을 수정했습니다. 원본은 효과가 있었지만 많은 하드 링크를 파일로 변환했습니다. 공간을 낭비하는 것 외에도, 이는 하드 링크가 있다고 가정하는 많은 용도를 손상시킵니다. (현재 이미지에는 869 개의 ​​링크가 있으며 많은 것은 라즈 비아 자체에 있습니다.)

이 작업을 수행하는 스크립트는 다음과 같습니다. (내 파티션이 PiData에 장착/mnt/PiData

#!/bin/bash
# script to synchronise Pi files to backup
BACKUP_MOUNTED=$(mount | awk '/PiData/ {print $6}' | grep "rw")
if [ $BACKUP_MOUNTED ]; then
    echo $BACKUP_MOUNTED
    echo "Commencing Backup"
    rsync -avH --delete-during --delete-excluded --exclude-from=/usr/bin/rsync-exclude.txt / /mnt/PiData/PiBackup/
else
    echo "Backup drive not available or not writable"
fi

다음을 사용하여 복원하거나 다른 Pi를 업데이트하십시오.

sudo rsync -avH /mnt/PiData/PiBackup/ /

rsync-exclude.txt불필요한 파일을 제거하기 위해 기능을 향상 시켰습니다 .

첫 번째 그룹은 @goldilocks https://raspberrypi.stackexchange.com/users/5538/에 의해 문서화 된 디렉토리입니다.

두 번째 그룹은 AFP (Apple Filing Protocol)를 사용하여 Pi에 액세스 할 때 OS X에서 생성 한 파일 및 디렉토리입니다. (이것은 일반적으로 OS X에서는 보이지 않지만 Raspbian에서는 보이지 않습니다. 어떤 경우에도 백업 할 필요가 없습니다.) AFP를 전혀 사용하지 않더라도 해를 끼치 지 않습니다.

세 번째 그룹은 백업 할 필요가없는 파일이며 다른 Pi에 복사 할 필요는 없습니다. fake-hwclock.data, RPi-Monitor 보고서의 예 아마 다른 사람들이있을 것입니다.

/proc/*
/sys/*
/dev/*
/boot/*
/tmp/*
/run/*
/mnt/*

.Trashes
._.Trashes
.fseventsd
.Spotlight-V100
.DS_Store
.AppleDesktop
.AppleDB
Network Trash Folder
Temporary Items

.bash_history
/etc/fake-hwclock.data
/var/lib/rpimonitor/stat/

1
출력을 .img 파일 로 만드는 방법이 있습니까?
IgorGanapolsky

@IgorGanapolsky 글쎄, 모든 필수 파일이 (부팅 파일 제외) 있다는 것을 알면 분명히 가능하지만 이미지를 원한다면 이미지를 만듭니다. 의견이 아닌 새 게시물에 새로운 질문을해야합니다.
Milliways 2012 년

@Milliways 왜 "sudo rsync ..."를 사용해야하지 않습니까? 동기화 할 수없는 파일이 있습니까?
Smilia

6

로컬 네트워크에서 3 개의 Pis가 실행 중이며 크론을 사용하여 정기적으로 백업해야합니다. 그래서 dd, tar 및 rsync 백업을 생성하고 복원 할 수있는 스크립트를 작성했습니다. 나는 백업에 rsync를 사용하는 것을 선호하지만 다른 사람들은 dd 또는 tar를 선호합니다. 이미 많은 사람들이 사용하고 있습니다. 그것이 다른 사람들에게도 유용하기를 바랍니다 :-) raspibackup-Raspberry는 자체 백업을 만듭니다.


1
죄송합니다. HTTP를 통해 다운로드 한 스크립트를 루트 (root!)로 실행하도록 요청하는 것은 무책임합니다. 이 스크립트를 안전한 채널을 통해 배포하십시오.
Clément

1
나는 그것이 주제에서 벗어난 것으로 생각하지 않으며 뿌리가 중요하지 않습니다. 요점은 소프트웨어가 보안 채널을 통해 배포되어야하며 귀하의 대답은 잘못된 보안 관행을 장려한다는 것입니다.
Clément

1
그것은 큰 발전이 될 것입니다. 예 :)
Clément

2
HTTPS를 통한 전달이이 인스턴스에서 보안을 추가하지는 않습니다. 여전히 인터넷에서 스크립트를 다운로드하여 실행하고 있습니다. 안전한 프로세스는 스크립트를 다운로드하고 (http / https는 관련이 없음) 편집기에서 스크립트를 열고 위에서 아래로 읽고 이상한 점과 불안정한 부분이 있는지 확인하는 것입니다. 만족할 때만 실행하십시오. Framp는 (! BTW, 즉 고발 Framp 아닌) 우리 모두 어떤 알고 HTTPS를 통해 전달 만 그 경우 :)에 미소를 만들 것에 대한 해커 수 있습니다
줄리안 나이트

2
동의합니다. 그렇기 때문에 스크립트를 설치하는 방법에는 두 가지 방법이 설명되어 있습니다. 1. installerScript를 사용하십시오. 2. 수동으로 다운로드하고 코드를 확인한 다음 수동으로 설치하십시오
framp

3

이러한 목적을위한 안정적인 도구는 다음과 같습니다. https://github.com/aktos-io/aktos-dcs-tools

이 도구에 기록됩니다 make ssh연결 make backup-root, make mount-root원격 처음에는 마음에 장소, 다음 로컬 세션이 추가됩니다에서. 따라서 로컬 백업, 직접 원격 백업, 프록시 원격 백업을 지원합니다. 백업은 증분 방식으로 수행되며 (diff 만 전송 됨) 백업 디렉토리는 독립형입니다 (복원 할 디렉토리 / 버전을 선택하면 모든 디렉토리에 전체 백업이 있음). 물론 버전이 있습니다 (backup.last-0이 최신 버전 임). 언제든지 백업 프로세스를 중단하고 나중에 계속할 수 있습니다.

특정 문제에 대한 지침은 다음과 같습니다.

 ssh to-your-raspberry
 cd /mnt/usb0/my-rpi-backups
 git clone https://github.com/ceremcem/aktos-dcs-tools backup-tools
 ln -s backup-tools/Makefile .

 ./backup-tools/configure # you do not need to make any settings for local sessions, just save the default 

 # just for the first time
 make set-local-session  # a flag file is created
 make init               # snapshots directory is created

 # anytime you want to back up
 make backup-root        # backup with rsync

편집하다

이제 새로운 대상이 추가되었습니다. 하나의 명령으로 백업에서 실제 SD 카드를 만들 수 있습니다.

make create-disk-from-last-backup

지침에 따라 SD 카드를 생성하고 새로 생성 된 SD 카드로 RaspberryPi를 부팅하십시오.


1

완전히 다른 접근법이 있습니다. 당신은 사용할 수 있습니다 LVM ( L ogical V의 olume의 M의 일관된 백업을 위해 anager을). 스토리지를 쉽게 추가, 확장 및 축소하거나 운영 체제를 스냅 샷에서 이전 상태로 복원하는 등의 다른 개선 사항 외에도 백업을 수행 할 수도 있습니다. 백업 중에 동적으로 변경된 파일에 대해 걱정할 필요가 없으며 파일 시스템을 읽기 전용으로 설정하고 특정 디렉토리 또는 다른 것을 제외하십시오. LVM 을 사용 하면 간단히 스냅 샷을 생성하고이 스냅 샷을 마운트하고 원하는 방법으로 백업 할 수 있습니다. 을 사용하여 복사하거나을 (를 cp -a) 사용하여 미러를 rsync만들거나을 (를) tar사용하여 이미지를 만들거나 이미지를 만들 수 있습니다.dd. /mnt/usbhd/pi_backup/예를 들어 백업 장치를 마운트했다고 가정하면 다음과 같습니다.

rpi ~$ sudo lvcreate --snapshot --name rpi_snap --size 1G rpi_vg/root_lv
rpi ~$ sudo mkdir /mnt/snapshot
rpi ~$ sudo mount /dev/mapper/rpi_vg-rpi_snap /mnt/snapshot

# make backups
rpi ~$ sudo cp -a /mnt/snapshot/ /mnt/usbhd/pi_backup/
rpi ~$ sudo rsync -aH --delete /mnt/snapshot/ /mnt/usbhd/pi_backup/
rpi ~$ sudo tar -czf /mnt/usbhd/pi_backup/backup.tar.gz -V "Backup of my Raspberry Pi" -C /mnt/snapshot/ ./
rpi ~$ sudo dd if=/mnt/snapshot/ of=/mnt/usbhd/pi_backup/backup.img bs=4M

rpi ~$ sudo umount /mnt/snapshot/
rpi ~$ sudo lvremove rpi_vg/rpi_snap

LVM 을 설정하는 데 약간의 시간이 걸립니다 . 이를 수행하는 방법 LVM을 사용하여 실행중인 시스템의 간편한 백업 및 스냅 샷을 볼 수 있습니다 .


0

설치 가능한 이미지를 만드는 백업 도구 를 찾았습니다 .

이미지를 마운트하고 축소하는 유틸리티도 있습니다.

이것은 다른 사람들에게 유용 할 수 있습니다

함께 제공되는 설명서는 매우 간단하므로 다음 사항에 유의하십시오.

  1. 유틸리티를 임의의 디렉토리에 추출하고 스크립트를 실행 가능하게하십시오.
  2. ext4Pi in /mnt또는 에 포맷 된 파티션을 마운트 하십시오 /media(큰 파일을 허용하고 exFAT 또는 네트워크 드라이브와 같은 Pi가 지원하는 모든 포맷 사용 가능).
  3. 처음 실행하는 경우 백업 이미지 이름을 입력하라는 메시지가 표시됩니다 (예 : /mnt/Image/BusterBackup.img
  4. Image ROOT 파일 시스템 크기 (MB)를 묻는 메시지가 표시됩니다. 가능한 최소값은 0이거나 전체 백업의 경우 비어있을 수 있습니다.
  5. 이후 실행시 증분 업데이트 할 백업 이미지의 경로를 입력하십시오.
An example of the commands I used:-
# Mount USB
sudo mount /dev/sda1 /mnt/Image/
# Update backup
sudo image-utils/image-backup /mnt/Image/BusterBackup.img
# Mount backup
sudo image-utils/image-mount /mnt/Image/BusterBackup.img  MountedImages
When done, run:
sudo umount MountedImages; sudo losetup -d /dev/loop0
# Compress backup
sudo sh -c "gzip -9c /mnt/Image/BusterBackup.img  > Images/BusterBackup.img.gz"

마운트 오프셋을 복사하기 위해 원본을 약간 수정하여 파티션 오프셋과 크기를 올바르게 계산하고 몇 가지 주석을 추가했습니다.

#!/bin/bash
# Original https://raspberrypi.org/forums/viewtopic.php?p=1528736
# 2019-09-26    Modified to set size of boot sector

trap '{ stty sane; echo ""; errexit "Aborted"; }' SIGINT SIGTERM

ADDBLK=0

# Set BOOT_SIZE_MB to the Desired boot sector size (in MB) - should be multiple of 4MB
BOOT_SIZE_MB=256
BOOTSIZEM=$BOOT_SIZE_MB'M'

BOOTBEG=8192
BOOT_SIZE="$((BOOT_SIZE_MB * 1024 * 1024))"
ROUND_SIZE="$((4 * 1024 * 1024))"
# Ensure root sector starts on an Erase Block Boundary (4MB)
ROOTBEG=$(((BOOT_SIZE + ROUND_SIZE -1) / ROUND_SIZE * ROUND_SIZE / 512 + BOOTBEG))

MNTPATH="/tmp/img-backup-mnt"

ONEMB=$((1024 * 1024))

# create BOOT loop device
mkloop1()
{
  local INFO1=""
  local SIZE1=0
  local START1=0

  sync
  INFO1="$(sfdisk -d "${IMGFILE}")"
  START1=$(grep type=c <<< "${INFO1}" | sed -n 's|^.*start=\s\+\([0-9]\+\).*$|\1|p')
  SIZE1=$(grep type=c <<< "${INFO1}" | sed -n 's|^.*size=\s\+\([0-9]\+\).*$|\1|p')
  LOOP1="$(losetup -f --show -o $((${START1} * 512)) --sizelimit $((${SIZE1} * 512)) "${IMGFILE}")"
  if [ $? -ne 0 ]; then
    errexit "Unable to create BOOT loop device"
  fi
}

rmloop1()
{
  if [ "${LOOP1}" != "" ]; then
    sync
    losetup -d "${LOOP1}"
    LOOP1=""
 fi
}

# create ROOT loop device
mkloop2()
{
  local INFO2=""
  local SIZE2=0
  local START2=0

  sync
  INFO2="$(sfdisk -d "${IMGFILE}")"
  START2=$(grep type=83 <<< "${INFO2}" | sed -n 's|^.*start=\s\+\([0-9]\+\).*$|\1|p')
  SIZE2=$(grep type=83 <<< "${INFO2}" | sed -n 's|^.*size=\s\+\([0-9]\+\).*$|\1|p')
  LOOP2="$(losetup -f --show -o $((${START2} * 512)) --sizelimit $((${SIZE2} * 512)) "${IMGFILE}")"
  if [ $? -ne 0 ]; then
    errexit "Unable to create ROOT loop device"
  fi
}

rmloop2()
{
  if [ "${LOOP2}" != "" ]; then
    sync
    losetup -d "${LOOP2}"
    LOOP2=""
  fi
}

# Mount Image partitions
mntimg()
{
  MNTED=TRUE
  if [ ! -d "${MNTPATH}/" ]; then
    mkdir "${MNTPATH}/"
    if [ $? -ne 0 ]; then
      errexit "Unable to make ROOT partition mount point"
    fi
  fi
  mkloop2
  mount "${LOOP2}" "${MNTPATH}/"
  if [ $? -ne 0 ]; then
    errexit "Unable to mount image ROOT partition"
  fi
  if [ ! -d "${MNTPATH}/boot/" ]; then
    mkdir -p "${MNTPATH}/boot/"
    if [ $? -ne 0 ]; then
      errexit "Unable to make BOOT partition mount point"
    fi
  fi
  mkloop1
  mount "${LOOP1}" "${MNTPATH}/boot/"
  if [ $? -ne 0 ]; then
    errexit "Unable to mount image BOOT partition"
  fi
}

umntimg()
{
  umount "${MNTPATH}/boot/"
  if [ $? -ne 0 ]; then
    errexit "Unable to unmount image BOOT partition"
  fi
  rmloop1
  umount "${MNTPATH}/"
  if [ $? -ne 0 ]; then
    errexit "Unable to unmount image ROOT partition"
  fi
  rmloop2
  rm -r "${MNTPATH}/"
  MNTED=FALSE
}

errexit()
{
  echo ""
  echo "$1"
  echo ""
  if [ "${MNTED}" = "TRUE" ]; then
    umount "${MNTPATH}/boot/" &> /dev/null
    umount "${MNTPATH}/" &> /dev/null
    rm -rf "${MNTPATH}/" &> /dev/null
  fi
  rmloop1
  rmloop2
  exit 1
}

LOOP1=""
LOOP2=""
MNTED=FALSE

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

if [ $(id -u) -ne 0 ]; then
  errexit "$0 must be run as root user"
fi

PGMNAME="$(basename $0)"
for PID in $(pidof -x -o %PPID "${PGMNAME}"); do
  if [ ${PID} -ne $$ ]; then
    errexit "${PGMNAME} is already running"
  fi
done

rsync --version &> /dev/null
if [ $? -ne 0 ]; then
  errexit "rsync not installed (run: apt-get install rsync)"
fi

if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
  SYSTEMD=1
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
  SYSTEMD=0
else
  errexit "Unrecognized init system"
fi

if [ ${SYSTEMD} -eq 1 ]; then
  ROOT_PART="$(mount | sed -n 's|^/dev/\(.*\) on / .*|\1|p')"
else
  if [ ! -h /dev/root ]; then
    errexit "/dev/root does not exist or is not a symlink"
  fi
  ROOT_PART="$(readlink /dev/root)"
fi

ROOT_TYPE=$(blkid "/dev/${ROOT_PART}" | sed -n 's|^.*TYPE="\(\S\+\)".*|\1|p')

ROOT_DEV="${ROOT_PART:0:(${#ROOT_PART} - 1)}"
if [ "${ROOT_DEV}" = "mmcblk0p" ]; then
  ROOT_DEV="${ROOT_DEV:0:(${#ROOT_DEV} - 1)}"
fi

PTUUID="$(blkid "/dev/${ROOT_DEV}" | sed -n 's|^.*PTUUID="\(\S\+\)".*|\1|p')"

DEVSIZE=$(blockdev --getsize64 "/dev/${ROOT_PART}")
BLKSIZE=$(blockdev --getbsz "/dev/${ROOT_PART}")
BLKCNT=$((${DEVSIZE} / ${BLKSIZE}))
INFO="$(df | grep /dev/root)"
DFKSIZE=$(awk '{print $2}' <<< "${INFO}")
DFKFREE=$(awk '{print $4}' <<< "${INFO}")
ROOTSIZE=$((${BLKCNT} * ${BLKSIZE}))
ROOTUSED=$(((${DFKSIZE} - ${DFKFREE}) * 1024))
IRFSMIN=$(((${ROOTUSED} + (${ADDBLK} * ${BLKSIZE}) + (${ONEMB} - 1)) / ${ONEMB}))
IRFSMAX=$(((${ROOTSIZE} + (${ONEMB} - 1)) / ${ONEMB}))

IMGFILE="$1"
if [ "${IMGFILE}" = "" ]; then
# Create Image file
  while :
  do
    echo ""
    read -r -e -i "${IMGFILE}" -p "Image file to create? " IMGFILE
    if [ "${IMGFILE}" = "" ]; then
      continue
    elif [[ ! "${IMGFILE}" =~ ^/mnt/.*$ && ! "${IMGFILE}" =~ ^/media/.*$ ]]; then
      echo ""
      echo "${IMGFILE} does not begin with /mnt/ or /media/"
      continue
    fi
    if [ -d "${IMGFILE}" ]; then
      echo ""
      echo "${IMGFILE} is a directory"
    elif [ -f "${IMGFILE}" ]; then
      echo ""
      echo -n "${IMGFILE} already exists, Ok to delete (y/n)? "
      while read -r -n 1 -s answer; do
        if [[ "${answer}" = [yYnN] ]]; then
          echo "${answer}"
          if [[ "${answer}" = [yY] ]]; then
            break 2
          else
            break 1
          fi
        fi
      done
    else
      break
    fi
  done
  IRFSSIZE=""
  while :
  do
    echo ""
    read -r -e -i "${IRFSSIZE}" -p "Image ROOT filesystem size (MB) [${IRFSMAX}]? " IRFSSIZE
    if [ "${IRFSSIZE}" = "" ]; then
      IRFSSIZE=${IRFSMAX}
      break
    elif [ ${IRFSSIZE} -ge ${IRFSMIN} ]; then
      break
    else
      echo ""
      echo "Requested image ROOT filesystem size (${IRFSSIZE}) is too small (Minimum = ${IRFSMIN})"
      IRFSSIZE=${IRFSMIN}
    fi
  done
  echo ""
  echo -n "Create ${IMGFILE} [${IRFSSIZE} MB] (y/n)? "
  while read -r -n 1 -s answer; do
    if [[ "${answer}" = [yYnN] ]]; then
      echo "${answer}"
      if [[ "${answer}" = [yY] ]]; then
        break
      else
        errexit "Aborted"
      fi
    fi
  done
  if [ -f "${IMGFILE}" ]; then
    rm "${IMGFILE}"
    if [ $? -ne 0 ]; then
      errexit "Unable to delete existing image file"
    fi
  fi
  ROOTEND=$((${ROOTBEG} + ((${IRFSSIZE} * ${ONEMB}) / 512) - 1))
  truncate -s $(((${ROOTEND} + 1) * 512)) "${IMGFILE}"
  if [ $? -ne 0 ]; then
    errexit "Unable to create image file"
  fi
# create image/partitions
  sync
  fdisk "${IMGFILE}" <<EOF > /dev/null
p
n
p
1
${BOOTBEG}
+${BOOTSIZEM}
t
c
p
n
p
2
${ROOTBEG}
${ROOTEND}
p
w
EOF

  mkloop1
  mkloop2
  mkfs.vfat "${LOOP1}" > /dev/null
  if [ $? -ne 0 ]; then
    errexit "Unable to create image BOOT filesystem"
  fi
  dosfsck "${LOOP1}" > /dev/null
  if [ $? -ne 0 ]; then
    errexit "Image BOOT filesystem appears corrupted"
  fi
  if [ "${ROOT_TYPE}" = "f2fs" ]; then
    mkfs.f2fs "${LOOP2}" > /dev/null
  else
    mkfs.ext4 -q -b ${BLKSIZE} "${LOOP2}" > /dev/null
  fi
  if [ $? -ne 0 ]; then
    errexit "Unable to create image ROOT filesystem"
  fi
  rmloop2
  rmloop1
# Initialise image PARTUUID
  fdisk "${IMGFILE}" <<EOF > /dev/null
p
x
i
0x${PTUUID}
r
p
w
EOF
# Create empty directories in image root partition
  mntimg
  mkdir "${MNTPATH}/dev/" "${MNTPATH}/media/" "${MNTPATH}/mnt/" "${MNTPATH}/proc/" "${MNTPATH}/run/" "${MNTPATH}/sys/" "${MNTPATH}/tmp/"
  if [ $? -ne 0 ]; then
    errexit "Unable to create image directories"
  fi
  chmod a+rwxt "${MNTPATH}/tmp/"
  umntimg
  echo ""
  echo "Starting full backup (for incremental backups, run: $0 ${IMGFILE})"
# END of create image/partitions
else

# Check existing Image
  if [[ ! "${IMGFILE}" =~ ^/mnt/.*$ && ! "${IMGFILE}" =~ ^/media/.*$ ]]; then
    errexit "${IMGFILE} does not begin with /mnt/ or /media/"
  fi
  if [ -d "${IMGFILE}" ]; then
    errexit "${IMGFILE} is a directory"
  elif [ ! -f "${IMGFILE}" ]; then
    errexit "${IMGFILE} not found"
  fi
  echo "Starting incremental backup to ${IMGFILE}"
fi

# rsync root partition
mntimg
sync
rsync -aDH --partial --numeric-ids --delete --force --exclude "${MNTPATH}" --exclude '/dev' --exclude '/media' --exclude '/mnt/*/*' --exclude '/proc' --exclude '/run' --exclude '/sys' \
--exclude '/tmp' --exclude 'lost\+found' --exclude '/etc/udev/rules.d/70-persistent-net.rules' --exclude '/var/lib/asterisk/astdb.sqlite3-journal' / "${MNTPATH}/"
if [[ $? -ne 0 && $? -ne 24 ]]; then
  errexit "Unable to create backup"
fi
sync
umntimg

-1

터미널을 열고 'lsblk -f'를 입력하십시오.
연결된 모든 저장 장치가 표시됩니다.
그런 다음 'dd if = / dev / [sd 카드의 이름] bs = 1M'을 입력하십시오.
백그라운드에서 실행하고 싶을 때까지 시간이 걸립니다.
이것은 Linux에서 sd 카드를 백업하는 것과 동일한 방법입니다.


그것은 불필요하고 바람직하지 않은 파일까지 모두 백업합니다.
IgorGanapolsky

3
이것은 실행중인 시스템에서 백업 중에 변경된 것들 때문에 일관성없는 백업을 만듭니다!
Ingo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.