After updating to 8.2.1 from 8.1.10 on our Acquia Cloud based site, the log files began filling with error like:
Warning: apcu_store(): Unable to allocate memory for pool. in Drupal\Core\Cache\ApcuBackend->set()...
The settings.conf initially had memcache (dev branch which works with Acquia) configure with:
$settings['memcache']['servers'] = $conf['memcache_servers'];
$settings['memcache']['key_prefix'] = $conf['memcache_key_prefix'];
$settings['memcache']['bins'] = ['default' => 'default'];
// Use memcache as the default bin
$settings['cache']['default'] = 'cache.backend.memcache';
In debugging, this was converted to just:
$settings['cache']['default'] = 'cache.backend.database';
This did not stop the errors.
Notes:
- Acquia Cloud has apcu enabled but only allocates 8M to it.
- The error did not immediately appear after clearing cache but only after some normal web access (multiple users).
- Once it started, any request would start creating multiple entries in the log.
The expected behavior is what is documented in the Cache Api Configuration documentation. This says the settings default cache method should be used and not ChainedFastCache which uses APCu.
A way to "reproduce" this, is to just make the cache.backend.database mechanism the default in a Dev site's settings.php. Then run the following code in the devel php page (assumes devel / kint modules enabled):
kint(Drupal::cache('bootstrap'));
This will show that the cache class used is the ChainedFastCache class and not the expected DB Cache class.
The source of this problem was tracked down to the logic change made in the CacheFactory code for this issue:
CacheFactory::get() should not use default cache backend before cache bin defaults
This makes it so the settings file cannot override the default_backend service settings. This is not the documented behaviour.
The 'quick' fix for this was to define the cache mechanisms for each specific bin in addition to the default one. E.g.:
# https://docs.acquia.com/article/drupal-8-cache-backend
$settings['cache']['default'] = 'cache.backend.database';
# Force common chainedfast bins to use database.
$settings['cache']['bins']['discovery'] = 'cache.backend.database';
$settings['cache']['bins']['bootstrap'] = 'cache.backend.database';
$settings['cache']['bins']['render'] = 'cache.backend.database';
$settings['cache']['bins']['data'] = 'cache.backend.database';
$settings['cache']['bins']['config'] = 'cache.backend.database';
Not sure if the best solution is to roll back the logic change in the CacheFactory or update the documentation.