Junte-se a grandes arquivos sobrepostos

7

Estou tentando recuperar um banco de dados (MySQL) de um disco com falha. Há um número de despejos recentes, que são arquivos bz2 corrompidos. Como o banco de dados não muda com frequência, os despejos devem ser quase idênticos. bzip2recover recuperou cerca de 70-80% dos fragmentos dos arquivos, então a maioria, se não todos, os dados puderam ser recuperados, encontrando as sobreposições nos arquivos e juntando-os. Por exemplo:

dump1: |-----------------|xxxxxxxxxxxxxxxx|------------------|
dump2: |-------------|----------------|xxxxxxxxxxxxxxxxxxxxxx|
dump3: |xxxxxxxxxxxxxxxxxxxxxx|---------------|xxxxxxxxxxxxxx|

aqui eu posso detectar que o primeiro pedaço no dump1 é continuado pelo segundo no dump2, que é continuado pelo segundo no dump3, que é continuado pelo terceiro no dump1. Ao juntar esses quatro arquivos, recuperei os dados.

O problema é que existem milhares de arquivos (eu tenho dez despejos de ~ 400 pedaços de 1M cada). Existe uma ferramenta que poderia automatizar este processo, ou pelo menos partes dele (como um comando linux verificando a mais longa sobreposição entre o final de um arquivo e o início de outro)?

    
por Tgr 17.01.2012 / 08:52

4 respostas

3

Eu precisava exatamente da mesma coisa. Eu criei este código Python surpreendentemente rápido (ele juntou dois arquivos de 2GB com uma sobreposição de 800MB em 30 segundos). Ajuste overlap_size conforme necessário para seus pedaços. Deve ser o maior tempo possível, mas menos do que o tamanho real de sobreposição.

#!/usr/bin/env python

import sys

overlap_size = 100000000 # 100MB

a = file(sys.argv[1]).read()
b = file(sys.argv[2]).read()
end = a[-overlap_size:]
offset = b.find(end)

c = file(sys.argv[3], 'wb')
c.write(a[:-overlap_size])
c.write(b[offset:])
c.close()

Uso:

./join.py chunkA chunkB outputAB
./join.py outputAB chunkC outputABC
./join.py outputABC chunkD outputABCD
...etc
    
por 23.03.2012 / 20:58
1

Eu não tenho uma ferramenta para você fazer o trabalho completamente, mas você pode usar ferramentas como:

cmp -l dump1 dump2

Isso lhe dará a lista de diferentes bytes e seus deslocamentos. A sobreposição é onde não há offset impresso por cmp .

Além disso, você pode usar o comando dd para copiar parte de um dump e anexá-lo a outro dump.

Você pode tentar escrever seu próprio script que usa essas ferramentas ou pode escrever um pequeno programa em C que compara esses arquivos e copiar as partes necessárias.

Espero que você ache essas ideias úteis.

    
por 17.01.2012 / 09:39
1

like a linux command checking for the longest overlap between the end of one file and the start of another

Tradicionalmente, isso seria diff . Ele produzirá a "diferença" de dois arquivos de texto como saída, junto com algumas informações de controle (o que foi adicionado, o que foi removido, quais linhas verificar). O comando patch é capaz de reverter o processo.

Em teoria, você deve ser capaz de usar diff em seus diferentes trechos, trabalhar um pouco em sua saída (como remover os comandos para exclusão de linha) e alimentá-lo com patch :

# echo 'this
> is
> a' > file1
# echo 'a
> chunked' > file2
# echo 'chunked
> data
> file' > file3

# diff file2 file1 | egrep -v '^>' | patch -p0 -R file1 -o file12
patching file file1

# cat file12
this
is
a
chunked

# diff file3 file12 | egrep -v '^>' | patch -p0 -R file12 -o -
patching file file12
this
is
a
chunked
data
file
#

Observe que, se você tiver arquivos de entrada muito grandes, diff precisará de uma grande quantidade de memória.

    
por 17.01.2012 / 12:02
1

Eu acho que você vai ter que escrever uma ferramenta como essa.

Comece com o maior arquivo e copie-o para a memória como sua imagem.

Em seguida, percorra todos os arquivos, um por um, procurando uma sobreposição com o primeiro ou último fragmento da imagem de memória atual. Se você encontrar uma sobreposição, estenda a imagem da memória.

Repita até passar por todos os arquivos sem adicionar nenhum byte. Em seguida, escreva a imagem da memória em um arquivo.

    
por 17.01.2012 / 12:47