Incremental backup in a dozen lines

What is most important for backups? That's right, reproducibility. So let's make a bike on the knee and on the --link-dest option of rsync . Our bike will not have a complex git-like restic data structure, nor a bunch of backends like duplicity. But we can restore his work from memory, even under stress.


The --link-dest option allows you to specify the previous backup version on which rsync will put hard links if files have not changed since the last time.


That is, rsync --link-dest=/var/backups/www.1 remote:/var/www /var/backups/www.0 copies only those files from the remote server to the /var/backups/www.0 folder that have changed, but for the rest it will put a hard link in /var/backups/www.1


Now the trick is small: wrap the rsync call in code that shifts backups by one back and frees up space for a new backup in /var/backups/www.0 , and also removes the last copy of /var/backups/www.9 .


 #  find /var/www/backups/ -maxdepth 1 -type d -name '*.[0-9]'| sort -rn| while read dir do #     this=`expr match "$dir" '.*\([0-9]\)'`; #   1,  ,      10  let next=($this+1)%$10; basedirname=${dir%.[0-9]} if [ $next -eq 0 ] ; then rm -rf $dir else mv $dir $basedirname.$next fi done 

This code will rename /var/backups/www.1 to /var/backups/www.2 and /var/backups/www.0 rename /var/backups/www.1 .


It remains only to run rsync --link-dest=/var/backups/www.1 remote:/var/www /var/backups/www.0 , adding options to taste. So the --delete option deletes the files in the last copy ( rsync does not do this by default), the -C option ignores the .svn , .git folders, patch artifacts and some other common types of temporary files.


Together:


 #!/bin/bash FROM=$1 #  TO=$2 #  LINKTO=--link-dest=$TO/`basename $FROM`.1 #   OPTS="-Ca --delete" #    rsync NUMBER_OF_BACKUPS=10 #     #    ,       # dir.1, dir.2, dir.3     dir.9 find $TO -maxdepth 1 -type d -name '*.[0-9]'| sort -rn| while read dir do this=`expr match "$dir" '.*\([0-9]\)'`; let next=($this+1)%$NUMBER_OF_BACKUPS; basedirname=${dir%.[0-9]} if [ $next -eq 0 ] ; then rm -rf $dir else mv $dir $basedirname.$next fi done #  ,  rsync rsync $OPTS $LINKTO $FROM/ $TO/`basename $FROM.0` 

Outside of the brackets was error handling (see set -e ) and notifications, and the number of copies can be made customizable.


But it works!



Source: https://habr.com/ru/post/475510/


All Articles