Ładuję dość gigantyczny plik do bazy danych postgresql. Aby to zrobić, najpierw używam split
w pliku, aby uzyskać mniejsze pliki (30 Gb każdy), a następnie ładuję każdy mniejszy plik do bazy danych za pomocą GNU Parallel
i psql copy
.
Problem polega na tym, że dzielenie pliku zajmuje około 7 godzin, a następnie zaczyna ładować plik na rdzeń. Potrzebuję sposobu, aby powiedzieć, split
aby wydrukować nazwę pliku na standardowym wyjściu za każdym razem, gdy kończy zapisywanie pliku, dzięki czemu mogę go przesłać do Parallel
niego, a on zaczyna ładować pliki w momencie, split
gdy go zapisuje. Coś takiego:
split -l 50000000 2011.psv carga/2011_ | parallel ./carga_postgres.sh {}
Przeczytałem split
strony podręcznika i nic nie mogę znaleźć. Czy można to zrobić za pomocą split
innego narzędzia?
źródło
Dlaczego nie użyć --pipe AND --pipepart z GNU Parallel? To eliminuje dodatkowy kot i rozpoczyna bezpośrednie odczytywanie z pliku na dysku:
źródło
Znalazłem zamieszczone tutaj odpowiedzi, które są skomplikowane, więc zapytałem na Stack Overflow i otrzymałem tę odpowiedź:
Jeśli używasz
GNU split
, możesz to zrobić z--filter
opcjąMożesz utworzyć skrypt powłoki, który tworzy plik i uruchomić carga_postgres.sh na końcu w tle
i użyj tego skryptu jako filtra
źródło
Alternatywą dla
split
drukowania nazw plików jest wykrycie, kiedy pliki są gotowe. W systemie Linux można użyć funkcji inotify , a zwłaszczainotifywait
narzędzia.Musisz zabić
inotifywait
ręcznie. Automatyczne zabicie go jest trochę trudne, ponieważ istnieje potencjalny warunek wyścigu: jeśli zabijesz go zaraz posplit
zakończeniu, może otrzymać zdarzenia, których jeszcze nie zgłosił. Aby upewnić się, że wszystkie zdarzenia są zgłaszane, policz pasujące pliki.źródło