Can rsync break a USB pen?

To confirm, they are dead after performing multiple backups over months!


Looking at the command you provided in your OP, the issue is that you have not specified any default “–delete*” option to delete files that no longer exist in the source image.

Because of that, any files that

  • are deleted the source,
  • have been renamed on the source,       or
  • have been moved to a different directory location than that on the source,

remain as real, but not required copies, on the backup image, thereby creating an unwanted data growth on the USB keys!

You need to specify one of those “–delete*” options to ensure that your backup directory is an exact mirror of your source directory.

If there is no chance of ever coming close to disk limits on your backup disk, you could use the option “–delete-after”, but I strongly recommend you try to reign data growth in by using either “–delete-during”.

I don’t know what others feel about this, but I think the “–delete-before” option is inadvisable for all scenarios except those where it is directly required to achieve some particular disk image configuration “goal”.


One caveat …

If you are creating backup directories (multiple, date-named), then you need a logic to perform a “turnover” of backup images, namely, establish an aging mechanism to purge images that are older than a specified age.


If you are interested, you might want to have a look at my backup script, which is available here:

The behaviour of that script is presented in a posting as part of the following discussion:


Give you a look at my backup drive “high-level” contents, this is a listing:

DB005_F1:
LIMIT__Bandwidth_rsync.txt  lost+found

DB005_F2:
DB001_F2                           Z_backup.DB001_F2.CheckSum.batch     Z_backup.DB001_F2.DateSize.out
KEEP__Z_backup.DB001_F2.err__KEEP  Z_backup.DB001_F2.CheckSum.err       Z_backup.DB001_F2.DateSize.out.PREV
KEEP__Z_backup.DB001_F2.out__KEEP  Z_backup.DB001_F2.CheckSum.out       Z_backup.DB001_F2.err
LIMIT__Bandwidth_rsync.txt         Z_backup.DB001_F2.DateSize.batch     Z_backup.DB001_F2.err.PREV
lost+found                         Z_backup.DB001_F2.DateSize.err
Z_backup.DB001_F2.batch            Z_backup.DB001_F2.DateSize.err.PREV

DB005_F3:
Backup.DB001_F3.tarerr      lost+found                        Z_backup.DB001_F3.DateSize.err
Backup.DB001_F3.tarlog      tarBackup.batch                   Z_backup.DB001_F3.DateSize.err.PREV
DB001_F3                    Z_backup.DB001_F3.batch           Z_backup.DB001_F3.DateSize.out
LIMIT__Bandwidth_rsync.txt  Z_backup.DB001_F3.DateSize.batch  Z_backup.DB001_F3.DateSize.out.PREV

DB005_F4:
DB001_F4                    Z_backup.DB001_F4.DateSize.batch     Z_backup.DB001_F4.DateSize.out.PREV
LIMIT__Bandwidth_rsync.txt  Z_backup.DB001_F4.DateSize.err       Z_backup.DB001_F4.err
lost+found                  Z_backup.DB001_F4.DateSize.err.PREV  Z_backup.DB001_F4.err.PREV
Z_backup.DB001_F4.batch     Z_backup.DB001_F4.DateSize.out

DB005_F5:
DB001_F5                    Z_backup.DB001_F5.batch           Z_backup.DB001_F5.DateSize.err
DB001_F5_Restore.err        Z_backup.DB001_F5.CheckSum.batch  Z_backup.DB001_F5.DateSize.err.PREV
DB001_F5_Restore.log        Z_backup.DB001_F5.CheckSum.err    Z_backup.DB001_F5.DateSize.out
LIMIT__Bandwidth_rsync.txt  Z_backup.DB001_F5.CheckSum.out    Z_backup.DB001_F5.DateSize.out.PREV
lost+found                  Z_backup.DB001_F5.DateSize.batch

DB005_F6:
DB001_F6                    Z_backup.DB001_F6.DateSize.batch     Z_backup.DB001_F6.DateSize.out.PREV
LIMIT__Bandwidth_rsync.txt  Z_backup.DB001_F6.DateSize.err       Z_backup.DB001_F6.err
lost+found                  Z_backup.DB001_F6.DateSize.err.PREV  Z_backup.DB001_F6.err.PREV
Z_backup.DB001_F6.batch     Z_backup.DB001_F6.DateSize.out

