O que poderia fazer com que um script PHP fosse executado como uma tarefa cron no estado D?

1

Meu servidor está executando o Ubuntu 12.04 LTS (preciso) e estou tendo um problema estranho. O servidor está hospedando um site grande que é usado para coleta de dados. O site está em PHP e usa o Zend Framework. Os dados estão em um banco de dados MySQL. Parte desses dados (de pesquisas) é processada em arquivos do Excel (usando a biblioteca PHPExcel) a cada hora (tarefa cron). Esse processo (um script do PHP / Zend Framework) é feito para cada cliente, cada um com um conjunto de dados diferente e, às vezes, pode levar muito tempo (mais de 30 minutos).

Assim que atinge os 30 minutos, o estado do processo muda de R para D. O mais estranho é que os processos no estado D são geralmente "impossíveis de matar", mas este pode ser eliminado como qualquer outro processo. Aqui está um exemplo de saída enquanto o processo está sendo executado normalmente:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
www      16089  0.5  0.8 311640 31708 ?        S    09:34   0:39 /usr/sbin/apache2 -k start
www      17635  0.6  0.6 305020 23396 ?        S    10:52   0:18 /usr/sbin/apache2 -k start
www      18520  0.0  0.0  63104  1960 pts/0    S    11:32   0:00 su www
www      18521  0.0  0.1  23236  4516 pts/0    S    11:32   0:00 bash
www      18621 98.8 68.1 2665208 2416568 pts/0 R    11:33  10:48 php run.php -a hourly
www      18659  0.6  0.6 302848 22948 ?        S    11:34   0:03 /usr/sbin/apache2 -k start
www      18876  0.0  0.0  18160  1244 pts/0    R+   11:44   0:00 ps ux

Você pode ver que o processo é intensivo em recursos: ele já foi muito aparado e ainda está passando por uma cirurgia, mas eu preciso que ele seja concluído para que eu possa obter os arquivos do Excel resultantes. O processo está registrando muitas de suas atividades (~ 300k log para cada arquivo do Excel), e os arquivos de log sempre terminam abruptamente. Não há nenhum erro registrado em qualquer lugar que eu possa encontrar.

Aqui está a mesma lista de processos logo após a marca de 30 minutos:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
www      18034  1.0  0.7 312412 26632 ?        S    11:13   0:33 /usr/sbin/apache2 -k start
www      18245  2.1  0.4 303656 16912 ?        S    11:25   0:49 /usr/sbin/apache2 -k start
www      18520  0.0  0.0  63104   296 pts/0    S    11:32   0:00 su www
www      18521  0.0  0.0  23236   968 pts/0    S    11:32   0:00 bash
www      18621 96.3 85.0 3969192 3012596 pts/0 D    11:33  30:08 php run.php -a hourly
www      18659  0.4  0.5 302856 19136 ?        S    11:34   0:08 /usr/sbin/apache2 -k start
www      19431  0.0  0.0  18160  1240 pts/0    R+   12:04   0:00 ps ux

Se for deixado em execução, o processo ainda consumirá recursos, mas não fará nada. Nada mais é registrado.

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
www      18621  9.1 80.0 4030532 2835032 ?     D    11:33  33:19 php run.php -a hourly

Observe que o estado do processo é alterado após exatamente 30 minutos. Ele terá mais ou menos dados processados, dependendo da carga do servidor. Curiosamente, isso só acontece no servidor de produção. Meu servidor de desenvolvimento, o Ubuntu 12.04 também, não tem esse problema.

Existe algo, qualquer coisa que faça com que os processos sejam executados normalmente por um máximo de 30 minutos e, em seguida, altere seu estado para D? O que poderia fazer com que um script PHP acabasse no estado D?

    
por Technoh 22.04.2013 / 00:53

1 resposta

1

Primeiramente, um processo no estado D está em suspensão ininterrupta (geralmente IO) .

Normalmente, o que faz com que um processo seja colocado nesse estado é a execução de uma chamada de sistema de bloqueio .

Você pode ver qual foi a última chamada feita pelo seu processo usando strace :

strace -fp <pid>

Como o estado D geralmente é causado por uma operação IO, também é útil examinar quais arquivos o processo abriu usando lsof :

lsof -p <pid>
    
por 11.10.2013 / 13:38