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/*

นี่เป็นกรณีพิเศษที่มี distros เฉพาะของ Pi ส่วนใหญ่ (อาจทั้งหมด) เช่น Raspbian จริงๆแล้วมันเป็นจุดเมานท์สำหรับพาร์ติชันแรก 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 ภายหลังจะถูกลบออกจากการสำรองข้อมูลของคุณ arecursion ชุดลงในไดเรกทอรีและทำให้แน่ใจว่าทุกแอตทริบิวต์ของแฟ้มแข่งขัน -Hคือการรักษาฮาร์ดลิงก์2ไว้vสำหรับ verbose ซึ่งเป็นสาเหตุที่คุณได้รับเอาต์พุตบางส่วน (มิฉะนั้นrsyncจะเงียบ) ดูman rsyncเพิ่มเติม

มีทางลัดที่คุณสามารถข้าม--exclude-fromไฟล์ได้ หากคุณแน่ใจว่าทุกสิ่งที่คุณไม่ต้องการคัดลอก ( /tmpฯลฯ ) อยู่ในระบบไฟล์แยกกันคุณสามารถใช้:

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

-xถูกแทรก นี่เป็นรูปแบบย่อของ--one-file-systemซึ่งบอกว่าจะrsyncไม่ข้ามขอบเขตของระบบไฟล์ โดยส่วนตัวแล้วฉันชอบ--exclude-fromแต่ในตัวอย่างเช่น Raspbian ที่เป็นค่าเริ่มต้น--one-file-systemจะทำงานได้ดี คุณสามารถใช้ทั้งคู่ได้หากต้องการ-xระวัง: D

นั่นไม่ใช่การสำรองข้อมูลที่ค่อนข้างสมบูรณ์ ก็เพียงพอแล้วหากคุณไม่ได้ใส่อะไรลงไปbootและคุณก็สบายใจเมื่อใช้แบ็คอัพเพื่อกู้คืนระบบโดยการใส่การ์ดในคอมพิวเตอร์และทำงาน:

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

คุณสามารถทำได้ด้วยการ์ดที่มีภาพใหม่อยู่บนนั้น (สมมุติว่าเป็นภาพเดียวกับภาพฐานของคุณ) แม้ว่ามันจะไม่มีประสิทธิภาพเล็กน้อยถ้าคุณต้องสร้างภาพ (เพราะคุณจะเขียนทับมันเป็นส่วนใหญ่) คุณยังสามารถเชื่อมต่อการ์ด SD อีกการ์ดผ่านอะแดปเตอร์ USB ที่มีภาพดังกล่าวและใช้วิธีการด้านบนเพื่อรักษาการ์ดที่ซ้ำกัน

หากคุณใส่สิ่งต่าง ๆ/boot(เช่นเคอร์เนลที่กำหนดเอง) รวมถึง/boot/config.txtคุณจะต้องสำรองข้อมูลนั้นด้วย (ค่อนข้างง่าย - มีไม่มาก) แยกกันทำและเมื่อคุณกู้คืนสิ่งนั้นจะอยู่ในพาร์ติชันแรก

ดูที่นี่หากคุณต้องการสร้างภาพสไตล์ Raspbian เปล่าซึ่งคุณสามารถสำรองไว้ คุณสามารถใช้วิธีการที่คล้ายกันเพื่อสร้างการ์ดสไตล์ Raspbian ที่ว่างเปล่า - แทนที่จะจัดการกับ.imgไฟล์คุณจะต้องจัดการกับอุปกรณ์จริง (เช่น/dev/sdb) หมายถึงสิ่งที่คุณต้องทำคือสร้างตารางพาร์ติชันด้วยfdiskแล้ว รูปแบบ/dev/sdb1และsdb2(หรืออะไรก็ตาม) mkfsด้วย

แต่การคัดลอกภาพทั้งหมดนั้นง่ายกว่า! ทำไมต้องกังวลกับเรื่องนี้?

มันไม่ยากเลย ฉันกู้คืนไปยังการ์ดเปล่า (จัดรูปแบบตามลิงค์สุดท้ายนั้น) ใน 10 นาที ใช่เพียงแค่ใช้ddกับทุกสิ่งนั้นง่ายกว่า (หากคุณพบสิ่งต่าง ๆ เช่นคำที่ทำให้สับสน ... ) แต่ก็ใช้เวลาพอสมควรทุกครั้งที่คุณต้องการอัปเดตการสำรองข้อมูลเพราะคุณต้องทำ 100% ทุกครั้ง ใช้rsyncเมื่อมีการสำรองข้อมูลอยู่การอัปเดตจะเร็วกว่ามากดังนั้นคุณสามารถตั้งค่านี้ให้เกิดขึ้นได้ทุกวันผ่าน cron ผ่านเครือข่ายได้ ทุกหกชั่วโมง ยิ่งคุณทำบ่อยเท่าไหร่ก็จะยิ่งใช้เวลาน้อยลงเท่านั้น

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ขอบคุณ Kris ที่ชี้rsyncไม่ได้ทำสิ่งนี้โดยอัตโนมัติ


Goldilocks ดูเหมือนว่าการใช้ rysync อย่างยอดเยี่ยม มีโอกาสที่จะม้วนมันเป็นสคริปต์สำหรับเราหรือไม่?
เผด็จการ

แทนที่จะแยกจุดเมานท์ทั้งหมดด้วยตนเองทำไมไม่ทำเช่นmkdir /tmp/backupable && mount --bind / /tmp/backupableนั้น นอกจากนี้ยังมีข้อดีในการสำรองข้อมูลใด ๆ ที่จัดเก็บในสถานที่ที่มี "เงา" โดยบางสิ่งที่ติดตั้งอยู่ที่นั่น
n.st

@ n.st ความคิดที่ดี (lol)! ฉันได้แก้ไขข้อเสนอแนะในคำถามแม้ว่าฉันยังคิดว่าการใช้--exclude-fromเป็นความคิดที่ดีกว่า หากคุณมีเวลาคุณสามารถเขียนคำตอบนี้เป็นคำตอบแยกต่างหากคุณมีคะแนนของฉันและฉันสามารถอ้างอิงได้ คำตอบนี้ยืดยาวพอ
goldilocks

1
@IgorGanapolsky ความตั้งใจที่จะไม่สร้างภาพ (อ่าน"แต่การคัดลอกภาพทั้งหมดเป็นเรื่องง่าย! รำคาญกับเรื่องนี้ทำไม?"บางส่วน) นอกจากจะง่ายขึ้นและเร็วขึ้นในการรักษาเมื่อสร้างขึ้นโดยทั่วไปแล้ววิธีนี้มีความยืดหยุ่นมากขึ้น หากคุณต้องการใช้ในภายหลังเพื่อสร้าง.imgคุณสามารถ; สิ่งนี้และสิ่งนี้จะช่วยอธิบายว่าพวกมันมีโครงสร้างและสามารถสร้างได้อย่างไร
goldilocks

1
ดูย่อหน้าที่เริ่มต้น"นั่นคือไม่ได้ค่อนข้างสำรองข้อมูลให้สมบูรณ์ ..." โดยพื้นฐานแล้วมันเป็นสิ่งเดียวกันที่ตรงกันข้าม สิ่งนี้อาจช่วยด้วยแนวคิดบางอย่างที่ผู้คนมักสับสนโดย / เกี่ยวกับ
goldilocks

24

สคริปต์ทำงานจากชุมชนราสเบอร์รี่ที่สมาชิกทำไว้ที่นั่น

คุณสามารถนำโค้ดกลับมาใช้ใหม่และปรับแต่งได้ตามต้องการมีการบันทึกและอธิบายตัวเองได้ดี

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


2
จะเป็นอย่างไรถ้าระบบไฟล์ (การลบไฟล์, ไฟล์ใหม่เพิ่ม) เปลี่ยนแปลงไปในขณะที่ pi ทำการสำรองข้อมูล?
keiki

2
ฉันสำรองดิสก์หลายแผ่นในขณะที่ทำงานด้วย rsync และฉันสามารถรับสิ่งที่ฉันต้องการจากการสำรองข้อมูลไฟล์เหล่านี้ได้บ่อยครั้ง อย่างไรก็ตามโดยทั่วไประบบไฟล์ unix ไม่สามารถคัดลอกได้อย่างสมบูรณ์แบบ (ทุกบิตในสถานที่และถูกต้อง) ในขณะที่ติดตั้งระบบไฟล์ (*) สำเนาที่ทำในขณะที่ระบบถูกติดตั้งบางครั้งเรียกว่า "สำเนาสกปรก" สามารถใช้มาตรการหลายอย่างเพื่อปรับปรุงคุณภาพของสำเนาที่สกปรก (ดังที่สคริปต์ด้านบนทำปิด cron และ mysql) แต่ก็ไม่สมบูรณ์แบบ ไชโย! * - ฉันผิดเกี่ยวกับเรื่องนี้มันขึ้นอยู่กับระบบไฟล์
Tai Viinikka

1
คุณสามารถดูยูทิลิตี้การสำรองข้อมูลที่แนะนำ Debianและดูว่า Pi มีพอร์ตของพวกเขาหรือไม่ rsnapshotเสียง promoising
Piotr กุลา

1
@TaiViinikka คุณไม่ต้องการสำเนาที่สมบูรณ์แบบ คุณต้องการสำเนาบางส่วนที่สามารถกำหนดได้อย่างรวดเร็วและง่ายดายบนภาพต้นฉบับดั้งเดิม rsyncเป็นวิธีที่จะไป; เมื่อฉันมีเวลาพรุ่งนี้ฉันจะเพิ่มคำตอบ rsnapshotยังเป็นมูลค่าการตรวจสอบ
goldilocks

3
จากคำตอบ ppumkins ด้านบนฉันได้ซิงค์สคริปต์ 'dd' กับความคิดเห็นล่าสุดในชุดข้อความต้นฉบับและเพิ่มการปรับปรุงเล็กน้อยด้วยตัวเอง ผลลัพธ์สุดท้ายมีให้ที่นี่: < github.com/aweijnitz/pi_backup > โปรดอย่าลังเลที่จะเพิ่มการปรับปรุงและส่งคำขอดึง
AndersW

14

ฉันได้ดัดแปลง @goldilocks ให้คำตอบใน rsync สำหรับการสำรองข้อมูลบน pi ฉันสำรองข้อมูลไปยังext4พาร์ติชันบน HDD ที่ติดตั้งบน Pi หากไม่ได้ติดตั้งฮาร์ดไดรฟ์ rsync จะคัดลอกไปยังไดเรกทอรีติดตั้ง (จนกว่า SD การ์ดจะเต็ม) หาก HDD ไม่ได้ติดตั้งในrwโหมดข้อความผิดพลาดมากมายถูกผลิตขึ้น ทั้งสองอย่างนี้ไม่เป็นที่ต้องการดังนั้นฉันจึงตรวจสอบว่าพาร์ติชันของฉันถูกเมาท์ในrwโหมดก่อนดำเนินการต่อ

หมายเหตุ 2015-03-03 ฉันแก้ไขคำตอบเพื่อคัดลอกลิงก์ที่ถูกต้อง ผลงานต้นฉบับ แต่แปลงฮาร์ดลิงก์จำนวนมากเป็นไฟล์ นอกเหนือจากการสิ้นเปลืองพื้นที่แล้วยังเป็นการใช้งานจำนวนมากซึ่งถือว่ามีการใช้งานฮาร์ดลิงก์ (ภาพปัจจุบันของฉันมี 869 ลิงก์ส่วนมากใน Raspbian นั้น)

สคริปต์ของฉันที่ต้องทำดังต่อไปนี้ (พาร์ติชันของฉันคือ 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/

กลุ่มที่สองคือไฟล์และไดเรกทอรีที่สร้างโดย OS X เมื่อฉันเข้าถึง Pi ของฉันโดยใช้ AFP (Apple Filing Protocol) (โดยทั่วไปจะมองไม่เห็นใน 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

@Milliways ทำไมเราไม่ควรใช้ "sudo rsync ... "? จะมีบางไฟล์ที่ไม่สามารถซิงโครไนซ์ได้หรือไม่
Smilia

6

ฉันมี Pis สามตัวที่ทำงานในเน็ตท้องถิ่นของฉันและต้องการสำรองข้อมูลเหล่านั้นบนฐานปกติพร้อม cron เมื่อมันเริ่มทำงาน นั่นเป็นเหตุผลที่ฉันสร้างสคริปต์ที่สามารถสร้างการสำรองข้อมูล dd, tar และ rsync และเรียกคืนได้ ฉันชอบที่จะใช้ rsync สำหรับการสำรองข้อมูลของฉัน แต่คนอื่นชอบ dd หรือ tar มันถูกใช้โดยคนจำนวนมากแล้ว หวังว่ามันจะมีประโยชน์สำหรับคนอื่น ๆ เช่นกัน :-) raspibackup - Raspberry สร้างการสำรองข้อมูลของตัวเอง


1
ไม่ขออภัย: การขอให้ผู้ใช้เรียกใช้ (ในฐานะ root!) สคริปต์ที่ดาวน์โหลดผ่าน HTTP นั้นจะไม่รับผิดชอบ โปรดแจกจ่ายสคริปต์นี้ผ่านช่องทางที่ปลอดภัย
Clément

1
ฉันไม่คิดว่ามันอยู่นอกหัวข้อและรูทหรือไม่สำคัญมาก ประเด็นก็คือซอฟต์แวร์ควรแจกจ่ายผ่านช่องทางที่ปลอดภัยและคำตอบของคุณคือการส่งเสริมความปลอดภัยที่ไม่ดี
Clément

1
ซึ่งก็จะเป็นขั้นตอนที่ดีข้างหน้าใช่ :)
Clément

2
เพียงเพื่อให้ทราบว่าการส่งมอบผ่าน HTTPS ไม่ได้เพิ่มความปลอดภัยใด ๆ ในตัวอย่างนี้! คุณยังคงดาวน์โหลดและเรียกใช้สคริปต์จากอินเทอร์เน็ต กระบวนการที่ปลอดภัยคือการดาวน์โหลดสคริปต์ (http / https ไม่เกี่ยวข้อง) เปิดสคริปต์ในโปรแกรมแก้ไขและอ่านจากบนลงล่างตรวจสอบสคริปต์เพื่อหาสิ่งแปลก ๆ และความไม่ปลอดภัย เฉพาะเมื่อคุณพอใจคุณควรเรียกใช้ Framp อาจเป็นแฮ็กเกอร์สำหรับเราทุกคนรู้และการส่งมอบผ่าน https จะทำให้เขายิ้มในกรณีนั้น :) (BTW นั่นไม่ใช่ข้อกล่าวหา Framp!)
Julian Knight

2
ฉันเห็นด้วยกับคุณ. นั่นเป็นเหตุผลที่มีสองวิธีที่อธิบายวิธีติดตั้งสคริปต์: 1. ใช้โปรแกรมติดตั้ง 2. ดาวน์โหลดด้วยตนเองตรวจสอบรหัสแล้วติดตั้งด้วยตนเอง
framp

3

นี่คือเครื่องมือที่มีเสถียรภาพของเราสำหรับวัตถุประสงค์ดังกล่าว: https://github.com/aktos-io/aktos-dcs-tools

เครื่องมือนี้ถูกเขียนขึ้นเพื่อmake sshการเชื่อมต่อmake backup-root, make mount-rootจากสถานที่ห่างไกลในใจในตอนแรกและจากนั้นการประชุมในท้องถิ่นที่มีการเพิ่ม ดังนั้นจึงรองรับการสำรองข้อมูลท้องถิ่นการสำรองข้อมูลระยะไกลโดยตรงการสำรองข้อมูลระยะไกลของพร็อกซี การสำรองข้อมูลจะถูกนำมาเพิ่มเติม (เฉพาะส่วนต่างจะถูกโอนย้าย) และไดเรกทอรีการสำรองข้อมูลเป็นแบบสแตนด์อโลน แน่นอนคุณมีรุ่น (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 ของคุณบูต RaspberryPi ด้วยการ์ด SD ที่สร้างขึ้นใหม่


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. เมาท์ext4พาร์ติชันที่จัดรูปแบบแล้วบน Pi in ของคุณ/mntหรือ/media(รูปแบบใดก็ได้ที่อนุญาตให้มีไฟล์ขนาดใหญ่และรองรับโดย Pi เช่น exFAT หรือสามารถใช้ไดรฟ์เครือข่ายได้)
  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'
ขั้นตอนนี้อาจใช้เวลาสักครู่ดังนั้นคุณอาจต้องการเรียกใช้ในพื้นหลัง
นี่เป็นวิธีเดียวกับที่คุณสำรองข้อมูลการ์ด sd ใน Linux


สำรองข้อมูลทุกอย่างแม้กระทั่งไฟล์ที่ไม่จำเป็นและไม่พึงประสงค์
IgorGanapolsky

3
สิ่งนี้จะทำให้การสำรองข้อมูลไม่สอดคล้องกันเพราะสิ่งที่ระบบกำลังทำงานเปลี่ยนแปลงไประหว่างการสำรองข้อมูล!
Ingo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.