Existe uma maneira de pausar um processo em execução nos sistemas Linux e continuar mais tarde?

37

Eu tenho que copiar arquivos em uma máquina. E os dados são imensamente grandes. Agora, os servidores precisam servir normalmente, e geralmente há um intervalo específico de horas ocupadas. Portanto, existe uma maneira de executar esses comandos de uma maneira que, se o servidor entra em horário de pico, ele interrompe o processo e, quando sai desse intervalo, o reinicia?

Resultado pretendido

cp src dst

if time between 9:00-14:00 pause process
After 14:00 resume cp command.
Sollosa
fonte
22
rsync pode retomar transferências parciais
Thorbjørn Ravn Andersen 21/02
2
Você precisa que os dados reais sejam copiados como backup? Caso contrário, você poderia usar cp -alpara criar um farm de hardlinks? Ou use um sistema de arquivos que ofereça suporte a reflinks no nível de bloco com a cópia na gravação, usando cp -a --reflink=auto? O BTRFS e o ZFS são compatíveis com cópias no mesmo dispositivo físico.
Peter Cordes
9
Algum dos arquivos srcmuda entre 9:00 e 14:00? Nesse caso, simplesmente pausar e retomar o cpprocesso pode resultar em arquivos corrompidos. Pode ser melhor executar rsyncem combinação com o timeoutcomando.
Mark Plotnick
De e para onde os arquivos estão sendo copiados? Este é um sistema virtual? Qual é o sistema de arquivos de origem? Qual é o objetivo da cópia?
Braiam 24/02
@Braiam Estou usando o rsync e copiando arquivos do computador remoto para o local. Eu apenas usei o comando cp como exemplo aqui btw
Sollosa

Respostas:

7

Sim, você precisa

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

O processo será exibido com o status "T" (PS). Para continuar faça um

$> kill -CONT <pid>

Boa sorte!

gerhard d.
fonte
77

Você pode pausar a execução de um processo enviando a ele um sinal SIGSTOP e, posteriormente, retomando-o enviando a ele um SIGCONT.

Supondo que sua carga de trabalho seja um processo único (não ajuda os funcionários em execução em segundo plano), você pode usar algo como isto:

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

Em seguida, quando o horário de ocupado começar, envie um SIGSTOP:

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

Posteriormente, quando o servidor estiver inativo novamente, retome-o.

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

Você precisará agendá-lo para horários específicos, quando desejar executá-lo. Você pode usar ferramentas como cron ou systemd timers (ou várias outras ferramentas similares) para agendá-lo. Em vez de agendar com base em um intervalo de tempo, você pode optar por monitorar o servidor (talvez analisando a média de carga, uso da CPU ou atividade dos logs do servidor) para decidir quando pausar / retomar a cópia.

Você também precisa gerenciar o arquivo PID (se você usar um), verifique se a sua cópia ainda está em execução antes de pausá-la, provavelmente você desejará limpar removendo o arquivo pid quando a cópia terminar, etc.

Em outras palavras, você precisa de mais informações para torná-lo confiável, mas a idéia básica do uso desses sinais SIGSTOP e SIGCONT para pausar / retomar a execução de um processo parece ser o que você está procurando.

filbranden
fonte
11
Talvez adicione um lembrete de que você deve tomar muito cuidado para que '/var/run/bigcopy.pid' ainda se refira ao mesmo processo que você pensa. parar aleatoriamente outros processos no sistema pode não ser desejável. Não conheço nenhuma maneira segura de garantir que o pid se refira ao programa que você pensa que faz ...
Evan Benn
@EvanBenn Sim, é isso que eu quis dizer com "certifique-se de que sua cópia ainda esteja em execução antes de pausá-la", embora seu argumento seja certamente mais explícito do que isso! Sim, a verificação de PIDs é inerentemente corrida, portanto, às vezes, não é realmente possível fazê-lo de forma 100% confiável ...
filbranden em 22/02
@cat Na verdade, um processo não pode bloquear o SIGSTOP. Veja o link do primeiro comentário: "SIGSTOP é um sinal não bloqueável como o SIGKILL" (ou apenas pesquise no Google, você verá que é esse o caso).
filbranden
76

Em vez de suspender o processo, você também pode dar uma prioridade mais baixa:

renice 19 "$pid"

dará a menor prioridade (mais alta gentileza), para que o processo traga a CPU para outros processos que precisam dela na maioria das vezes.

No Linux, o mesmo pode ser feito com E / S com ionice:

