Estou carregando um arquivo gigantesco em um banco de dados postgresql. Para fazer isso, primeiro uso split
no arquivo para obter arquivos menores (30 GB cada) e, em seguida, carrego cada arquivo menor no banco de dados usando GNU Parallel
e psql copy
.
O problema é que leva cerca de 7 horas para dividir o arquivo e, em seguida, ele começa a carregar um arquivo por núcleo. O que eu preciso é uma maneira de informar split
para imprimir o nome do arquivo na saída std toda vez que ele terminar de escrever um arquivo, para que eu possa canalizá-lo Parallel
e ele começará a carregar os arquivos no momento em que split
terminar de escrevê-lo. Algo assim:
split -l 50000000 2011.psv carga/2011_ | parallel ./carga_postgres.sh {}
Eu li as split
páginas de manual e não consigo encontrar nada. Existe uma maneira de fazer isso com split
ou qualquer outra ferramenta?
fonte
Por que não usar --pipe AND --pipepart com o GNU Parallel? Isso elimina o gato extra e inicia leituras diretas do arquivo no disco:
fonte
Eu achei as respostas postadas aqui muito complexas, então perguntei no Stack Overflow e recebi esta resposta:
Se você usar
GNU split
, poderá fazer isso com a--filter
opçãoVocê pode criar um script de shell, que cria um arquivo e inicia carga_postgres.sh no final em segundo plano
e use esse script como filtro
fonte
Uma alternativa para
split
imprimir os nomes dos arquivos é detectar quando os arquivos estão prontos. No Linux, você pode usar o recurso inotify e, especificamente, oinotifywait
utilitário.Você precisará matar
inotifywait
manualmente. Matá-lo automaticamente é um pouco difícil, porque existe uma condição potencial de corrida: se você matá-lo assim quesplit
terminar, pode ter recebido eventos que ainda não foram relatados. Para garantir que todos os eventos sejam relatados, conte os arquivos correspondentes.fonte