Recebo de 4 a 100 arquivos tar muito grandes (~ 20 GB) todos os dias. Eu os concatenei no passado, percorrendo cada um dos arquivos que vejo no sistema de arquivos e fazendo algo assim
/bin/tar -concatenate --file=allTars.tar receivedTar.tar
O problema com isso, entretanto, é que à medida que concateno mais e mais arquivos tar, ele deve ser lido até o final allTars.tar
para começar a concatenar novamente. Às vezes, leva mais de 20 minutos para começar a adicionar outro arquivo tar. É muito lento e estou perdendo um prazo de entrega combinado do produto completo allTars.tar
.
Também tentei entregar ao meu comando tar uma lista de arquivos como esta:
/bin/tar --concatenate --file=alltars.tar receiverTar1.tar receivedTar2.tar receivedTar3.tar...etc
Isto deu resultados muito estranhos. allTars.tar
seria o tamanho esperado (ou seja, próximo ao receivedTar.tar
tamanho de todos os arquivos somados), mas parecia sobrescrever os arquivos quando allTars.tar
foi descompactado.
Existe alguma maneira de concatenar todos esses arquivos tar em um comando ou então ele não precisa ler até o final do arquivo sendo concatenado todas as vezesepeça para eles descompactarem corretamente e com todos os arquivos/dados?
Responder1
Isso pode não ajudá-lo, mas se você estiver disposto a usar a -i
opção ao extrair do arquivo final, poderá simplesmente cat
juntar os tars. Um arquivo tar termina com um cabeçalho cheio de nulos e mais preenchimento nulo até o final do registro. Com --concatenate
tar devemos percorrer todos os cabeçalhos para encontrar a posição exata do cabeçalho final, para poder começar a sobrescrever ali.
Se você apenas usar cat
o tars, terá nulos extras entre os cabeçalhos. A -i
opção pede ao tar para ignorar esses nulos entre os cabeçalhos. Então você pode
cat receiverTar1.tar receivedTar2.tar ... >>alltars.tar
tar -itvf alltars.tar
Além disso, seu tar --concatenate
exemplo deveria estar funcionando. No entanto, se você tiver o mesmo arquivo nomeado em vários arquivos tar, você reescreverá esse arquivo várias vezes ao extrair tudo do tar resultante.
Responder2
Esta questão é bastante antiga, mas gostaria que tivesse sido mais fácil encontrar as seguintes informações mais cedo. Então, se alguém se deparar com isso, aproveite:
O que Jeff descreve acima é um bug conhecido no gnu tar (relatado em agosto de 2008). Somente o primeiro arquivo (aquele após a -f
opção) tem seu marcador EOF removido. Se você tentar concatenar mais de 2 arquivos, o(s) último(s) arquivo(s) ficará(ão) "escondido(s)" atrás dos marcadores de final de arquivo.
É um bug no alcatrão. Ele concatena arquivos inteiros, incluindo blocos de zeros à direita, portanto, por padrão, a leitura do arquivo resultante é interrompida após a primeira concatenação.
Fonte:https://lists.gnu.org/archive/html/bug-tar/2008-08/msg00002.html (e mensagens seguintes)
Considerando a idade do bug, me pergunto se algum dia ele será corrigido. Duvido que haja uma massa crítica afetada.
A melhor maneira de contornar esse bug seria usar a -i
opção, pelo menos para arquivos .tar em seu sistema de arquivos.
Como Jeff aponta, tar --concatenate
pode levar muito tempo para chegar ao EOF antes de concatenar o próximo arquivo. Portanto, se você ficar com um arquivo "quebrado" que precisa da tar -i
opção de descompactar, sugiro o seguinte:
Ao invés de usar
tar --concatenate -f archive1.tar archive2.tar archive3.tar
provavelmente será melhor você correr cat archive2.tar archive3.tar >> archive1.tar
ou pipe dd
se você pretende gravar em um dispositivo de fita. Observe também que issopoderialevaria a um comportamento inesperado se as fitas não fossem zeradas antes de (sobre)escrever novos dados nelas. Por esse motivo, a abordagem que adotarei em meu aplicativo é o nested tars, conforme sugerido nos comentários abaixo da pergunta.
A sugestão acima é baseada no seguinte benchmark de amostra muito pequena:
time tar --concatenate -vf buffer.100025.tar buffer.100026.tar
real 65m33.524s
user 0m7.324s
sys 2m50.399s
time cat buffer.100027.tar >> buffer.100028.tar
real 46m34.101s
user 0m0.853s
sys 1m46.133s
Os arquivos buffer.*.tar têm todos 100 GB de tamanho, o sistema estava praticamente ocioso, exceto para cada uma das chamadas. A diferença de tempo é significativa o suficiente para que eu pessoalmente considere este benchmark válido, apesar do pequeno tamanho da amostra, mas você é livre para fazer seu próprio julgamento sobre isso e provavelmente é melhor executar um benchmark como este em seu próprio hardware.
Responder3
Como você declarou, o arquivo de destino deve ser lido até o fim antes que o segundo arquivo de origem seja anexado a ele. GNU tar tem uma -n
opção que o instrui a assumir que um arquivo é pesquisável (lembre-se que o tar foi projetado para arquivos de fita e fluxo que não são pesquisáveis). O tar GNU supostamente tem como padrão detectar automaticamente se um arquivo pode ser procurado, no entanto, muitos usuários como você podem garantir que o tar pule a leitura do conteúdo completo de cada registro adicionando a -n
opção:
tar -n --concatenate --file=target_file.tar other_file.tar
Não consigo verificar (no momento da escrita) quais versões do tar, se houver, funcionarão conforme o esperado para este comando. Se outros usuários tiverem a capacidade de provar esta solução, comente abaixo e atualizarei esta resposta de acordo.
Responder4
Como a concatenação exige muita E/S, eu recomendaria a necessidade de 3 SSD (1 TB) em um RAID 0. Um único SSD no sata 3 fornecerá 500 MB/s de leitura e similar para gravação. Caro, sim, mas rápido x3.