--- memcache/memcache.inc.orig	2011-11-15 14:17:04.000000000 +1100
+++ memcache/memcache.inc	2012-01-31 18:06:16.000000000 +1100
@@ -31,6 +31,14 @@
  *   'cache_menu', 'cache_page', or 'cache' for the default cache.
  */
 function cache_get($cid, $table = 'cache') {
+  //
+  // set to database path if memcache error detected in the last 60 seconds (todo: configurable?)
+  //
+  $memcache_error = memcache_variable_get('memcache_error', 0);
+  if ($memcache_error && (time() - $memcache_error < 60)) {
+    return _cache_get($cid, $table);
+  }
+
   // Handle excluded bins first.
   $bins = variable_get('memcache_bins', array());
   if (!is_null($table) && isset($bins[$table]) && $bins[$table] == 'database') {
@@ -40,6 +48,14 @@
   // Retrieve the item from the cache.
   $cache = dmemcache_get($cid, $table);
 
+  //
+  // first-time memcache error: database path.
+  //
+  $memcache_error = memcache_variable_get('memcache_error', 0);
+  if ($memcache_error && (time() - $memcache_error < 60)) {
+    return _cache_get($cid, $table);
+  }
+
   // Set up common variables.
   $cache_flush = variable_get("cache_flush_$table", 0);
   $cache_content_flush = variable_get("cache_content_flush_$table", 0);
@@ -171,6 +187,11 @@
  *   A string containing HTTP header information for cached pages.
  */
 function cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
+  $memcache_error = memcache_variable_get('memcache_error', 0);
+  if ($memcache_error && (time() - $memcache_error < 60)) {
+    return _cache_set($cid, $data, $table, $expire, $headers);
+  }
+
   // Handle database fallback first.
   $bins = variable_get('memcache_bins', array());
   if (!is_null($table) && isset($bins[$table]) && $bins[$table] == 'database') {
@@ -426,6 +447,20 @@
 }
 
 /**
+ * Re-implementation of variable_get()
+ */
+function memcache_variable_get($name, $default) {
+  global $conf;
+
+  if (!isset($conf[$name])) {
+    $result      = db_query("SELECT value FROM {variable} WHERE name='%s'", $name);
+    $conf[$name] = ($result) ? unserialize( db_result($result) ) : $default;
+  }
+
+  return $conf[$name];
+}
+
+/**
  * Re-implementation of variable_set() that writes through instead of clearing.
  */
 function memcache_variable_set($name, $value) {
@@ -436,13 +471,28 @@
   if (!db_affected_rows()) {
     @db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, $serialized_value);
   }
+
+  //
+  // use database path if setting memcache_error.
+  //
+  if ($name == "memcache_error") {
+    if ($cached = _cache_get('variables', 'cache')) {
+      $variables        = $cached->data;
+      $variables[$name] = $value;
+      _cache_set('variables', $variables);
+    }
+    $conf[$name] = $value;
+    return;
+  }
+
   // If the variables are cached, get a fresh copy, update with the new value
   // and set it again.
   if ($cached = cache_get('variables', 'cache')) {
-    $variables = $cached->data;
+    $variables        = $cached->data;
     $variables[$name] = $value;
     cache_set('variables', $variables);
   }
+
   // If the variables aren't cached, there's no need to do anything.
   $conf[$name] = $value;
 }
--- memcache/dmemcache.inc.orig	2011-11-15 14:17:04.000000000 +1100
+++ memcache/dmemcache.inc	2012-01-31 17:03:55.000000000 +1100
@@ -109,12 +109,16 @@
 
     if (!empty($php_errormsg)) {
       register_shutdown_function('watchdog', 'memcache', 'Exception caught in dmemcache_get: !msg', array('!msg' => $php_errormsg), WATCHDOG_WARNING);
+      ini_set('track_errors', $track_errors);
+      memcache_variable_set("memcache_error", time());
       $php_errormsg = '';
+      return;
     }
     ini_set('track_errors', $track_errors);
 
     return $result;
   }
+
 }
 
 /**
@@ -339,6 +343,7 @@
       }
       else {
         drupal_set_message('You must enable the PECL memcached or memcache extension to use memcache.inc.', 'error');
+        memcache_variable_set("memcache_error", time());
         return;
       }
 
@@ -355,6 +360,7 @@
 
       // Link all the servers to this cluster.
       foreach ($memcache_servers as $s => $c) {
+
         if ($c == $cluster) {
           list($host, $port) = explode(':', $s);
 
@@ -381,6 +387,15 @@
                 $init = TRUE;
               }
 
+              //
+              // error handling of memcache->connect();
+              //
+              if (!$init) {
+                ini_set('track_errors', $track_errors);
+                memcache_variable_set("memcache_error", time());
+                return FALSE;
+              }
+
               if (!empty($php_errormsg)) {
                 register_shutdown_function('watchdog', 'memcache', 'Exception caught in dmemcache_object: !msg', array('!msg' => $php_errormsg), WATCHDOG_WARNING);
                 $php_errormsg = '';
