Raspberry Pi có thể được sử dụng để tạo bản sao lưu của chính nó không?


78

Câu hỏi này trả lời câu hỏi về cách tôi sử dụng máy tính bên ngoài để tạo bản sao lưu RPi của mình.

Tôi tự hỏi liệu tôi có thể tạo hình ảnh sao lưu của thẻ SD hiện đang sử dụng hay không và sao chép nó vào một tệp trên thiết bị lưu trữ USB. Điều này có thể không? Nếu không, có cách nào để tạo bản sao lưu RPi mà không liên quan đến máy tính khác không?


2
Chắc chắn, nhưng bỏ qua / tmp, / run, / Proc, / sys, / dev và / mnt. Bạn không cần tạo hình ảnh, bạn cần bản sao lưu bạn có thể tạo hoặc cập nhật hình ảnh từ đó. Vì vậy, không sử dụng dd, nhìn vào rsync.
goldilocks

1
@goldilocks Tôi sẽ thích nó nếu bạn đưa ra nhận xét này thành một câu trả lời đầy đủ hơn, giải thích quá trình sao lưu và khôi phục bạn có trong tâm trí.
Eric Wilson

Xong - xin lỗi, tôi mất vài ngày để tìm thời gian.
goldilocks

1
Nếu khối lượng đích của bạn đủ lớn, việc hiển thị lại hệ thống tệp chỉ đọc và thực hiện một ddbản sao với kích thước khối phù hợp có thể sẽ nhanh nhất cho bản sao "mới". Thực hiện sao chép từng tập tin vào phương tiện flash / SD có lẽ là một ý tưởng tồi.
Chris Stratton

Câu trả lời:


86

Đây là phần giới thiệu để sử dụng rsyncđể sao lưu trên Pi. Khi sao lưu ban đầu được tạo, việc cập nhật nó theo cách này nhanh hơn nhiều so với việc liên tục trích xuất toàn bộ hình ảnh. Bạn có thể làm điều này với một ổ cứng cục bộ hoặc qua mạng.

Bạn thực sự không muốn một bản sao hoàn chỉnh của một hệ thống đang chạy để sao lưu, vì một số nội dung có vẻ bề ngoài trong hệ thống tệp chỉ tồn tại trong thời gian chạy. Bao gồm điều đó trong một bản sao lưu và sau đó sử dụng nó để tạo lại một hình ảnh sau này có thể tạo ra vấn đề cho bạn.

