Czy istnieje sposób na zatrzymanie uruchomionego procesu w systemach Linux i wznowienie go później?

37

Muszę skopiować pliki na maszynie. A dane są niezwykle duże. Teraz serwery muszą normalnie obsługiwać, a na nich zazwyczaj jest określony zakres godzin pracy. Czy jest więc sposób na uruchomienie takich poleceń w taki sposób, że jeśli serwer osiągnie godziny pracy, wstrzymuje proces, a kiedy wychodzi poza ten zakres, wznawia go?

Wynik zamierzony

cp src dst

if time between 9:00-14:00 pause process
After 14:00 resume cp command.
Sollosa
źródło
22
rsync może wznowić częściowe transfery
Thorbjørn Ravn Andersen
2
Czy potrzebujemy rzeczywiste dane mogą być kopiowane jako kopii zapasowej? Jeśli nie, czy mógłbyś użyć cp -aldo stworzenia farmy z twardymi linkami? Lub użyj systemu plików, który obsługuje odnośniki na poziomie bloku z kopiowaniem przy zapisie, używając cp -a --reflink=auto? BTRFS i ZFS obsługują kopie na tym samym urządzeniu fizycznym.
Peter Cordes
9
Czy któryś z plików srczmienia się między 9:00 a 14:00? Jeśli tak, po prostu wstrzymanie i wznowienie cpprocesu może spowodować uszkodzenie plików. Może być lepiej uruchomić rsyncw połączeniu z timeoutpoleceniem.
Mark Plotnick
Skąd i gdzie są kopiowane pliki? Czy to jest system wirtualny? Jaki jest źródłowy system plików? Jaki jest cel kopii?
Braiam
@Braiam Im używam rsync i kopiuję pliki ze zdalnego na komputer lokalny. Właśnie użyłem polecenia cp jako przykładu tutaj btw
Sollosa

Odpowiedzi:

7

Tak, musisz

acquire the process id of the process-to-paus (PS), then do
$> kill -SIGSTOP <pid>

Proces wyświetli się ze statusem „T” (PS). Aby kontynuować, zrób

$> kill -CONT <pid>

Powodzenia!

gerhard d.
źródło
77

Możesz wstrzymać wykonywanie procesu, wysyłając mu sygnał SIGSTOP, a następnie wznowić, wysyłając mu sygnał SIGCONT.

Zakładając, że obciążenie jest pojedynczym procesem (nie rozwidla pomocników działających w tle), możesz użyć czegoś takiego:

# start copy in background, store pid
cp src dst &
echo "$!" >/var/run/bigcopy.pid

Następnie, gdy rozpocznie się zajęty czas, wyślij mu SIGSTOP:

# pause execution of bigcopy
kill -STOP "$(cat /var/run/bigcopy.pid)"

Później, gdy serwer będzie ponownie bezczynny, wznów go.

# resume execution of bigcopy
kill -CONT "$(cat /var/run/bigcopy.pid)"

Będziesz musiał zaplanować to na określone czasy, kiedy chcesz to wykonać, możesz użyć narzędzi, takich jak cron lub systemd timery (lub wiele innych podobnych narzędzi), aby zaplanować to. Zamiast planowania na podstawie przedziału czasu, możesz monitorować serwer (być może patrząc na średnie obciążenie, użycie procesora lub aktywność z dzienników serwera), aby zdecydować, kiedy wstrzymać / wznowić kopiowanie.

Musisz także zarządzać plikiem PID (jeśli go używasz), upewnij się, że kopia jest nadal uruchomiona przed wstrzymaniem, prawdopodobnie będziesz chciał wyczyścić, usuwając plik pid po zakończeniu kopiowania itp.

Innymi słowy, potrzebujesz więcej w tym celu, aby uzyskać wiarygodny, ale wydaje się, że szukasz podstawowego pomysłu wykorzystania tych sygnałów SIGSTOP i SIGCONT do wstrzymania / wznowienia wykonania procesu.

filbranden
źródło
1
Może dodaj przypomnienie, że powinieneś bardzo uważać, aby „/var/run/bigcopy.pid” nadal odnosi się do tego samego procesu, jak myślisz. losowe zatrzymywanie innych procesów w systemie może nie być pożądane. Nie znam żadnego bezpiecznego sposobu, aby zapewnić, że pid odnosi się do programu, który Twoim zdaniem tak się dzieje ...
Evan Benn
@EvanBenn Tak, właśnie to miałem na myśli w ten sposób, że „upewnij się, że twoja kopia nadal działa, zanim ją zatrzymasz”, choć twoja uwaga jest z pewnością bardziej wyraźna! Tak, sprawdzanie PID jest z natury wyścigowe, więc czasami naprawdę nie jest to możliwe w 100% niezawodnie ...
filbranden
@cat Nie bardzo, proces nie może zablokować SIGSTOP. Zobacz link z pierwszego komentarza: „SIGSTOP to sygnał nie do zablokowania, taki jak SIGKILL” (lub po prostu google, zobaczysz, że tak jest.)
filbranden
76

Zamiast zawieszać proces, możesz również nadać mu niższy priorytet:

renice 19 "$pid"

nada mu najniższy priorytet (najwyższą niezawodność), dzięki czemu proces da procesor innym procesom, które go potrzebują przez większość czasu.

W systemie Linux to samo można zrobić z I / O za pomocą ionice:

