I am using Rsync to do the incremental backups of the data, but for some reason after 3-4 proper incremental backups, rsync performs Full backup, occupying twice the space, then I quickly run out of space on the backup machine. The scenario is that cron performs the incremental rsync everyday, and then additional script removes certain backups , leaving:

  • 7 daily backups
  • 4 (approx.) weekly backups
  • 12 monthly backups
  • 5 annual backups

Here is the script I am using:


TODAY=$(date +%Y-%m-%d)
if [[ ! -e ${TODAYPATH} ]]; then
        mkdir -p ${TODAYPATH}

rsync -a --link-dest ${LASTDAYPATH} ${DATADIR} ${TODAYPATH} $@


And then the deleteOldBackups.sh looks like:


function listYearlyBackups() {
        for i in 0 1 2 3 4 5
                do ls ${BACKUPDIR} | egrep "$(date +%Y -d "${i} year ago")-[0-9]{2}-[0-9]{2}" | sort -u | head -n 1

function listMonthlyBackups() {
        for i in 0 1 2 3 4 5 6 7 8 9 10 11 12
                do ls ${BACKUPDIR} | egrep "$(date +%Y-%m -d "${i} month ago")-[0-9]{2}" | sort -u | head -n 1

function listWeeklyBackups() {
        for i in 0 1 2 3 4
                do ls ${BACKUPDIR} | grep "$(date +%Y-%m-%d -d "last monday -${i} weeks")"

function listDailyBackups() {
        for i in 0 1 2 3 4 5 6
                do ls ${BACKUPDIR} | grep "$(date +%Y-%m-%d -d "-${i} day")"

function getAllBackups() {

function listUniqueBackups() {
        getAllBackups | sort -u

function listBackupsToDelete() {
        ls ${BACKUPDIR} | grep -v -e "$(echo -n $(listUniqueBackups) |sed "s/ /\\\|/g")"

listBackupsToDelete | while read file_to_delete; do
        rm -rf ${file_to_delete}

What am I doing wrong that after 3-4 incremental backups rsync does not link the previous, but make the new FULL one ? Thank you

1 Answer 1


Consider replacing your script with rsnapshot, which does exactly what you're trying to do.

It's hard to say exactly why your script is failing without more troubleshooting, but here are some ideas. I see three possible issues that could be causing your problem:


This could happen if there are stray files/directories getting written to $BACKUPDIR for some reason. Check for this by logging the value of $LASTDAYPATH to a file to make sure it's getting setting to what you expect. If this is the problem, you may be able to fix by using an appropriate glob when setting $LASTDAYPATH:

LASTDAYPATH=${BACKUPDIR}/$(ls -d "${BACKUPDIR}"/2???-??-?? | tail -n 1)

Backed up files or metadata are changing

--link-dest will only link files if the size, mtime, owner, group, and permissions match. So even if the data in the files isn't changing, you would still do a full copy of a file where the timestamp gets changed for some reason. To help debug this issue, compare two backups to see which files have different inode numbers. If the inodes match, the files are linked, if they don't match, then those particular files got copied. Use a command like this to compare $DIR1 and $DIR2:

diff <(cd $DIR1 && find -type f -printf "%i %p\n" | sort -k 2) <(cd $DIR2 && find -type f -printf "%i %p\n" | sort -k 2)

Previous day's backup is incomplete

If the rsync fails for any reason, you will end up with an empty or partial backup but you will still use it as --link-dest because the directory exists. It would be a good idea to rsync to a directory name like partial.${TODAY} and then rename that to $TODAY only if the rsync command completed without error. And combine that with the LASTDAYPATH change above.

  • I should have mentioned this earlier: +1 for recommending rsnapshot Dec 14, 2020 at 12:33
  • I stuck at a similar problem with a test scenario at the moment. No matter if I change one of my files or no files the inodes are never the same with your shown diff command. The only main difference: my link-dest is a symbolik link.
    – MaKaNu
    Mar 25, 2022 at 13:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .