diff --git a/core/lib/Drupal/Core/Cache/ApcuBackend.php b/core/lib/Drupal/Core/Cache/ApcuBackend.php
index ffaeba3..b8a31be 100644
--- a/core/lib/Drupal/Core/Cache/ApcuBackend.php
+++ b/core/lib/Drupal/Core/Cache/ApcuBackend.php
@@ -204,9 +204,12 @@ public function set($cid, $data, $expire = CacheBackendInterface::CACHE_PERMANEN
     // until the next cache clear, restart, etc. This is what we want to do
     // when $expire equals CacheBackendInterface::CACHE_PERMANENT.
     if ($expire === CacheBackendInterface::CACHE_PERMANENT) {
-      $expire = 0;
+      $ttl = 0;
     }
-    apc_store($this->getApcuKey($cid), $cache, $expire);
+    else {
+      $ttl = max(1, $expire - REQUEST_TIME);
+    }
+    apc_store($this->getApcuKey($cid), $cache, $ttl);
   }
 
   /**
@@ -236,7 +239,7 @@ public function deleteMultiple(array $cids) {
    * {@inheritdoc}
    */
   public function deleteAll() {
-    apc_delete(new \APCIterator('user', '/^' . preg_quote($this->binPrefix, '/') . '/'));
+    apc_delete($this->getAll());
   }
 
   /**
@@ -272,7 +275,8 @@ public function invalidate($cid) {
    */
   public function invalidateMultiple(array $cids) {
     foreach ($this->getMultiple($cids) as $cache) {
-      $this->set($cache->cid, $cache, REQUEST_TIME - 1);
+      $cache->expire = REQUEST_TIME - 1;
+      apc_store($this->getApcuKey($cache->cid), $cache, 1);
     }
   }
 
@@ -281,8 +285,8 @@ public function invalidateMultiple(array $cids) {
    */
   public function invalidateAll() {
     foreach ($this->getAll() as $data) {
-      $cid = str_replace($this->binPrefix, '', $data['key']);
-      $this->set($cid, $data['value'], REQUEST_TIME - 1);
+      $data['value']->expire = REQUEST_TIME - 1;
+      apc_store($data['key'], $data['value'], 1);
     }
   }
 
@@ -295,6 +299,7 @@ public function deleteTags(array $tags) {
       if (!$success) {
         apc_store($this->deletionsTagsPrefix . $tag, 1);
       }
+      unset(static::$tagCache['deletions'][$tag]);
     }
   }
 
@@ -307,6 +312,7 @@ public function invalidateTags(array $tags) {
       if (!$success) {
         apc_store($this->invalidationsTagsPrefix . $tag, 1);
       }
+      unset(static::$tagCache['invalidations'][$tag]);
     }
   }
 
@@ -364,9 +370,13 @@ protected function checksumTags(array $tags) {
 
     foreach (array('deletions', 'invalidations') as $type) {
       if ($query_tags[$type]) {
+        $prefix_length = strlen($this->{$type . 'TagsPrefix'});
         $result = apc_fetch($query_tags[$type]);
-        static::$tagCache[$type] = array_merge(static::$tagCache[$type], $result);
-        $checksum[$type] += array_sum($result);
+        foreach ($result as $key => $value) {
+          $tag = substr($key, $prefix_length);
+          static::$tagCache[$type][$tag] = $value;
+          $checksum[$type] += $value;
+        }
       }
     }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php
index 5df23c9..1a9640d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php
@@ -508,6 +508,10 @@ function testInvalidate() {
     $cids = $reference;
     $ret = $backend->getMultiple($cids, TRUE);
     $this->assertEqual(count($ret), 4, 'Four items returned.');
+    // Test that calling invalidate() does not change data.
+    $this->assertIdentical($ret['test1']->data, 1);
+    // Test that calling invalidateMultiple() does not change data.
+    $this->assertIdentical($ret['test2']->data, 2);
   }
 
   /**
@@ -589,6 +593,8 @@ public function testInvalidateAll() {
     $this->assertTrue($unrelated->get('test3'), 'Item in other bin is preserved.');
     $this->assertTrue($backend->get('test1', TRUE), 'First key has not been deleted.');
     $this->assertTrue($backend->get('test2', TRUE), 'Second key has not been deleted.');
+    // Test that calling invalidateAll() does not change data.
+    $this->assertIdentical($backend->get('test1', TRUE)->data, 1);
   }
 
 }