ionice -c idle -p "$pid"

Umieści proces w klasie „bezczynności”, dzięki czemu uzyska czas na dysku tylko wtedy, gdy żaden inny program nie poprosił o dyskowe operacje we / wy przez określony okres karencji .

Stéphane Chazelas
źródło
22
Jest to typowy przypadek problemu XY . Pytanie brzmiało, jak zatrzymać proces, ale to nie odpowiada na pytanie. Wprawdzie obniżenie priorytetu jest lepszym podejściem do rzeczywistego problemu, ale nie odpowiada na pytanie. Chciałbym edytować to pytanie także sposób, aby wstrzymać proces i dlaczego zatrzymując może być problem (np plik może być edytowany w trybie pauzy).
MechMK1
22
@DavidStockinger, technicznie rzecz biorąc, ta odpowiedź mówi, jak powiedzieć systemowi operacyjnemu, aby wstrzymał proces, gdy (system operacyjny, procesor, harmonogram we / wy) jest zajęty (nawet jeśli jest to ułamek sekundy na raz). Jak ręcznie zawiesić proces został już omówiony w innych odpowiedziach. To rozwiązanie nie rozwiązuje problemu modyfikacji plików podczas ich kopiowania.
Stéphane Chazelas
5
Zmiana priorytetu we / wy nie zawsze jest najlepszym rozwiązaniem. Jeśli kopiujesz z obracających się dysków, możesz nadal wyszukiwać przed każdym żądaniem o wysokim priorytecie, którego nie ponosiłbyś, gdybyś całkowicie wstrzymał operację o niskim priorytecie.
Mark
2
Niższy priorytet nawet nie rozwiązuje problemu. Nawet jeśli pudełko jest całkowicie bezczynne przez kilka sekund lub minut, nie oznacza to, że ogromny proces kopiowania, który usunie wszystko z pamięci podręcznej systemu plików, będzie dyskretny. Jak tylko znów pojawi się ładunek, nastąpi bardzo powolne wywoływanie wszystkiego z powrotem.
R ..
2
@DavidStockinger preferowanym sposobem radzenia sobie z problemami XY jest zapewnienie właściwego rozwiązania, nawet jeśli nie o to pyta pytanie. Jeśli wiesz, że podejście opisane w pytaniu jest złe, wtedy dobra odpowiedź nie daje tego złego podejścia, ale proponuje lepsze.
terdon
8

W tym scenariuszu użyj rsync, zapomnij o cp. istnieją parametry, które ograniczają pasmo, lub można je zabić / zatrzymać i uruchomić później, w sposób, w jaki będzie to kontynuowane, w którym pozostawił google rsync example / s

Anton Tománek
źródło
3

Jeśli zamierzasz to zrobić, przerywając uruchomiony proces, sugeruję grę z programem Screen. Od jakiegoś czasu nie używałem Linuksa, ale IIRC po prostu wstrzymuje polecenie i wznawia je później, co czyni cię dość wrażliwym, jeśli przypadkowo się wylogujesz, nie będziesz mógł wznowić sesji.

Wydaje mi się, że z screenem możesz przerwać sesję, a następnie ją odłączyć i wylogować. Później możesz wrócić i ponownie dołączyć do tej sesji. Trzeba by się z tym trochę pobawić, ale dzięki temu sesje są znacznie bardziej niezawodne.

Możesz także wylogować się i wrócić do domu, a następnie zalogować się zdalnie, ponownie podłączyć do systemu uruchomionego w biurze i wznowić go wieczorem, a następnie odebrać go następnego dnia w pracy.

Bill K.
źródło
Już używam Tmux do tego. Ale piszę skrypt, który byłby samoświadomy lub najlepiej świadomy środowiska, więc zatrzymuje się, jeśli serwer osiągnie duży ruch, i kontynuuje, gdy jest normalny.
Sollosa
0

Jeśli twoja powłoka go obsługuje (prawie wszyscy tak robią), możesz nacisnąć ^ Z (Ctrl + Z), aby łatwo wysłać SIGTSTPsygnał do zadania na pierwszym planie, a następnie kontynuować z fg(na pierwszym planie) lub bg(w tle).

Jeśli zrobisz to dla wielu zadań i chcesz wrócić do nich później, możesz użyć jobspolecenia, a następnie wrócić za pomocą fg/bg %#, gdzie # to liczba podana w nawiasach na zadaniach.

Pamiętaj, że SIGTSTPjest nieco inny niż SIGSTOP(który jest używany we wszystkich innych odpowiedziach), co najważniejsze, ponieważ można go zignorować (ale nie widziałem, aby program ignorował to inaczej niż sl). Więcej szczegółów można znaleźć w tej odpowiedzi na StackOverflow .

zdrowaśka
źródło
Zaskoczony, że żadna odpowiedź jeszcze o tym nie wspominała.
Ave
Ty Ave, znam tę sztuczkę wielozadaniowości. Ale żeby tak się stało, trzeba być na terminalu, podczas gdy ja miałem zbudować skrypt, który wykona zadanie samodzielnie, bez względu na to, czy zajmie to kilka dni.
Sollosa
@Sollosa może być przydatny dla innych z tym samym pytaniem i dostępem do terminala.
Ave
Zgadzam się. Fajnie wiedząc, że Ave :)
Sollosa