DB005_F7:
DB001_F7                    Z_backup.DB001_F7.DateSize.batch     Z_backup.DB001_F7.DateSize.out.PREV
LIMIT__Bandwidth_rsync.txt  Z_backup.DB001_F7.DateSize.err       Z_backup.DB001_F7.err
lost+found                  Z_backup.DB001_F7.DateSize.err.PREV  Z_backup.DB001_F7.err.PREV
Z_backup.DB001_F7.batch     Z_backup.DB001_F7.DateSize.out

DB005_F8:
Appl__Firefox__CachePurge.20220723-225612.001.log  Z_backup.DB001_F1.CheckSum.out
ApplRestore__Firefox.sh                            Z_backup.DB001_F1.DateSize.batch
DB001_F1                                           Z_backup.DB001_F1.DateSize.err
LIMIT__Bandwidth_rsync.txt                         Z_backup.DB001_F1.DateSize.err_FULL
lost+found                                         Z_backup.DB001_F1.DateSize.err.PREV
REF__Z_backup.DB001_F1.DateSize.err__REF           Z_backup.DB001_F1.DateSize.out
Z_backup.DB001_F1.batch                            Z_backup.DB001_F1.DateSize.out_FULL
Z_backup.DB001_F1.CheckSum.batch                   Z_backup.DB001_F1.DateSize.out.PREV
Z_backup.DB001_F1.CheckSum.err                     zzz

Each of those DB005_F? is located at /site/DB005_F?.


The following is an example of the actual “batch” script which runs in the background to perform the backups.

# more Z_backup.DB001_F6.DateSize.batch

	
echo 'Thu 21 May 2026 03:55:17 PM EDT |rsync| Start DB001_F6 
	Process ID => '$$' ...' >&2
	cd /DB001_F6
	
	rm -f /site/Z_backup.DB001_F6.DateSize.out
	rm -f /site/Z_backup.DB001_F6.DateSize.err
	{
	
ionice -c 2 -n 7 rsync 		--bwlimit=32768 		 		 		 		--one-fi
le-system 		--outbuf=Line 		--recursive 		--delete-during 		--preallocate 	
	--links 		--perms 		--times 		--group 		--owner 	
	--atimes 		--devices 		--specials 		--verbose --out-format="%t|%i|%M|%b|%f|"
 		--whole-file 		--human-readable 		--protect-args 		--ignore-errors 	
	--msgs2stderr 		 		./ /site/DB005_F6/DB001_F6/
	
echo 'START = Thu 21 May 2026 03:55:17 PM EDT' ; 
echo '  END = '`date` 
	} 2>/site/Z_backup.DB001_F6.DateSize.err >/site/Z_backup.DB001_F6.DateSize.out
	RC=$?
	
if [ ${RC} -eq 0 ]; then
	
	test -s /site/DB005_F6/Z_backup.DB001_F6.DateSize.out  &&  mv -f /site/DB005_F6/Z_backup.DB001_F6.DateSize.out /
site/DB005_F6/Z_backup.DB001_F6.DateSize.out.PREV
	test -s /site/DB005_F6/Z_backup.DB001_F6.DateSize.err  &&  mv -f /site/DB005_F6/Z_backup.DB001_F6.DateSize.err /
site/DB005_F6/Z_backup.DB001_F6.DateSize.err.PREV
	
	mv /site/Z_backup.DB001_F6.DateSize.out /site/DB005_F6/Z_backup.DB001_F6.DateSize.out
	mv /site/Z_backup.DB001_F6.DateSize.err /site/DB005_F6/Z_backup.DB001_F6.DateSize.err
	
else
	
	mv /site/Z_backup.DB001_F6.DateSize.out /site/DB005_F6/Z_backup.DB001_F6.DateSize.out.$RC
	mv /site/Z_backup.DB001_F6.DateSize.err /site/DB005_F6/Z_backup.DB001_F6.DateSize.err.$RC
	
	man rsync | awk -v P=$RC '{ if( $1 == P ){ print $0 ; } ; }' 
	
fi

@Actionparsnip shared his viewpoint with that statement!

That may be valid for his context. It can also be invalid for your context. You need to make that determination yourself.

My own script uses the command line in the form

rsync ${options} ${relativePathToSource} ${absolutePathToMirror}

which for my context, is the best! You have to test the various approaches to identify which works best for you.


The “–bwlimit” value is supposedly for controlling interface thruput.

In my case, with the system able to collect the source faster than being able to write the backup image, I specify a value to limit the memory buffer size, so that I don’t swamp my memory, slowing down my GUI responsiveness, during the backups which, by the way, is another strategic reason to divide both your main drive and backup drive into multiple partitions, so you can work on one partition while doing backups of another partition which is static. Hence the multiple backup directories listed above.

1 Like