Có một số trường hợp ngoại lệ khác quá. rsynccó thể chấp nhận một danh sách các mẫu (toàn cầu ) để loại trừ và những mẫu này có thể được đọc từ một tệp, vì vậy trước tiên chúng ta hãy tìm hiểu những gì nên có trong một tệp như vậy. Lưu ý rằng các mục có dạng /directory/*và không /directory. Điều này là do chúng tôi muốn chúng tồn tại, nhưng chúng tôi không muốn sao chép bất cứ thứ gì trong đó.

/proc/*
/sys/*

Chúng không thực sự tồn tại trên đĩa. Chúng là một giao diện cho kernel, tạo và duy trì chúng trong bộ nhớ . Nếu bạn sao chép chúng và sau đó sao chép chúng trở lại vào một hệ thống và khởi động nó, thì nó sẽ (vô nghĩa), vì kernel sử dụng chúng làm điểm gắn kết cho các giao diện [Nếu bạn muốn xem điều gì xảy ra khi bạn gắn kết phân vùng hệ thống tập tin trên một thư mục có dữ liệu trong đó, hãy thử. Nó hoạt động và sẽ không gây hại gì, nhưng những thứ trong thư mục hiện không thể truy cập được.]

Lưu ý rằng điều quan trọng là các điểm /sys/procđiểm gắn kết tồn tại. Nhưng chúng không nên chứa bất cứ thứ gì. Kế tiếp:

/dev/*

Các devthư mục không hoàn toàn giống như procsyscho mục đích của chúng tôi. Nếu bạn tin rằng bạn nên lưu cái này để bạn có thể có cùng các nút thiết bị trong bản sao lưu của mình hoặc thứ gì đó, thì bạn đã nhầm . Đừng bận tâm. Đừng sao chép dev. Ngày xưa Linux đã hoạt động theo cách đó, nhưng nó không còn nữa.

/boot/*

Đây là một trường hợp đặc biệt với hầu hết (có lẽ là tất cả) các bản phân phối cụ thể của Pi như Raspbian. Đây thực sự là một điểm gắn kết cho phân vùng đầu tiên, vfat. Chúng tôi sẽ giải quyết vấn đề đó một cách riêng biệt. Dù bạn làm gì, đừng bận tâm bao gồm nó ở đây, bởi vì một lần nữa, đó là một điểm gắn kết.

/tmp/*
/run/*

/runnói chung cũng không có trên đĩa, nó nằm trong bộ nhớ. Có lẽ /tmpcũng có thể (điều này sẽ tiết kiệm một chút hành động của thẻ SD), nhưng trong mọi trường hợp, như tên gọi, đây không phải là nơi lưu trữ dữ liệu liên tục. Các ứng dụng sử dụng chúng hy vọng rằng chúng có thể bị xóa tại mỗi lần khởi động.

/mnt/*
/media/*

Đây là những điều đặc biệt quan trọng nếu bạn dự định sao lưu vào ổ cứng hoặc thẻ nhớ USB và thiết bị đang ở trong /mnthoặc /media(tự động hóa có xu hướng sử dụng thiết bị sau), bởi vì nếu bạn không loại trừ vị trí của các thiết bị đó trong hệ thống tệp, bạn sẽ tạo một vòng lặp sao lưu nội dung của ổ đĩa cho đến khi hết dung lượng. Tôi nghĩ rsync thể đủ thông minh để phát hiện ra thứ gì đó ngớ ngẩn nhưng cố gắng tránh thử nghiệm tiền đề.

Bật để sao lưu thực tế: Tạo một thư mục để sao lưu trên ổ cứng được gắn cục bộ, điều USB, v.v. - ví dụ: "pi_backup". Bạn có thể luân phiên sao lưu vào một vị trí từ xa thông qua ssh(xem bên dưới) hoặc sử dụng hệ thống tập tin gắn trên mạng, nhưng điều này có thể sẽ mất một lúc lần đầu tiên.

Nếu tệp chứa danh sách cần loại trừ là /rsync-exclude.txt1 và ổ đĩa của bạn là /mnt/usbhd, để thực hiện sao lưu thực tế:

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

Lưu ý rằng có một dấu gạch chéo trênpi_backup/ .

Điều này sẽ mất một thời gian và tạo ra rất nhiều đầu ra (nếu bạn muốn kiểm tra điều đó trong một bản ghi thay thế, hãy chắp thêm > rsync.log). --deletelà vô nghĩa lần đầu tiên, nhưng để giữ cho bản sao lưu được cập nhật, hãy sử dụng nó. Điều này đảm bảo rằng những thứ bạn đã xóa sau đó trên Pi cũng sẽ bị xóa khỏi bản sao lưu của bạn. Các atập hợp đệ quy vào các thư mục và đảm bảo tất cả các thuộc tính tệp khớp. -Hlà để bảo vệ các liên kết cứng 2 , vdành cho verbose, đó là lý do tại sao bạn nhận được một số đầu ra (nếu không rsyncthì yên tĩnh). Xem man rsyncđể biết thêm.

Có một phím tắt theo đó bạn có thể bỏ qua các --exclude-fromtập tin. Nếu bạn chắc chắn rằng tất cả những thứ bạn không muốn sao chép ( /tmpv.v.) nằm trên các hệ thống tệp riêng biệt, bạn chỉ có thể sử dụng:

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

-xđã được chèn Đây là hình thức ngắn --one-file-system, nói rsynckhông vượt qua ranh giới hệ thống tập tin. Cá nhân tôi thích --exclude-from, nhưng ví dụ, Raspbian mặc định, --one-file-systemsẽ hoạt động tốt. Bạn có thể sử dụng cả hai nếu bạn muốn -xcẩn thận: D

Đó không phải là một bản sao lưu hoàn chỉnh. Thế là đủ nếu bạn không đặt bất cứ thứ gì vào bootvà bạn vẫn ổn với việc sử dụng sao lưu để chỉ cần khôi phục hệ thống bằng cách dán thẻ vào máy tính và chạy:

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

Bạn cũng có thể làm điều này với một thẻ có hình ảnh mới trên đó (giả sử nó giống với hình ảnh cơ sở của bạn) mặc dù điều đó không hiệu quả nếu bạn phải tạo hình ảnh (vì khi đó bạn sẽ ghi đè lên hầu hết hình ảnh đó). Bạn cũng có thể kết nối một thẻ SD khác thông qua bộ chuyển đổi USB với hình ảnh như vậy trên đó và sử dụng phương pháp trên để duy trì thẻ trùng lặp.

Nếu bạn đã đặt nội dung vào /boot(ví dụ: kernel tùy chỉnh), bao gồm /boot/config.txt, bạn cũng sẽ muốn sao lưu nó (khá đơn giản - không có gì nhiều). Chỉ cần làm riêng, và khi bạn khôi phục, công cụ đó sẽ nằm trong phân vùng đầu tiên.

Xem ở đây nếu bạn muốn tạo một hình ảnh phong cách Raspbian trống mà sau đó bạn có thể sao lưu vào. Bạn có thể sử dụng một phương pháp tương tự để tạo thẻ kiểu Raspbian trống - thay vì xử lý .imgtệp, bạn sẽ xử lý một thiết bị thực (ví dụ /dev/sdb), nghĩa là tất cả những gì bạn phải làm là tạo bảng phân vùng fdiskvà sau đó định dạng /dev/sdb1sdb2(hoặc bất cứ điều gì) với mkfs.

Nhưng sao chép toàn bộ hình ảnh thì dễ dàng hơn! Tại sao phải bận tâm với điều này?

Nó không khó lắm đâu; Tôi đã khôi phục vào một thẻ trống (được định dạng theo liên kết cuối cùng đó) trong 10 phút. Có, chỉ sử dụng ddtrên toàn bộ mọi thứ đơn giản hơn (nếu bạn tìm thấy những thứ như từ khó hiểu ...), NHƯNG sau đó bạn phải mất khá nhiều thời gian mỗi lần bạn muốn cập nhật bản sao lưu của mình vì bạn phải thực hiện 100% mỗi lần. Sử dụng rsync, một khi sao lưu tồn tại, cập nhật nó nhanh hơn nhiều, vì vậy bạn có thể thiết lập điều này xảy ra hàng ngày không đau đớn thông qua cron. Qua một mạng thậm chí. Cứ sáu giờ một lần. Bạn càng làm thường xuyên, nó sẽ mất ít thời gian hơn.

rsync thông qua ssh

Đây là một ví dụ:

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

"Tùy chọn" sẽ là, ví dụ, -av --delete --exclude-from=/rsync-exclude.txtvà "tùy chọn ssh" là bất cứ điều gì bạn thường sử dụng (nếu có). Bạn phải có quyền truy cập root qua sshđể làm điều này cho các mục đích của một bản sao lưu hệ thống (thiết lập PermitRootLogin=yestrong /etc/ssh/sshd_configvà khởi động lại máy chủ).


1 Bạn nên giữ tập tin này. Bạn có thể đặt bình luận trong đó trên các dòng bắt đầu bằng #hoặc ;. Điều này có thể bao gồm rsynclệnh thực tế , có thể được sao chép dán sau đó để bạn không phải nhớ nó mỗi lần.

2 Cảm ơn Kris vì đã chỉ ra rsynckhông làm điều này tự động.


Goldilocks. Trông giống như một công dụng tuyệt vời của rysync. Bất kỳ cơ hội để đưa nó vào một kịch bản cho chúng tôi?
toàn trị

Thay vì tự loại trừ tất cả các điểm gắn kết, tại sao không mkdir /tmp/backupable && mount --bind / /tmp/backupablevà rsync đó? Điều đó cũng có lợi thế là sao lưu mọi dữ liệu được lưu trữ ở những nơi bị "che khuất" bởi thứ gì đó được gắn ở đó.
n.st

@ n.st Ý kiến ​​hay (lol)! Tôi đã chỉnh sửa đề xuất thành câu hỏi, mặc dù tôi vẫn nghĩ sử dụng --exclude-fromlà một ý tưởng tốt hơn. Nếu bạn có thời gian, bạn có thể viết nó thành một câu trả lời riêng biệt, bạn có phiếu bầu của tôi và tôi có thể tham khảo điều đó. Câu trả lời này là đủ dài.
goldilocks

1
@IgorGanapolsky Ý định là không tạo ra một hình ảnh (đọc phần "Nhưng sao chép toàn bộ hình ảnh thì dễ dàng hơn! Tại sao phải bận tâm với điều này?" ). Ngoài việc dễ dàng hơn và nhanh hơn để duy trì một khi được tạo, phương pháp này thường linh hoạt hơn. Nếu bạn muốn sử dụng nó sau này để tạo một .imgbạn có thể; cái nàycái này sẽ giúp giải thích cách chúng được cấu trúc và có thể được tạo ra.
goldilocks

1
Xem đoạn bắt đầu, "Đó không hẳn là một bản sao lưu hoàn chỉnh ..." . Về cơ bản, điều tương tự chính xác là ngược lại. Điều này có thể giúp với một số khái niệm mà mọi người thường nhầm lẫn bởi / về.
goldilocks

24

Một kịch bản làm việc từ Cộng đồng Raspberry được thực hiện bởi một thành viên ở đó.

Bạn có thể sử dụng lại và điều chỉnh mã bao giờ bạn thích. Nó được ghi chép tốt và tự giải thích.

#!/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

Xem xét thêm ý kiến ​​vào diễn đàn ban đầu hoặc đăng phiên bản của riêng bạn để giúp trưởng thành nội dung. Hãy cho một chút cho một chút.

* Và cảm ơn bạn đã trả lại AndersW (Bấm vào tập lệnh GIT)


2
Điều gì xảy ra nếu hệ thống tập tin (xóa tập tin, tập tin mới được thêm vào) thay đổi theo thời gian trong khi pi đang sao lưu?
keiki

2
Tôi sao lưu một số đĩa trong khi chúng đang chạy với rsync và tôi thường xuyên có thể nhận được chính xác những gì tôi cần từ các bản sao lưu tệp này. Tuy nhiên, nói chung, một hệ thống tệp unix không thể được sao chép một cách hoàn hảo (với từng bit đúng và chính xác) trong khi hệ thống tệp được gắn (*). Một bản sao được tạo trong khi hệ thống được gắn đôi khi được gọi là "bản sao bẩn". Một số biện pháp có thể được thực hiện để cải thiện chất lượng của một bản sao bẩn (như đoạn script trên, tắt cron và mysql) nhưng nó không thể hoàn hảo. Chúc mừng! * - Tôi sai về điều này, nó phụ thuộc vào hệ thống tập tin.
Tai Viinikka

1
Bạn có thể xem các tiện ích sao lưu được đề xuất của Debian và xem Pi có cổng của chúng không. rsnapshotâm thanh đầy hứa hẹn
Piotr Kula

1
@TaiViinikka Bạn không cần một bản sao hoàn hảo. Bạn cần một bản sao một phần có thể (nhanh chóng và dễ dàng) được áp đặt lại trên hình ảnh cơ sở ban đầu. rsynclà con đường để đi; khi tôi có thời gian vào ngày mai tôi sẽ thêm một câu trả lời. rsnapshotcũng đáng để điều tra.
goldilocks

3
Dựa trên câu trả lời của ppumkins ở trên, tôi đã đồng bộ hóa tập lệnh 'dd' với các nhận xét mới nhất trong chuỗi gốc và tự mình thêm một số cải tiến nhỏ. Kết quả cuối cùng có sẵn tại đây: < github.com/aweijnitz/pi_backup >. Xin đừng ngần ngại để thêm cải tiến và gửi cho tôi yêu cầu kéo.
AndersW

14

Tôi đã điều chỉnh câu trả lời @goldilocks trên rsync để sao lưu trên pi. Tôi sao lưu vào một ext4phân vùng trên ổ cứng gắn trên Pi. Nếu ổ cứng không được gắn, rsync sẽ sao chép vào thư mục gắn kết (cho đến khi Thẻ SD đầy). Nếu ổ cứng không được gắn trong rwchế độ thông báo lỗi nhiều chế độ được tạo ra. Cả hai điều này đều không mong muốn, vì vậy tôi kiểm tra xem phân vùng của mình có được gắn kết trong rwchế độ trước khi tiếp tục không.

LƯU Ý 2015/03/03 Tôi đã sửa đổi câu trả lời của mình để sao chép chính xác các liên kết cứng. Bản gốc đã làm việc, nhưng chuyển đổi nhiều liên kết cứng thành tập tin. Ngoài việc lãng phí không gian, điều này còn làm ảnh hưởng đến nhiều mục đích sử dụng mà giả sử các liên kết cứng được đưa ra. (Hình ảnh hiện tại của tôi có 869 liên kết, nhiều trong chính Raspbian.)

Kịch bản của tôi để làm điều này sau đây. (Phân vùng của tôi là PiData, được gắn trên/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

Khôi phục (hoặc cập nhật Pi khác) bằng cách sau: -

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

Tôi đã tăng cường rsync-exclude.txtđể loại bỏ các tập tin không cần thiết.

Nhóm đầu tiên là các thư mục được tài liệu bởi @goldilocks https://raspberrypi.stackexchange.com/users/5538/

Nhóm thứ hai là các tệp và thư mục được tạo bởi OS X khi tôi truy cập Pi của mình bằng AFP (Apple Filing Protocol). (Những thứ này thường vô hình trên OS X, nhưng không phải trên Raspbian. Trong mọi trường hợp, không cần sao lưu.) Ngay cả khi bạn không bao giờ sử dụng AFP, những thứ này sẽ không gây hại.

Nhóm thứ ba là các tệp không cần sao lưu (và chắc chắn không được sao chép sang Pi khác). Ví dụ các báo cáo fake-hwclock.data, RPi-Monitor. Bạn có thể sẽ có người khác.

/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
Có cách nào để làm cho đầu ra đó thành một tệp .img không?
IgorGanapolsky

@IgorGanapolsky Vâng, vì tất cả các tệp thiết yếu đều ở đó (ngoại trừ các tệp khởi động), rõ ràng là có thể, nhưng nếu bạn muốn một hình ảnh tạo ra một hình ảnh. Bạn nên hỏi bất kỳ câu hỏi mới trong một bài viết mới, không bình luận.
Milliways

@Milliways tại sao chúng ta không nên sử dụng "sudo rsync ..."? Sẽ có một số tệp không thể được đồng bộ hóa?
Smilia

6

Tôi có ba Pis đang chạy trong mạng cục bộ của mình và cần sao lưu chúng trên cơ sở thường xuyên bằng cron khi chúng hoạt động. Đó là lý do tại sao tôi tạo một tập lệnh có thể tạo các bản sao lưu dd, tar và rsync và khôi phục chúng. Tôi thích sử dụng rsync cho các bản sao lưu của mình nhưng những người khác thích dd hoặc tar. Nó được sử dụng bởi rất nhiều người. Hy vọng nó cũng hữu ích cho những người khác :-) raspibackup - Raspberry tạo bản sao lưu của chính nó


1
Không, xin lỗi: yêu cầu người dùng chạy (với quyền root!) Một tập lệnh được tải xuống qua HTTP là vô trách nhiệm. Vui lòng phân phối tập lệnh này qua một kênh an toàn.
Clément

1
Tôi không nghĩ nó lạc đề, và root hay không không quan trọng lắm. Vấn đề là phần mềm nên được phân phối trên một kênh bảo mật và câu trả lời của bạn là khuyến khích các thực tiễn bảo mật xấu.
Clément

1
Đó sẽ là một bước tiến tuyệt vời, vâng :)
Clément

2
Chỉ cần lưu ý rằng việc phân phối qua HTTPS không theo bất kỳ cách nào thêm bất kỳ bảo mật nào trong trường hợp này! Bạn vẫn đang tải xuống và chạy một tập lệnh từ Internet. Quá trình bảo mật là tải xuống tập lệnh (http / https là không liên quan), mở tập lệnh trong trình chỉnh sửa và đọc từ trên xuống dưới, kiểm tra xem có bất kỳ sự bất thường và không an toàn nào không. Chỉ khi bạn hài lòng, bạn nên chạy nó. Framp có thể là một hacker cho tất cả chúng ta biết và giao hàng qua https sẽ chỉ khiến anh ta mỉm cười trong trường hợp đó :) (BTW, đó không phải là lời buộc tội Framp!)
Julian Knight

2
Tôi đồng ý với bạn. Đó là lý do tại sao có hai cách mô tả cách cài đặt tập lệnh: 1. Sử dụng trình cài
đặtScript

3

Đây là công cụ ổn định của chúng tôi cho các mục đích như vậy: https://github.com/aktos-io/aktos-dcs-tools

Công cụ này được ghi vào make sshkết nối, make backup-root, make mount-roottừ nơi xa xôi trong tâm trí lúc đầu, và sau đó phiên địa phương được thêm vào. Vì vậy, nó hỗ trợ sao lưu cục bộ, sao lưu từ xa trực tiếp, sao lưu từ xa proxy. Sao lưu được thực hiện tăng dần (chỉ khác biệt được chuyển) và các thư mục sao lưu là độc lập (chỉ cần chọn một thư mục / phiên bản để khôi phục, bất kỳ thư mục nào cũng có bản sao lưu đầy đủ). Tất nhiên, bạn có phiên bản (backup.last-0 là phiên bản mới nhất). Bạn có thể làm gián đoạn quá trình sao lưu bất cứ lúc nào và tiếp tục sau đó.

Dưới đây là hướng dẫn cho vấn đề cụ thể của bạn:

 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

BIÊN TẬP

Bây giờ có một mục tiêu mới được thêm vào: Bạn có thể tạo Thẻ SD vật lý từ các bản sao lưu của mình bằng một lệnh:

make create-disk-from-last-backup

Làm theo hướng dẫn, tạo Thẻ SD của bạn, khởi động RaspberryPi bằng Thẻ SD mới được tạo này.


1

Đây là một cách tiếp cận hoàn toàn khác nhau. Bạn có thể sử dụng LVM ( L ogical V thể tích nước M anager) để thực hiện sao lưu phù hợp. Bên cạnh các cải tiến khác như dễ dàng thêm, mở rộng và giảm lưu trữ hoặc khôi phục hệ điều hành về trạng thái trước đó từ ảnh chụp nhanh, bạn cũng có thể tạo bản sao lưu. Bạn không phải lo lắng về các tệp thay đổi động trong quá trình sao lưu, chỉ cài đặt hệ thống tệp, loại trừ các thư mục cụ thể hoặc một cái gì đó khác. Với LVM bạn chỉ cần tạo một ảnh chụp nhanh, gắn ảnh chụp nhanh này và sao lưu nó bằng phương pháp bạn thích. Bạn có thể tạo một bản sao với cp -a, tạo một tấm gương với rsync, tạo một kho lưu trữ với tarhoặc tạo một hình ảnh vớidd. Giả sử bạn đã gắn một thiết bị sao lưu vào /mnt/usbhd/pi_backup/bạn có thể làm ví dụ:

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

Chỉ mất một lần nỗ lực để thiết lập LVM . Cách thực hiện mà bạn có thể xem Sao lưu dễ dàng và ảnh chụp nhanh của hệ thống đang chạy với LVM .


0

Tôi đã tìm thấy một công cụ sao lưu làm cho hình ảnh có thể cài đặt.

Nó cũng có các tiện ích để gắn kết và thu nhỏ hình ảnh.

Điều này có thể hữu ích cho những người khác

Tài liệu đi kèm rất ngắn gọn nên tôi lưu ý những điều sau: -

  1. Trích xuất các tiện ích vào bất kỳ thư mục và làm cho các kịch bản thực thi.
  2. Gắn một ext4phân vùng được định dạng trên Pi của bạn trong /mnthoặc /media(bất kỳ định dạng nào cho phép các tệp lớn và được Pi hỗ trợ, ví dụ exFAT hoặc ổ đĩa mạng có thể được sử dụng).
  3. Đối với lần chạy đầu tiên, bạn sẽ được nhắc nhập tên Sao lưu hình ảnh, vd /mnt/Image/BusterBackup.img
  4. Bạn sẽ được nhắc về kích thước hệ thống tệp Image ROOT (tính bằng MB), giá trị này có thể là 0 đối với mức nhỏ nhất có thể hoặc để trống để sao lưu toàn bộ.
  5. Trong các lần chạy tiếp theo, hãy nhập đường dẫn của Ảnh sao lưu để cập nhật dần dần.
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"

Tôi đã sửa đổi một chút bản gốc (để sao chép các điểm gắn kết), để tính toán chính xác độ lệch và kích thước phân vùng và thêm một vài nhận xét.

#!/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

Mở terminal và gõ 'lsblk -f'.
Điều này sẽ hiển thị tất cả các thiết bị lưu trữ được kết nối.
Sau đó nhập 'dd if = / dev / [NAME của thẻ sd của bạn] bs = 1M'.
Điều này sẽ mất một lúc để bạn có thể muốn chạy nó trong nền.
Đây là cùng một cách chính xác mà bạn sao lưu thẻ sd trong Linux.


Điều đó sao lưu MỌI THỨ, thậm chí các tệp không cần thiết và không mong muốn.
IgorGanapolsky

3
Điều này sẽ tạo một bản sao lưu không nhất quán vì trên hệ thống đang chạy, mọi thứ đã thay đổi trong quá trình sao lưu!
Ingo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.