diff --git a/includes/cache-install.inc b/includes/cache-install.inc
new file mode 100644
index 0000000..8bcf8b7
--- /dev/null
+++ b/includes/cache-install.inc
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * @file
+ * Provides a stub cache implementation to be used during installation.
+ */
+
+/**
+ * A stub cache implementation to be used during the installation process.
+ *
+ * The stub implementation is needed when database access is not yet available.
+ * Because Drupal's caching system never requires that cached data be present,
+ * these stub functions can short-circuit the process and sidestep the need for
+ * any persistent storage. Obviously, using this cache implementation during
+ * normal operations would have a negative impact on performance.
+ */
+class DrupalFakeCache extends DrupalDatabaseCache implements DrupalCacheInterface {
+  function get($cid) {
+    return FALSE;
+  }
+
+  function getMultiple(&$cids) {
+    return array();
+  }
+
+  function set($cid, $data, $expire = CACHE_PERMANENT) {
+  }
+
+  function deletePrefix($cid) {
+    try {
+      if (class_exists('Database')) {
+        parent::deletePrefix($cid);
+      }
+    }
+    catch (Exception $e) {
+    }
+  }
+
+  function clear($cid = NULL, $wildcard = FALSE) {
+    // If there is a database cache, attempt to clear it whenever possible. The
+    // reason for doing this is that the database cache can accumulate data
+    // during installation due to any full bootstraps that may occur at the
+    // same time (for example, Ajax requests triggered by the installer). If we
+    // didn't try to clear it whenever this function is called, the data in the
+    // cache would become stale; for example, the installer sometimes calls
+    // variable_set(), which updates the {variable} table and then clears the
+    // cache to make sure that the next page request picks up the new value.
+    // Not actually clearing the cache here therefore leads old variables to be
+    // loaded on the first page requests after installation, which can cause
+    // subtle bugs, some of which would not be fixed unless the site
+    // administrator cleared the cache manually.
+    try {
+      if (class_exists('Database')) {
+        parent::clear($cid, $wildcard);
+      }
+    }
+    // If the attempt at clearing the cache causes an error, that means that
+    // either the database connection is not set up yet or the relevant cache
+    // table in the database has not yet been created, so we can safely do
+    // nothing here.
+    catch (Exception $e) {
+    }
+  }
+
+  function isEmpty() {
+    return TRUE;
+  }
+}
diff --git a/includes/cache.inc b/includes/cache.inc
index caa5c03..7226c20 100644
--- a/includes/cache.inc
+++ b/includes/cache.inc
@@ -20,8 +20,9 @@ function cache($bin = 'cache') {
   // bin names to be passed as arguments.
   $bin = str_replace('cache_', '', $bin);
 
-  $cache_objects = &drupal_static('cache_objects', array());
-
+  // We do not use drupal_static() here because we do not want to change the
+  // storage of a cache bin mid-request.
+  static $cache_objects;
   if (!isset($cache_objects[$bin])) {
     $class = variable_get('cache_class_' . $bin);
     if (!isset($class)) {
diff --git a/includes/install.core.inc b/includes/install.core.inc
index 60a2ad2..7405f9f 100644
--- a/includes/install.core.inc
+++ b/includes/install.core.inc
@@ -272,7 +272,8 @@ function install_begin_request(&$install_state) {
   // because any data put in the cache during the installer is inherently
   // suspect, due to the fact that Drupal is not fully set up yet.
   require_once DRUPAL_ROOT . '/includes/cache.inc';
-  $conf['cache_default_class'] = 'DrupalNullCache';
+  require_once DRUPAL_ROOT . '/includes/cache-install.inc';
+  $conf['cache_default_class'] = 'DrupalFakeCache';
 
   // Prepare for themed output. We need to run this at the beginning of the
   // page request to avoid a different theme accidentally getting set. (We also
@@ -1513,14 +1514,9 @@ function install_finished(&$install_state) {
   $output = '<p>' . st('Congratulations, you installed @drupal!', array('@drupal' => drupal_install_profile_distribution_name())) . '</p>';
   $output .= '<p>' . (isset($messages['error']) ? st('Review the messages above before visiting <a href="@url">your new site</a>.', array('@url' => url(''))) : st('<a href="@url">Visit your new site</a>.', array('@url' => url('')))) . '</p>';
 
-  // Now that the install is completed, allow the default cache backend to be
-  // used. DrupalNullCache must be used up to this point to avoid cached data
-  // from the partially installed site being stored. The cache clear here
-  // ensures that any data cached from AJAX requests to the site which are
-  // outside of the install environment will also be cleared.
-  global $conf;
-  unset($conf['cache_default_class']);
-  drupal_static_reset('cache_objects');
+  // Flush all caches to ensure that any full bootstraps during the installer
+  // do not leave stale cached data, and that any content types or other items
+  // registered by the install profile are registered correctly.
   drupal_flush_all_caches();
 
   // Remember the profile which was used.
