Como permitir que o rsync armazene adicionalmente um changelog diferencial em outro diretório?

1

Estou usando rsync --link-dir para obter instantâneos diários com pouco uso de espaço devido ao hardlinking. No entanto, seria bom ter também um diretório que, ao espelhar a estrutura original, contenha apenas (hardlinks para o backup completo) os arquivos realmente alterados. Por exemplo, aqui está a estrutura do diretório antes:

source/        <- contains the original data
backup/current <- symlink to the most recent snapshot
backup/12102?  <- recent daily snapshots (irrelevant)

e aqui a estrutura desejada depois:

source/
backup/current <- symlink to the _updated_ snapshot
backup/previous<- symlink to the snapshot that was was "current" before
backup/12102?  <- ...
backup/current.changes  <- (symlink to) directory containing _only_ the files that
                           have changed between "current" and "previous"
    
por Tobias Kienzler 24.10.2012 / 16:42

1 resposta

1

Aqui está o script que acabei usando:

#!/bin/bash
set +x
SRC=$1
BCK=$SRC/.snapshots
CUR=$BCK/current
DAT=$(date +%Y-%m/%y%m%d)
DST=$BCK/$DAT
PAR="-aP --chmod=a-w,o-rwx --no-owner"

LNK="--link-dest=$CUR --link-dest=$DST.changeset"
CMP="--compare-dest=$CUR --prune-empty-dirs"
XCL="--exclude-from $BCK/.rsyncignore"
LOG="$BCK/log/$DAT"
LGP="--log-file $LOG"

mkdir -pm750 $DST.incomplete
mkdir -pm750 $DST.changeset.incomplete
mkdir -pm750 $(dirname $LOG)

rsync $PAR $CMP $XCL $LGP.change.log $SRC/ $DST.changeset.incomplete | tee $LOG.change.out
mv $DST.changeset.incomplete $DST.changeset
find $DST.changeset -type d -empty -delete
rsync $PAR $LNK $XCL $LGP.log $SRC/ $DST.incomplete | tee $LOG.out
mv $DST.incomplete $DST
rm -f $CUR
ln -s $DAT $CUR

Ele criará instantâneos em DST=$1/.snapshots/YYYY-MM/yymmdd fashion e $DST.changeset conterá apenas os diretórios não vazios contendo arquivos que foram criados ou modificados . A exclusão (e indiretamente mv ) não é reconhecida, embora um terceiro rsync trocando $DST e $CUR criasse o modlog reverso, que então poderia ser mesclado com o changeset incompleto talvez usando a sintaxe diff para alguns renomeação intuitiva ... Ou, você apenas analisa a saída de log do rsync ou usa diretamente o git , já que você está basicamente versionando ...

resposta antiga:

Meu primeiro pensamento foi usar uma cópia de hardlink do backup anterior junto com o parâmetro --backup-dir , mas que obteria a versão anterior dos arquivos que foram alterados, que é a mesma do que Estou à procura de. O truque é inverter isso:

  • Primeiro, crie o instantâneo usual usando hardlinks:
    rsync -a --link-dest=/backup/current /source/ /backup/$TODAY.incomplete
    (Você pode ter que usar --no-owner --chmod=... etc. para fazer rsync definitivamente usar hardlinks)
  • Agora substitua o novo instantâneo pelo anterior, mas deixe --backup mover os arquivos alterados:
    rsync -ab --backup-dir=/backup/$TODAY.changelog.incomplete --delete /backup/current/ /backup/$TODAY.incomplete
    mv /backup/$TODAY.changelog.incomplete /backup/$TODAY.changelog
  • Parabéns, você estragou o novo instantâneo à custa de criar um changelog!
    Corrigir isto (e limpeza) com o
    cp -alf /backup/$TODAY.changelog/* /backup/$TODAY.incomplete
    mv /backup/$TODAY.incomplete /backup/$TODAY
    mv -f /backup/current /backup/previous
    ln -sf /backup/$TODAY /backup/current

Note que este "changelog" na verdade contém apenas arquivos novos ou alterados (o último somente se você não esqueceu o --delete ); nem exclusões nem mv s são rastreadas. Algumas modificações podem corrigir isso ...

    
por 24.10.2012 / 16:42

Tags