Ich lade eine ziemlich gigantische Datei in eine Postgresql-Datenbank. Dazu verwende ich zuerst split
in der Datei kleinere Dateien (jeweils 30 GB) und lade dann jede kleinere Datei mit GNU Parallel
und in die Datenbank psql copy
.
Das Problem ist, dass das Teilen der Datei ungefähr 7 Stunden dauert und dann eine Datei pro Kern geladen wird. Was ich brauche, ist eine Möglichkeit, split
den Dateinamen jedes Mal, wenn er mit dem Schreiben einer Datei fertig ist, in die Standardausgabe zu drucken, damit ich sie weiterleiten kann, Parallel
und er beginnt mit dem Laden der Dateien, wenn er split
fertig geschrieben ist. Etwas wie das:
split -l 50000000 2011.psv carga/2011_ | parallel ./carga_postgres.sh {}
Ich habe die split
Manpages gelesen und kann nichts finden. Gibt es eine Möglichkeit, dies mit split
oder einem anderen Tool zu tun ?
quelle
Warum nicht --pipe AND --pipepart mit GNU Parallel verwenden? Dadurch entfällt die zusätzliche Katze und es werden direkte Lesevorgänge von der Datei auf der Festplatte gestartet:
quelle
Ich fand die Antworten hier gepostet Weg zu komplex sein , so dass ich auf Stack - Überlauf gefragt , und ich habe diese Antwort:
Wenn Sie verwenden
GNU split
, können Sie dies mit der--filter
Option tunSie können ein Shell-Skript erstellen, das eine Datei erstellt und carga_postgres.sh am Ende im Hintergrund startet
und verwenden Sie dieses Skript als Filter
quelle
Eine Alternative zum
split
Drucken der Dateinamen besteht darin, zu erkennen, wann die Dateien fertig sind. Unter Linux können Sie die Funktion inotify und insbesondere dasinotifywait
Dienstprogramm verwenden.Sie müssen
inotifywait
manuell töten . Es automatisch zu töten ist etwas schwierig, da es eine mögliche Rennbedingung gibt: Wenn Sie es töten, sobaldsplit
es fertig ist, hat es möglicherweise Ereignisse erhalten, die es noch nicht gemeldet hat. Um sicherzustellen, dass alle Ereignisse gemeldet werden, zählen Sie die übereinstimmenden Dateien.quelle