diff -uprN update_status/update_status.install update_status_new/update_status.install
--- update_status/update_status.install	2007-08-15 10:54:00.000000000 -0500
+++ update_status_new/update_status.install	2009-05-09 22:52:30.476243335 -0500
@@ -16,6 +16,7 @@ function update_status_uninstall() {
   foreach ($variables as $variable) {
     variable_del($variable);
   }
+  db_query("DROP TABLE {cache_update}");
   cache_clear_all();
 }
 
@@ -62,3 +63,20 @@ function update_status_update_5202() {
   menu_rebuild();
   return $ret;
 }
+
+/**
+ * Backport cache functionality from 6.x (#155450.)
+ */
+function update_status_update_5203() {
+  $ret = array();
+  $ret[] = update_sql("CREATE TABLE {cache_update} (
+    cid varchar(255) NOT NULL default '',
+    data longblob,
+    expire int(11) NOT NULL default '0',
+    created int(11) NOT NULL default '0',
+    headers text,
+    serialized smallint(6) NOT NULL default '0',
+    PRIMARY KEY (cid)
+  )");
+  return $ret;
+}
diff -uprN update_status/update_status.module update_status_new/update_status.module
--- update_status/update_status.module	2008-08-14 14:01:19.000000000 -0500
+++ update_status_new/update_status.module	2009-05-09 22:47:57.616271201 -0500
@@ -632,7 +632,7 @@ function update_status_get_projects() {
     return $projects;
   }
   // Retrieve the projects from cache, if present.
-  $projects = update_status_project_cache('update_status_projects');
+  $projects = _update_status_cache_get('update_status_projects');
   if (!empty($projects)) {
     return $projects;
   }  
@@ -706,7 +706,7 @@ function update_status_get_projects() {
     }
   }
   asort($projects);
-  cache_set('update_status_projects', 'cache', serialize($projects), time() + (60 * 60));
+  _update_status_cache_set('update_status_projects', serialize($projects), time() + (60 * 60));
   return $projects;
 }
 
@@ -848,7 +848,7 @@ function update_status_process_project_i
 function update_status_calculate_project_data($available) {
 
   // Retrieve the projects from cache, if present.
-  $projects = update_status_project_cache('update_status_data');
+  $projects = _update_status_cache_get('update_status_data');
   // If $projects is empty, then the cache must be rebuilt.
   // Otherwise, return the cached data and skip the rest of the function.
   if (!empty($projects)) {
@@ -1186,7 +1186,7 @@ function update_status_calculate_project
       $projects[$project]['reason'] = t('No available releases found');
     }
   }
-  cache_set('update_status_data', 'cache', serialize($projects), time() + (60 * 60));
+  _update_status_cache_set('update_status_data', serialize($projects), time() + (60 * 60));
   return $projects;
 }
 
@@ -1412,7 +1412,7 @@ function update_status_refresh() {
   if ($data) {
     $parser = new update_status_xml_parser;
     $available = $parser->parse($data);
-    cache_set('update_status_info', 'cache', serialize($available), time() + (60 * 60 * 24));
+    _update_status_cache_set('update_status_info', serialize($available), time() + (60 * 60 * 24));
     variable_set('update_status_last', time());
     watchdog('update_status', t('Fetched information about all available new releases and updates.'), WATCHDOG_NOTICE, l(t('view'), 'admin/logs/updates'));
   }
@@ -1483,7 +1483,7 @@ function update_status_get_available($re
     }
   }
 
