After upgrading from 7.x-1.2 to 7.x-1.3 I get the following error which completely breaks the site, including Drush:

Error: Call to undefined function lock_acquire() in memcache.inc, line 147

Reverting to 7.x-1.2 fixes the problem. We are not using stampede protection.

Comments

scott.whittaker’s picture

Issue summary: View changes
dmsmidt’s picture

Same here with Drupal 7.34

Jeremy’s picture

Issue tags: +7.x-1.4 blocker

Tagging to review and fix in the next release.

Jeremy’s picture

Status: Active » Postponed (maintainer needs more info)

I'm not seeing how this would happen, and I'm unable to duplicate. Here's the code in question from 7.x-1.3, broken out to make it more clear what's happening:

if (variable_get('memcache_stampede_protection', FALSE)) {
  if ($this->lockInit()) {
    if (!lock_acquire("memcache_$cid:$this->bin", variable_get('memcache_stampede_semaphore', 15))) {
    }
  }
}

And, lockInit() does this:

  public function lockInit() {
    // On a cache miss when page_cache_without_database is enabled, we can end
    // up here without the lock system being initialized. Bootstrap drupal far
    // enough to load the lock system.
    if (!function_exists('lock_acquire')) {
      drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES, FALSE);
    }

    return TRUE;
  }

Please share your relevant settings.php configuration. There must be something nonstandard about your installation, but offhand I'm not sure what it would be. Are there any other errors/warnings/notices?

marcvangend’s picture

I'm getting the same error in some cases. It seems like the rebuilding of caches it too heavy, so the stampede protection kicks in.

This is the memcached config in settings.php:

$conf['cache_backends'][] = 'sites/all/modules/contrib/memcache/memcache.inc';
$conf['memcache_key_prefix'] = 'wb';
$conf['lock_inc'] = 'sites/all/modules/contrib/memcache/memcache-lock.inc';
$conf['memcache_stampede_protection'] = TRUE;
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['memcache_servers'] = array('localhost:11211' => 'default');
// Always database cache
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
// Don't bootstrap the database when serving pages from the cache.
$conf['page_cache_without_database'] = TRUE;
$conf['page_cache_invoke_hooks'] = FALSE;

Other details:
- memcache 7.x-1.3
- memcached 1.4.21 (started with /usr/bin/memcached -l 127.0.0.1 -m 512)
- memcached php module 2.2.0
- libmemcached 1.0.18
- PHP Version 5.6.3

I'm testing with a clean install, "minimal" profile, with the memcache module as the only addition.

I only get the error when memcache_stampede_protection == TRUE and I have just cleared the cache (drush cc all).
If I just keep memcache_stampede_protection set to FALSE, the site always loads as expected.
When I clear the cache, set memcache_stampede_protection to FALSE, load the front page once (no errors), and set memcache_stampede_protection back to TRUE, the site keeps working.

willeaton’s picture

I got this when I had authcache enabled. Basically the lock file is called in at the database bootstrap level. If the page is loaded at the fastcache bootstrap level and that system does a cache_get then it gives that error because it hasn't yet loaded that file. I had to modify bootstrap or authcache to load the file.

  • Jeremy committed 35e4778 on 7.x-1.x
    Issue #2376391: Call to undefined function lock_acquire()
    
Jeremy’s picture

Status: Postponed (maintainer needs more info) » Fixed

It seems the only way this could happen is if the bootstrap fails in lockInit(), so we now check if this happens and if so we return FALSE and log an error. @Catch noted that this could be caused by https://www.drupal.org/node/667098 .

marcvangend’s picture

Status: Fixed » Closed (fixed)

Thank you Jeremy, 7.x-1.4-rc1 indeed solves the problem described in #5.

PS . I'm setting this issue to "Closed (fixed)" because it would be auto-closed today if I didn't post this comment.

SocialNicheGuru’s picture

@willeaton how did you modify bootstrap and authcache to load the file?

willeaton’s picture

I just added an include_once to the missing file in the fastcache level of bootstrap. In fact Ive since turned off the stampede protection as it seemed to create more load

SocialNicheGuru’s picture

which file, line did you add the include to?

Sneakyvv’s picture

Version: 7.x-1.3 » 7.x-1.5
Status: Closed (fixed) » Needs work

I just had a similar problem. In my case the bootstrap sequence could not complete because

if (!function_exists('lock_acquire')) {
      // Bootstrap failed, log error.
      register_shutdown_function('watchdog', 'memcache', 'Bootstrap failed in lockInit(), lock_acquire() is not available. (phase:!phase)', array('!phase' => drupal_get_bootstrap_phase(NULL, FALSE)), WATCHDOG_ERROR);
      return FALSE;
    }

register_shutdown_function is calling drupal_get_bootstrap_phase(). As Jeremy mentioned, #667098: drupal_get_bootstrap_phase() is broken is the reason why this function is killing the bootstrap.

I've been debugging this, but not to the root cause. I kinda got tired of the recursions. However, what I noticed, and think is happening is this...

During the DRUPAL_BOOTSTRAP_VARIABLES phase, _drupal_bootstrap_variables() is executed. In this function memcache-lock.inc is being loaded. This file calls dmemcache_object(), and somewhere during the execution of this function we end up in lockInit() in memcache.inc. This file expects lock_acquire to exist. If it doesn't exist, it calls the bootstrap() function, with DRUPAL_BOOTSTRAP_VARIABLES.

if (!function_exists('lock_acquire')) {
  drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES, FALSE);
}