ionice -c idle -p "$pid"

Colocará o processo na classe "ocioso", para que ele obtenha tempo de disco apenas quando nenhum outro programa solicitar E / S de disco por um período de cortesia definido .

Stéphane Chazelas
fonte
22
Este é um caso típico de um problema XY . A questão era como pausar um processo, mas isso não responde à pergunta. Embora diminuir a prioridade seja a melhor abordagem para o problema real , ele não responde à pergunta. Gostaria de editar a pergunta para incluir também como pausar um processo e por que pausar pode ser um problema (por exemplo, o arquivo pode ser editado enquanto pausado).
MechMK1 21/02
22
@DavidStockinger, tecnicamente, esta resposta diz como dizer ao SO para interromper o processo quando ele (o SO, CPU, agendador de E / S) estiver ocupado (mesmo que seja por frações de segundos por vez). Como suspender o processo manualmente já foi abordado em outras respostas. Esta solução não resolve o problema dos arquivos que estão sendo modificados enquanto estão sendo copiados.
Stéphane Chazelas
5
Alterar a prioridade de E / S nem sempre é a melhor solução. Se você estiver copiando de discos giratórios, ainda poderá solicitar uma busca antes de cada solicitação de alta prioridade na qual não incorreria se pausasse completamente a operação de baixa prioridade.
Mark
2
Prioridade mais baixa nem resolve o problema. Mesmo que a caixa fique completamente ociosa por alguns segundos ou minutos, isso não significa que um processo enorme de cópia que removerá tudo do cache do sistema de arquivos seja discreto. Assim que houver uma carga novamente, será muito lento devolver tudo.
R ..
2
@DavidStockinger, a maneira preferida de lidar com os problemas do XY é fornecer a solução certa , mesmo que não seja isso que a pergunta esteja pedindo. Quando você sabe que a abordagem descrita na pergunta está errada, uma boa resposta não dá essa abordagem errada, mas propõe uma melhor.
terdon
8

Use rsync, esqueça o cp, para este cenário. existem parâmetros para limitar a largura de banda ou podem ser eliminados / interrompidos e iniciados mais tarde, de uma maneira que continuará, de onde saiu do google rsync example / s

Anton Tománek
fonte
3

Se você for fazer isso interrompendo o processo de execução, sugiro que você jogue com o programa Screen. Não uso o Linux há algum tempo, mas o IIRC apenas pausar o comando e retomar mais tarde o deixa bastante vulnerável; se você for desconectado acidentalmente, não poderá retomar sua sessão.

Com a tela, acredito que você pode interromper a sessão, desanexá-la e sair. Mais tarde, você pode voltar e reconectar a essa sessão. Você precisaria brincar um pouco, mas isso tornava as sessões muito mais robustas.

Você também pode sair e voltar para casa, depois fazer login remotamente, reconectar ao sistema que você iniciou no escritório e retomá-lo para a noite, depois recuperá-lo no dia seguinte no trabalho.

Bill K
fonte
Eu já estou usando o tmux para tha. Mas estou escrevendo um script que seja autoconsciente ou, de preferência, ciente do ambiente, para que ele pare se o servidor receber alto tráfego e continue quando estiver normal.
Sollosa 24/02
0

Se o seu shell o suportar (quase todos suportam), pressione ^ Z (Ctrl + Z) para enviar facilmente um SIGTSTPsinal para a tarefa em primeiro plano e continue com fg(em primeiro plano) ou bg(em segundo plano).

Se você fizer isso em várias tarefas e desejar retornar a elas posteriormente, poderá usar o jobscomando e retornar com fg/bg %#, onde # é o número fornecido entre parênteses nos trabalhos.

Lembre-se de que SIGTSTPé um pouco diferente de SIGSTOP(que é usado em todas as outras respostas), o mais importante devido ao fato de que pode ser ignorado (mas eu não vi um programa ignorá-lo sl). Mais detalhes podem ser encontrados nesta resposta no StackOverflow .

Ave
fonte
Surpreso que nenhuma resposta tenha mencionado isso ainda.
Ave
Ty Ave, conheço esse truque de multitarefa. Mas, para que isso aconteça, é preciso estar no terminal, enquanto eu deveria criar um script que faça o trabalho por conta própria, independentemente de levar dias.
Sollosa 26/02
@Sollosa pode ser útil para outras pessoas com a mesma pergunta e com acesso a um terminal.
Ave
Concordo. Bom conhecê-lo Ave :)
Sollosa 27/02