diff --git a/.htaccess b/.htaccess
index a69bdd4..2a2690c 100644
--- a/.htaccess
+++ b/.htaccess
@@ -95,7 +95,7 @@ DirectoryIndex index.php index.html index.htm
   #
   # If your site is running in a VirtualDocumentRoot at http://example.com/,
   # uncomment the following line:
-  # RewriteBase /
+  RewriteBase /
 
   # Redirect common PHP files to their new locations.
   RewriteCond %{REQUEST_URI} ^(.*)?/(update.php) [OR]
diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
index 73c7139..850368f 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
@@ -48,9 +48,6 @@ class DatabaseBackend implements CacheBackendInterface {
    */
   function getMultiple(&$cids) {
     try {
-      // Garbage collection necessary when enforcing a minimum cache lifetime.
-      $this->garbageCollection($this->bin);
-
       // When serving cached pages, the overhead of using db_select() was found
       // to add around 30% overhead to the request. Since $this->bin is a
       // variable, this means the call to db_query() here uses a concatenated
@@ -185,30 +182,29 @@ class DatabaseBackend implements CacheBackendInterface {
    * Implements Drupal\Core\Cache\CacheBackendInterface::expire().
    */
   function expire() {
-    if (variable_get('cache_lifetime', 0)) {
+    $config = config('system.performance');
+    if ($cache_lifetime = $config->get('cache_lifetime')) {
       // We store the time in the current user's $user->cache variable which
       // will be saved into the sessions bin by _drupal_session_write(). We then
       // simulate that the cache was flushed for this user by not returning
       // cached data that was cached before the timestamp.
       $GLOBALS['user']->cache = REQUEST_TIME;
 
-      $cache_flush = variable_get('cache_flush_' . $this->bin, 0);
-      if ($cache_flush == 0) {
-        // This is the first request to clear the cache, start a timer.
-        variable_set('cache_flush_' . $this->bin, REQUEST_TIME);
-      }
-      elseif (REQUEST_TIME > ($cache_flush + variable_get('cache_lifetime', 0))) {
-        // Clear the cache for everyone; cache_lifetime seconds have passed
-        // since the first request to clear the cache.
-        db_delete($this->bin)
-          ->condition('expire', CACHE_PERMANENT, '<>')
-          ->condition('expire', REQUEST_TIME, '<')
-          ->execute();
-        variable_set('cache_flush_' . $this->bin, 0);
-      }
+      // Clear expired items from the cache.
+      db_delete($this->bin)
+        ->condition('expire', CACHE_PERMANENT, '>')
+        ->condition('expire', REQUEST_TIME, '<')
+        ->execute();
+      variable_set('cache_flush_' . $this->bin, 0);
+
+      // Clear CACHE_TEMPORARY items that are older than the minimum cache lifetime.
+      db_delete($this->bin)
+        ->condition('expire', CACHE_TEMPORARY)
+        ->condition('created', REQUEST_TIME - $cache_lifetime, '<')
+        ->execute();
     }
     else {
-      // No minimum cache lifetime, flush all temporary cache entries now.
+      // No minimum cache lifetime, flush all expired and temporary cache entries now.
       db_delete($this->bin)
         ->condition('expire', CACHE_PERMANENT, '<>')
         ->condition('expire', REQUEST_TIME, '<')
@@ -220,20 +216,24 @@ class DatabaseBackend implements CacheBackendInterface {
    * Implements Drupal\Core\Cache\CacheBackendInterface::garbageCollection().
    */
   function garbageCollection() {
-    global $user;
+    $config = config('system.performance');
 
-    // When cache lifetime is in force, avoid running garbage collection too
-    // often since this will remove temporary cache items indiscriminately.
-    $cache_flush = variable_get('cache_flush_' . $this->bin, 0);
-    if ($cache_flush && ($cache_flush + variable_get('cache_lifetime', 0) <= REQUEST_TIME)) {
-      // Reset the variable immediately to prevent a meltdown in heavy load situations.
-      variable_set('cache_flush_' . $this->bin, 0);
-      // Time to flush old cache data
-      db_delete($this->bin)
-        ->condition('expire', CACHE_PERMANENT, '<>')
-        ->condition('expire', $cache_flush, '<=')
-        ->execute();
-    }
+
+    // Clear expired items from the cache.
+    db_delete($this->bin)
+      ->condition('expire', CACHE_PERMANENT, '>')
+      ->condition('expire', REQUEST_TIME, '<')
+      ->execute();
+
+    // Clear old temporary cache items, 'old' is defined as older than the
+    // minimum cache lifetime, or 24 hours, whichever is the greatest.
+    $old = max($config->get('cache_lifetime'), 86400);
+
+    // Clear CACHE_TEMPORARY items that are older than the minimum cache lifetime.
+    db_delete($this->bin)
+      ->condition('expire', CACHE_TEMPORARY)
+      ->condition('created', REQUEST_TIME - $old, '<')
+      ->execute();
   }
 
   /**
diff --git a/core/modules/simpletest/tests/cache.test b/core/modules/simpletest/tests/cache.test
index 81f2377..846fb32 100644
--- a/core/modules/simpletest/tests/cache.test
+++ b/core/modules/simpletest/tests/cache.test
@@ -317,6 +317,41 @@ class CacheClearCase extends CacheTestCase {
   }
 
   /**
+   * Test CACHE_TEMPORARY behaviour.
+   */
+  function testCacheTemporary() {
+    $cache = cache($this->default_bin);
+    // Set a permanent and temporary cache item.
+    $cache->set('test_cid_clear1', $this->default_value, CACHE_TEMPORARY);
+    $cache->set('test_cid_clear2', $this->default_value);
+    $this->assertTrue($this->checkCacheExists('test_cid_clear1', $this->default_value));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear2', $this->default_value));
+
+    // Expire all items in the bin, only the temporary item should be removed.
+    $cache->expire();
+    $this->assertFalse($this->checkCacheExists('test_cid_clear1', $this->default_value));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear2', $this->default_value));
+
+    // Set the temporary item again.
+    $cache->set('test_cid_clear1', $this->default_value, CACHE_TEMPORARY);
+
+    // Now call the garbageCollection method, neither item should be removed.
+    $cache->garbageCollection();
+    $this->assertTrue($this->checkCacheExists('test_cid_clear1', $this->default_value));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear2', $this->default_value));
+
+    // Set a minimum cache lifetime.
+    $cache->set('test_cid_clear1', $this->default_value, CACHE_TEMPORARY);
+    $this->setUpLifetime(300);
+
+    // Now after expiring the bin, neither the temporary nor permanent item
+    // should be removed.
+    $cache->expire();
+    $this->assertTrue($this->checkCacheExists('test_cid_clear1', $this->default_value));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear2', $this->default_value));
+  }
+
+  /**
    * Test drupal_flush_all_caches().
    */
   function testFlushAllCaches() {
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 14d4853..9379ce8 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -682,7 +682,7 @@ function system_schema() {
       ),
     ),
     'indexes' => array(
-      'expire' => array('expire'),
+      'expire_created' => array('expire', 'created'),
     ),
     'primary key' => array('cid'),
   );
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 94fd3e0..833d2da 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -3056,7 +3056,7 @@ function system_cron() {
   $core = array('cache', 'path', 'filter', 'page', 'form', 'menu');
   $cache_bins = array_merge(module_invoke_all('flush_caches'), $core);
   foreach ($cache_bins as $bin) {
-    cache($bin)->expire();
+    cache($bin)->garbageCollection();
   }
 
   // Cleanup the batch table and the queue for failed batches.
