2012-03-01 4 views
5

29分実行後に失敗したPHP cronジョブがあります。ログ(/var/log/php_errors.log)に誤りがある:最大実行時間の致命的なエラーによるPHP cronジョブの早すぎる終了

[01-Mar-2012 00:32:57 UTC] PHP Fatal error: Maximum execution time of 60 seconds exceeded in /path/file.php on line 2079 

のcronをトリガーcrontabエントリは次のとおりです。私の研究から

00 00 * * * /usr/bin/php /path/file.php 

私はこれがためmax_execution_timeコンフィグ設定に関連しているとは思いません:

  1. 実際には29分18秒(つまり、エラーメッセージのような60分以上)実行されています。 the PHP docsから
  2. - PHPをコマンドラインから実行する場合、デフォルトの設定は0

Qです:なぜスクリプトが早期に終了していますか?


注:

スクリプトは非常に重く、DBクエリの何千もを実行しないが、私はtopを実行していたし、CPUの負荷が高くありませんでした。

エラー・ログから行がmysql_query呼び出しです:

$sql = "SELECT SUM(amount) FROM mytab WHERE mem = '$id' AND validto > '$now'"; 
$res = mysql_query($sql); 

> php -v 
PHP 5.3.10 (cli) (built: Feb 2 2012 17:34:38) 
Copyright (c) 1997-2012 The PHP Group 
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies 
    with Suhosin v0.9.33, Copyright (c) 2007-2012, by SektionEins GmbH 

> cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 5.7 (Tikanga) 

更新 - スクリプトはリアルタイムの29分間実行することができますなぜ私が見つかりましたが、 PHPは引用実行時間をずっと短縮することができます。

system()、ストリーム操作、データベースクエリなどを使用したシステムコールなど、スクリプトの実行以外で発生するアクティビティに費やされる時間は、スクリプトが実行された最大時間。

the set_time_limit() docsよりも、the max-execution-time docsでも言及されている)。これは、スクリプトの大部分が、実行時間のクロッキングを行わないdbクエリと支払いAPI呼び出しを長時間実行していたため、私にとっては関係がありました。

+1

cronジョブはエラーとは何の関係もありません。これはPHPの純粋な問題です。メモリリークをチェックし、ループを実行した後にバグ配列の一部を解除しようとします。クエリ間に他の大きな変数を設定します。 –

+0

また、ドキュメントには以下のことが書かれています。_最大実行時間はシステムコール、ストリーム操作などの影響を受けません。 cronによって起動されたPHP _CLI_であることを確認できますか? –

+0

また、選択を高速化するのに適したインデックスがあることを確認します。 *** mem ***と*** validto ***のインデックスを持っていますか? –

答えて

1

あなたが確かに、その後PHP Fatal error: Maximum execution time of 60 seconds exceededを取得した場合、PHPのコードを実行しているいくつかの作品は、どこかの文set_time_limit(60)を実行します。 PHPのCLIモードでは、デフォルトでタイムアウトがないことがありますが、の場合、のコードパスで期限が設定されていれば、それが適用されます。 PHPが半時間近く実行された理由は、set_time_limitがCPU時間の制限を設定し、プロセスがI/Oが制限されているか、他のプロセスを待っている場合は、CPU使用量の合計がリアルタイムクロック。

set_time_limitのソースコードをすべて検索してみてください。何も見つからない場合は、スクリプトの最初にset_time_limit(0)を追加して、60秒の制限がローカルに変更された構成ファイルから来ないことを確認します。たとえば、Ubuntu LTSではPHP CLIの設定は/etc/php5/cli/php.iniで定義されています。

+0

感謝します。 'set_time_limit'の役に立つ情報が問題を明らかにしました。 – Tom

2

さて、あなたは、時間制限のために大きな値を設定することもできますし、set-time-limit()を使用して無制限に設定できます。

<?php set_time_limit(0); ?> 

けどacctually私は、スクリプト

ignore_user_abort(1); 
1
の開始時に、あまりにもこれを使用します

残念ながら私はコメントを書くことができないので、ここで私の質問は、あなたがこれを手動で実行するとどうなるでしょうか?それはまたタイムアウトになりますか?

手動で実行するときにタイムアウトしない場合は、実際にシェルを実行し、 "/ usr/bin/php /path/file.php"を実行する小さなシェルスクリプトを呼び出すことをお勧めしますシェル。

00 00 * * * /usr/local/scripts/start_php_job.sh

File: /usr/local/scripts/start_php_job.sh 
#!/usr/bin/bash 
date 

/usr/local/bin/php /path/to/script 

date 
+0

ありがとうございます。コマンドラインから手動で実行しようとしましたが、cron経由で自動的にトリガされたときと同じエラーが発生しました。 – Tom

+1

実行中にメモリ消費量を記録できますか?あなたの "リソース制限(ulimit -a)は何ですか?私はこれがちょうど停止すれば、バッファキャッシュはユーザの最大mem使用量、SQLサーバ最大mem使用量、またはシステムRAM量が最大に達すると仮定します。 ps -uef(私はこれもメモリを示すものだと思います)とあなたのプロセスをgrepすることをお勧めします。5秒ごとにこれを行います。上記のようなシェルスクリプトで、echo $?によってエラーコードを得ることができます。それが表示されます。多分もっとヒントを与えます。 –

関連する問題