core/lib/Drupal/Core/Cache/DatabaseBackend.php | 24 ++++++++++++++++++++++++ core/modules/system/system.install | 11 +++++++++++ 2 files changed, 35 insertions(+) diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php index d53c51c..eaa3b27 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php @@ -17,6 +17,16 @@ class DatabaseBackend implements CacheBackendInterface { /** + * The number of cache items that this cache bin is allowed to store. + * + * @todo Bikeshed the size limit. + * @todo Make configurable per-bin. + * + * @var int + */ + protected static $boundedSizeCount = 1000; + + /** * @var string */ protected $bin; @@ -326,6 +336,14 @@ public function invalidateAll() { */ public function garbageCollection() { try { + // Bounded size cache bin, using FIFO. + $query = $this->connection->select($this->bin); + $query->addExpression('MAX(bounded_id)', 'bounded_id'); + $max_bounded_id = $query->execute()->fetchField(); + $this->connection->delete($this->bin) + ->condition('bounded_id', $max_bounded_id - static::$boundedSizeCount, '<=') + ->execute(); + $this->connection->delete($this->bin) ->condition('expire', Cache::PERMANENT, '<>') ->condition('expire', REQUEST_TIME, '<') @@ -469,11 +487,17 @@ public function schemaDefinition() { 'length' => 255, 'not null' => TRUE, ], + 'bounded_id' => [ + 'type' => 'serial', + ], ], 'indexes' => [ 'expire' => ['expire'], ], 'primary key' => ['cid'], + 'unique keys' => [ + 'bounded_id' => ['bounded_id'], + ] ]; return $schema; } diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 90e6291..e0c9633 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1965,3 +1965,14 @@ function system_update_8400(&$sandbox) { $sandbox['#finished'] = $sandbox['current'] == $sandbox['max']; } + +/** + * Delete all cache_* tables. They are recreated on demand with the new schema. + */ +function system_update_8401() { + foreach (\Drupal\Core\Cache\Cache::getBins() as $bin => $cache_backend) { + if ($cache_backend instanceof \Drupal\Core\Cache\DatabaseBackend) { + db_drop_table("cache_$bin"); + } + } +}