Details
Description
It is possible for backup_log_info() (called from cron.php) to get into a (potentially) infinite loop when iterating over the logs. This can happen when one or more old log entries are deleted by another invocation of cron.php between the time when the current number of logs is determined by this line:
$count_logs = count_records("log","course",$preferences->backup_course);
and when the test to terminate the loop ("while ($counter < $count_logs)") is made and which should cause termination. If some logs have been deleted, the final call to get_records() may not return enough logs for the counter to equal $count_logs.
I first identified and described this problem (without knowing the cause) here: http://moodle.org/mod/forum/discuss.php?d=50467#238903
The following patch should fix the problem, but recognising that if get_records() doesn't return anything, then it's time to stop.
-
-
- backuplib.php.orig Mon Jan 15 13:13:38 2007
- backuplib.php Thu Apr 5 16:40:03 2007
***************
- 1308,1313 ****
- 1308,1317 ----
backup_flush(300);
}
}
+ } else { + //No logs -- old ones were deleted by a different cron.php + //execution; break to avoid potentially infinite loop + break; }
}
//End logs tag
-
I haven't yet had a chance to verify that this fix works. As this problem does not occur every single time backup_log_info(), a test case would need to be created.
Looks like this is what happened to us. Backups started at midnight and I caught this query still running over and over this morning (at 10am). It was seriously affecting performance of the server. I killed the cron job.
SELECT * FROM mdl_log WHERE course = '331' ORDER BY time LIMIT 108276,1000;
We're on Moodle 1.9.5.
We need a database-based check that there is no cron job running before a new cron starts.