-  if (!$needs_refresh && ($cache = cache_get('update_status_info', 'cache'))
+  if (!$needs_refresh && ($cache = _update_status_cache_get('update_status_info'))
       && $cache->expire > time()) {
     $available = unserialize($cache->data);
   }
@@ -1494,13 +1494,6 @@ function update_status_get_available($re
 }
 
 /**
- * Invalidates any cached data relating to update status.
- */
-function update_status_invalidate_cache() {
-  cache_clear_all('update_status_', 'cache', TRUE);
-}
-
-/**
  * XML Parser object to read Drupal's project info files 
  * This uses PHP4's lame XML parsing, but it works. Mostly.
  */
@@ -1612,27 +1605,73 @@ function _update_status_project_status_s
 }
 
 /**
- * Retrieve data from {cache} or empty the cache when necessary.
+ * @defgroup update_status_cache Private update status cache system
+ * @{
+ *
+ * We specifically do NOT use the core cache API for saving the fetched data
+ * about available updates. It is vitally important that this cache is only
+ * cleared when we're populating it after successfully fetching new available
+ * update data. Usage of the core cache API results in all sorts of potential
+ * problems that would result in attempting to fetch available update data all
+ * the time, including if a site has a "minimum cache lifetime" (which is both
+ * a minimum and a maximum) defined, or if a site uses memcache or another
+ * plug-able cache system that assumes volatile caches.
+ *
+ * Update module still uses the {cache_update} table, but instead of using
+ * cache_set(), cache_get(), and cache_clear_all(), there are private helper
+ * functions that implement these same basic tasks but ensure that the cache
+ * is not prematurely cleared, and that the data is always stored in the
+ * database, even if memcache or another cache backend is in use.
+ */
+
+/**
+ * Store data in the private update status cache table.
+ *
+ * Note: this function completely ignores the {cache_update}.headers field
+ * since that is meaningless for the kinds of data we're caching.
+ *
+ * @param $cid
+ *   The cache ID to save the data with.
+ * @param $data
+ *   The data to store.
+ * @param $expire
+ *   One of the following values:
+ *   - CACHE_PERMANENT: Indicates that the item should never be removed except
+ *     by explicitly using _update_cache_clear() or update_invalidate_cache().
+ *   - A Unix timestamp: Indicates that the item should be kept at least until
+ *     the given time, after which it will be invalidated.
+ */
+function _update_status_cache_set($cid, $data, $expire) {
+  $serialized = 0;
+  if (is_object($data) || is_array($data)) {
+    $data = serialize($data);
+    $serialized = 1;
+  }
+  $created = time();
+  db_query("UPDATE {cache_update} SET data = %b, created = %d, expire = %d, serialized = %d WHERE cid = '%s'", $data, $created, $expire, $serialized, $cid);
+  if (!db_affected_rows()) {
+    @db_query("INSERT INTO {cache_update} (cid, data, created, expire, serialized) VALUES ('%s', %b, %d, %d, %d)", $cid, $data, $created, $expire, $serialized);
+  }
+}
+
+/** 
+ * Retrieve data from the private update status cache table.
  *
  * Two very expensive arrays computed by this module are the list of all
  * installed modules (and .info data, project associations, etc), and the
  * current status of the site relative to the currently available
- * releases. These two arrays are cached in the {cache} table and used
+ * releases. These two arrays are cached in the {cache_update} table and used
  * whenever possible. The cache is cleared whenever the administrator visits
  * the status report, available updates report, or the module administration
  * pages, since we should always recompute the most current values on any of
  * those pages.
  *
  * @param $cid
- *   The cache id of data to return from the cache. Valid options are
- *   'update_status_data' and 'update_status_projects'.
- *
+ *   The cache ID to retrieve.
  * @return
- *   The cached value of the $projects array generated by
- *   update_status_calculate_project_data() or update_status_get_projects(),
- *   or an empty array when the cache is cleared.
+ *   The data for the given cache ID, or array() if the ID was not found.
  */
-function update_status_project_cache($cid) {
+function _update_status_cache_get($cid) {
   $projects = array();
 
   // In some cases, we must clear the cache.  Rather than do so on a time
@@ -1640,13 +1679,65 @@ function update_status_project_cache($ci
   $q = $_GET['q'];
   $paths = array('admin/build/modules', 'admin/logs', 'admin/logs/updates', 'admin/logs/status', 'admin/logs/updates/check');
   if (in_array($q, $paths)) {
-    cache_clear_all($cid, 'cache');
+    _update_status_cache_clear($cid);
   }
-  else {
-    $cache = cache_get($cid, 'cache');
-    if (!empty($cache->data) && $cache->expire > time()) {
+
+  $cache = db_fetch_object(db_query("SELECT data, created, expire, serialized FROM {cache_update} WHERE cid = '%s'", $cid));
+  if ($cache->expire > time() && isset($cache->data)) {
+    $cache->data = db_decode_blob($cache->data);
+    if ($cache->serialized) {
       $projects = unserialize($cache->data);
     }
   }
   return $projects;
 }
+
+/**
+ * Invalidates specific cached data relating to update status.
+ *
+ * @param $cid
+ *   Optional cache ID of the record to clear from the private update module
+ *   cache. If empty, all records will be cleared from the table.
+ */
+function _update_status_cache_clear($cid = NULL) { //ALMOST DONE.
+  if (empty($cid)) {
+    db_query("DELETE FROM {cache_update}");
+  }
+  else {
+    db_query("DELETE FROM {cache_update} WHERE cid = '%s'", $cid);
+  }
+}
+
+/**
+ * Implementation of hook_flush_caches().
+ *
+ * Called from update.php (among others) to flush the caches.
+ * Since we're running update.php, we are likely to install a new version of
+ * something, in which case, we want to check for available update data again.
+ * However, because we have our own caching system, we need to directly clear
+ * the database table ourselves at this point and return nothing, for example,
+ * on sites that use memcache where cache_clear_all() won't know how to purge
+ * this data.
+ *
+ * However, we only want to do this from update.php, since otherwise, we'd
+ * lose all the available update data on every cron run. So, we specifically
+ * check if the site is in MAINTENANCE_MODE == 'update' (which indicates
+ * update.php is running, not update module... alas for overloaded names).
+ */
+function update_status_flush_caches() {
+  if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
+    _update_status_cache_clear();
+  }
+  return array();
+}
+
+/**
+ * Invalidates all cached data relating to update status.
+ */
+function update_status_invalidate_cache() {
+  _update_status_cache_clear();
+}
+
+/**
+ * @} End of "defgroup update_status_cache".
+ */
