Pausando o tar | dividido enquanto o disco está cheio

0

Gostaria de obter um backup de alguns arquivos de um servidor. A idéia básica é criar um arquivo usando tar , salvá-lo em disco e baixá-lo. O problema é a falta de espaço em disco restante (ou RAM para um tmpfs), forçando-me a dividir o arquivo e baixá-lo em partes.

Existe uma maneira fácil (por exemplo, adicionar outro comando entre o pipe de tar to split ) para fazer split pause, quando o disco está cheio demais para a próxima parte e continuar quando o disco estiver Livre de novo? (Por padrão, a divisão apenas sai com uma mensagem de erro quando a gravação falha devido a um disco cheio).

Alternativas que gostaria de evitar:

  • Piping o tar via SSH para salvá-lo diretamente no destino - a conexão pode ser interrompida quando o download é executado por muito tempo e o cliente de download está executando o Windows.
  • Usando dsplit (ou similar para criar vários arquivos tar) - espero que isso evite de concatenar os arquivos depois de baixá-los.
por phi1010 19.11.2017 / 16:56

1 resposta

1

A maioria abaixo é um script rápido e sujo sh desenvolvido para funcionar como um filtro (entre tar e split no seu caso). Ele foi criado no Ubuntu e pode precisar de alguns ajustes para outros sistemas (por exemplo, não sei se column -t | cut -d " " -f 7 é o caminho certo para analisar df independentemente do sistema operacional). Requer /proc .

Salve como ensuredf para onde $PATH aponta, torne executável ( chmod -x ensuredf ) e use assim:

… | ensuredf path requirement | …

onde

  • path é o diretório que você deseja monitorar;
  • requirement é o espaço livre desejado ( df -B deve entender isso);

Exemplo:

… | ensuredf /mnt/foo/data/ 2G | …

A ideia é permitir que o plano de fundo cat passe dados de stdin (do script) para stdout , mas pause imediatamente. Em seguida, invoque df para um determinado path , analise sua saída e verifique se há mais espaço que requirement . Em caso afirmativo, cat é retomado, caso contrário, ele é pausado. Isso faz um loop com um intervalo codificado de 1 segundo, contanto que /proc entrada para esse cat exista.

Outras notas:

  • alguns sistemas de arquivos (especialmente BTRFS) tornam a saída df não tão exata quanto você gostaria;
  • se o seu tar for muito rápido e o espaço necessário for muito baixo, o intervalo de 1 segundo poderá ser muito longo;
  • mas, mesmo que o intervalo seja zero, quando o espaço livre ficar abaixo do requirement , haverá algum atraso antes que o cat seja pausado;
  • se por algum motivo o script de primeiro plano for atrasado e o plano de fundo cat funcionar bem, o disco poderá ficar cheio de qualquer maneira.

Isso significa que você deve definir seu requirement com a margem de segurança adequada. Use este código como um exemplo e ajuste suas necessidades. Consegui escrever um script mais seguro que invoca o primeiro plano dd para passar um pedaço de dados se e somente se houver espaço em disco suficiente, mas esses vários processos dd eram muito mais lentos que um único cat .

#!/bin/sh

[ $# -eq 2 ] || { printf '%s\n' "usage: $0 path requirement" >&2 ; exit 1;}

pth="$1"
rqrmnt="$2"
intrvl=1

</proc/$$/fd/0 cat >/proc/$$/fd/1 &
kill -s STOP $!

while [ -d /proc/$! ] ; do
  if [ $(df -P -B "$rqrmnt" "$pth" | tail -n 1 | column -t | cut -d " " -f 7) -ge 2 ]
  then kill -s CONT $!
  else kill -s STOP $!
  fi
  sleep "$intrvl"
done
    
por 19.11.2017 / 23:49