Drupal Tip: Forcing cron to get un-stuck
I just wasted the better part of an hour trying to troubleshoot a "cron run failed" error on one of my Drupal sites (oddly, only one of four was affected). Trying to run cron manually from the status page gives a "cron run failed" error, and looking at the "Recent log entries" (aka watchdog, apparently) showed a message "Attempting to re-run cron while it is already running".
I did a bit of searching for a resolution to this, there is a bit of discussion about this on the main Drupal site, and at least one other site. You will notice in both places, that a suggested fix is to use phpMyAdmin to manually delete the "cron_semaphore" and "cron_last" from the variables table.
cron_semaphore is, indeed the culprit, but in my case, deleting the cron_semaphore from the database did not help. All I can think of, is that the database query result was being cached s.t. even though cron_semaphore was not set in the database, PHP was still picking it up. To fix this, what I ended up doing was temporarily modifying common.inc drupal_cron_run() to disable the semaphore entirely:
// Fetch the cron semaphore
//$semaphore = variable_get('cron_semaphore', FALSE);
$semaphore = FALSE;
Making this change disables the semaphore mechanism entirely and allows cron to run. After doing this, I checked the variables table and sure enough the cron_last variable could be seen to be updated. I then re-enabled the semaphore (put the original common.inc back) and so far, everything seems to be o.k.
Note that some of you reading this might be tempted to just leave the semaphore disabled. And if you can be 100% certain you'll never get two crons running at the same time, it is probably safe to do so. I wouldn't recommend it though; instead, think of this as an emergency measure to get the cron_semaphore un-stuck when doing so using the database method doesn't work.