This is the actual problem in my opinion. Since the DRUPAL_BOOTSTRAP_VARIABLES bootstrap phase is called DURING a bootstrap sequence, the attempt of memcache.inc to run bootstrap() again, results in bootstrap() doing nothing, since the DRUPAL_BOOTSTRAP_VARIABLES phase has already completed. Actually it is right in the middle of that phase, to be precise. Since that phase has not fully completed, I guess, the lock_acquire function does not exist. Perhaps it would exist if the DRUPAL_BOOTSTRAP_VARIABLES phase finishes.

Nevertheless, the fact that the function still does not exist, after memcache attempt to bootstrap DRUPAL_BOOTSTRAP_VARIABLES again (which did nothing), it's going to write a watchdog message with the drupal_get_bootstrap_phase() as a parameter. Which breaks the whole bootstrap sequence.

Ok, granted, the core function drupal_get_bootstrap_phase is incorrect. That's a fact. But perhaps the fact that memcache is trying to call the bootstrap during a bootstrap sequence, actually the same phase it is currently bootstrapping, might be, and possible is, wrong as well.

markbannister’s picture

I doubt this helps anyone but I had some bizarre errors going on trying to turn on memcache on a multi-site. I had several configuration settings wrong, and I had to uninstall/reinstall a few times -- but I thought I had it all straight and then I would get the lock_acquire() error message "WD memcache: Bootstrap failed in lockInit(), lock_acquire() is not available. (phase:3)". I then disabled stampede protection, cleared caches, and re-enabled and everything seems ok.

DamienMcKenna’s picture

I'm still having problems after trying the steps @markbannister suggested. FYI I'm using the memcached plugin with PHP 5.6.6 on MAMP 3.1 on OSX Yosemite.

david.lukac’s picture

I'm getting the same error with Drupal 7.43, memcache module 7.x-1.5, stampede protection either ON or OFF - getting the "WD memcache: Bootstrap failed in lockInit(), lock_acquire() is not available. (phase:3)" in both cases. Clearing the caches and enabling/disabling stampede protection doesn't solve the issue - it always re-occurs after short time.

UPDATE: Looking into code, lock_init() is always called only when stampede protection, so turning stampede protection OFF and clearing caches gets rid off the error.

kenorb’s picture

It's a bit weird issue.

When I add var_dump() in memcache-lock-code.inc file, e.g.

var_dump('foo');
function lock_acquire($name, $timeout = 30) {

then I've got this error:

$ time drush -y ev ''
WD memcache: Bootstrap failed in lockInit(), lock_acquire() is not available. (phase:3)     

and secondly all dumps on the screen are ignored, like the files weren't parsed at all (ob_cache, cached file?).

However when I just add die() like:

var_dump('foo'); die();

then it works (the message from var_dump is printed on the terminal) and there is no warning.

Jeremy’s picture

I've finally duplicated this by installing PECL Memcached version 3.0.2. It may be related to #2849151: php-memcached 3.0.0 reverts method signature of get, getByKey, getMulti, and getMultiByKey .

  • Jeremy committed 05a9903 on 7.x-1.x authored by JStanton
    Issue #2376391 by Jeremy, marco: Call to undefined function lock_acquire...
Jeremy’s picture

Status: Needs work » Fixed

This only seems to happen with the PECL Memcached extension, not with the PECL Memcache extension. It also only happens when Stampede Protection is enabled.

Using the new debug logging built into the module, with PECL Memcache we see:

1487303942|get|cache_bootstrap|cache_bootstrap-variables|1
1487303942|get|cache_bootstrap|cache_bootstrap-bootstrap_modules|1
1487303942|get|cache_bootstrap|cache_bootstrap-lookup_cache|1
1487303942|get|cache_bootstrap|cache_bootstrap-system_list|1
1487303942|get|cache_bootstrap|cache_bootstrap-module_implements|1
1487303942|get|cache_bootstrap|cache_bootstrap-hook_info|1
1487303942|get|cache|cache-imageapi_optimize%3Amethods|1
1487303942|get|cache|cache-entity_info%3Aen|1
1487303942|getMulti|cache|cache-.wildcard-entity_info%3A|1
1487303942|getMulti|cache_field|cache_field-field%3Auser%3A0|1

Whereas with PECL Memcached we see:

1487303904|get|cache_bootstrap|cache_bootstrap-lookup_cache|1
1487303904|get|cache_bootstrap|cache_bootstrap-variables|1
1487303904|get|cache_bootstrap|cache_bootstrap-bootstrap_modules|1
1487303905|get|cache_bootstrap|cache_bootstrap-system_list|1
1487303905|get|cache_bootstrap|cache_bootstrap-module_implements|1
1487303905|get|cache_bootstrap|cache_bootstrap-hook_info|1
1487303905|get|cache|cache-imageapi_optimize%3Amethods|1
1487303905|get|cache|cache-entity_info%3Aen|1
1487303905|getMulti|cache|cache-.wildcard-entity_info%3A|1
1487303905|getMulti|cache_field|cache_field-field%3Auser%3A0|1

From a backtrace we see that there's an autoload being triggered for Memcached. Digging in further, Marco noticed that class_exists('Memcached') has an option to avoid triggering an autoload. I'm not sure (yet) why this only seems to happen for Memcached, in any case, committed a fix that consistently prevents this.

  • Jeremy committed 4e015d0 on 7.x-1.x
    Revert "Issue #2376391 by Jeremy, marco: Call to undefined function...
  • Jeremy committed 666a460 on 7.x-1.x authored by marco
    Issue #2376391 by Jeremy, marco: Call to undefined function lock_acquire...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

Jeremy’s picture

Version: 7.x-1.5 » 6.x-1.x-dev
Status: Closed (fixed) » Patch (to be ported)

this also affects 6.x

  • Jeremy committed 9d25898 on 6.x-1.x
    Issue #2376391 by Jeremy: Call to undefined function lock_acquire()
    
kenorb’s picture

Status: Patch (to be ported) » Fixed

Fixed as per #24.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.