Estoy cargando un archivo bastante gigantesco en una base de datos postgresql. Para hacer esto, primero lo uso split
en el archivo para obtener archivos más pequeños (30 Gb cada uno) y luego cargo cada archivo más pequeño en la base de datos usando GNU Parallel
y psql copy
.
El problema es que toma aproximadamente 7 horas dividir el archivo y luego comienza a cargar un archivo por núcleo. Lo que necesito es una manera de decirle split
que imprima el nombre del archivo a la salida estándar cada vez que termine de escribir un archivo para poder conectarlo Parallel
y comience a cargar los archivos en el momento en que split
termine de escribirlo. Algo como esto:
split -l 50000000 2011.psv carga/2011_ | parallel ./carga_postgres.sh {}
He leído las split
páginas del manual y no puedo encontrar nada. ¿Hay alguna manera de hacer esto con split
alguna otra herramienta?
fuente
¿Por qué no usar --pipe AND --pipepart con GNU Parallel? Esto elimina el gato extra e inicia lecturas directas del archivo en el disco:
fuente
Encontré que las respuestas publicadas aquí son complejas, así que pregunté por Stack Overflow y obtuve esta respuesta:
Si lo usa
GNU split
, puede hacerlo con la--filter
opciónPuede crear un script de shell, que crea un archivo e iniciar carga_postgres.sh al final en segundo plano
y usar ese script como filtro
fuente
Una alternativa para
split
imprimir los nombres de los archivos es detectar cuándo están listos. En Linux, puede usar la función inotify , y específicamente lainotifywait
utilidad.Tendrás que matar
inotifywait
manualmente. Matarlo automáticamente es un poco difícil porque hay una posible condición de carrera: si lo matas tan pronto comosplit
termine, es posible que haya recibido eventos que aún no ha informado. Para asegurarse de que se informan todos los eventos, cuente los archivos coincidentes.fuente