diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
index 570faee..63a3a98 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
@@ -190,7 +190,17 @@ public function query($query, array $args = array(), $options = array()) {
     return $return;
   }
 
+  /**
+   * {@inheritdoc}
+   */
   public function prepareQuery($query) {
+    // The statement class is not gauranteed to be set. This works around the
+    // issue that may be caused by a race condition in closing and opening
+    // the connection.
+    $statementClass = $this->connection->getAttribute(\PDO::ATTR_STATEMENT_CLASS);
+    if ($statementClass[0] <> $this->statementClass) {
+      $this->connection->setAttribute(\PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this)));
+    }
     // mapConditionOperator converts LIKE operations to ILIKE for consistency
     // with MySQL. However, Postgres does not support ILIKE on bytea (blobs)
     // fields.
diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
index aca4f31..789f626 100644
--- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
+++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Serialization\SerializationInterface;
 use Drupal\Core\Database\Query\Merge;
 use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\SchemaObjectExistsException;
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 
 /**
@@ -61,16 +62,26 @@ public function __construct($collection, SerializationInterface $serializer, Con
    * {@inheritdoc}
    */
   public function has($key) {
-    return (bool) $this->connection->query('SELECT 1 FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND name = :key', array(
-      ':collection' => $this->collection,
-      ':key' => $key,
-    ))->fetchField();
+    try {
+      return (bool) $this->connection->query('SELECT 1 FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND name = :key', array(
+        ':collection' => $this->collection,
+        ':key' => $key,
+      ))->fetchField();
+    }
+    catch (\Exception $e) {
+      $this->catchException($e);
+      return FALSE;
+    }
   }
 
   /**
    * {@inheritdoc}
    */
   public function getMultiple(array $keys) {
+    if (empty($keys)) {
+      return [];
+    }
+
     $values = array();
     try {
       $result = $this->connection->query('SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE name IN ( :keys[] ) AND collection = :collection', array(':keys[]' => $keys, ':collection' => $this->collection))->fetchAllAssoc('name');
@@ -84,6 +95,7 @@ public function getMultiple(array $keys) {
       // @todo: Perhaps if the database is never going to be available,
       // key/value requests should return FALSE in order to allow exception
       // handling to occur but for now, keep it an array, always.
+      $this->catchException($e);
     }
     return $values;
   }
@@ -92,7 +104,14 @@ public function getMultiple(array $keys) {
    * {@inheritdoc}
    */
   public function getAll() {
-    $result = $this->connection->query('SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection', array(':collection' => $this->collection));
+    try {
+      $result = $this->connection->query('SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection', array(':collection' => $this->collection));
+    }
+    catch (\Exception $e) {
+      $this->catchException($e);
+      $result = [];
+    }
+
     $values = array();
 
     foreach ($result as $item) {
@@ -107,40 +126,75 @@ public function getAll() {
    * {@inheritdoc}
    */
   public function set($key, $value) {
-    $this->connection->merge($this->table)
-      ->keys(array(
-        'name' => $key,
-        'collection' => $this->collection,
-      ))
-      ->fields(array('value' => $this->serializer->encode($value)))
-      ->execute();
+    $try_again = FALSE;
+    try {
+      $this->connection->merge($this->table)
+        ->keys(array(
+          'name' => $key,
+          'collection' => $this->collection,
+        ))
+        ->fields(array('value' => $this->serializer->encode($value)))
+        ->execute();
+    }
+    catch (\Exception $e) {
+      // If there was an exception, try to create the table.
+      if (!$try_again = $this->ensureTableExists()) {
+        // If the exception happened for other reason than the missing bin
+        // table, propagate the exception.
+        throw $e;
+      }
+    }
+    // Now that the bin has been created, try again if necessary.
+    if ($try_again) {
+      $this->set($key, $value);
+    }
   }
 
   /**
    * {@inheritdoc}
    */
   public function setIfNotExists($key, $value) {
-    $result = $this->connection->merge($this->table)
-      ->insertFields(array(
-        'collection' => $this->collection,
-        'name' => $key,
-        'value' => $this->serializer->encode($value),
-      ))
-      ->condition('collection', $this->collection)
-      ->condition('name', $key)
-      ->execute();
-    return $result == Merge::STATUS_INSERT;
+    $try_again = FALSE;
+    try {
+      $result = $this->connection->merge($this->table)
+        ->insertFields(array(
+          'collection' => $this->collection,
+          'name' => $key,
+          'value' => $this->serializer->encode($value),
+        ))
+        ->condition('collection', $this->collection)
+        ->condition('name', $key)
+        ->execute();
+      return $result == Merge::STATUS_INSERT;
+    }
+    catch (\Exception $e) {
+      // If there was an exception, try to create the table.
+      if (!$try_again = $this->ensureTableExists()) {
+        // If the exception happened for other reason than the missing bin
+        // table, propagate the exception.
+        throw $e;
+      }
+    }
+    // Now that the bin has been created, try again if necessary.
+    if ($try_again) {
+      return $this->setIfNotExists($key, $value);
+    }
   }
 
   /**
    * {@inheritdoc}
    */
   public function rename($key, $new_key) {
-    $this->connection->update($this->table)
-      ->fields(array('name' => $new_key))
-      ->condition('collection', $this->collection)
-      ->condition('name', $key)
-      ->execute();
+    try {
+      $this->connection->update($this->table)
+        ->fields(array('name' => $new_key))
+        ->condition('collection', $this->collection)
+        ->condition('name', $key)
+        ->execute();
+    }
+    catch (\Exception $e) {
+      $this->catchException($e);
+    }
   }
 
   /**
@@ -149,20 +203,98 @@ public function rename($key, $new_key) {
   public function deleteMultiple(array $keys) {
     // Delete in chunks when a large array is passed.
     while ($keys) {
+      try {
+        $this->connection->delete($this->table)
+          ->condition('name', array_splice($keys, 0, 1000), 'IN')
+          ->condition('collection', $this->collection)
+          ->execute();
+      }
+      catch (\Exception $e) {
+        $this->catchException($e);
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll() {
+    try {
       $this->connection->delete($this->table)
-        ->condition('name', array_splice($keys, 0, 1000), 'IN')
         ->condition('collection', $this->collection)
         ->execute();
     }
+    catch (\Exception $e) {
+      $this->catchException($e);
+    }
   }
 
   /**
-   * {@inheritdoc}
+   * Check if the table exists and create it if not.
    */
-  public function deleteAll() {
-    $this->connection->delete($this->table)
-      ->condition('collection', $this->collection)
-      ->execute();
+  protected function ensureTableExists() {
+    try {
+      $database_schema = $this->connection->schema();
+      if (!$database_schema->tableExists($this->table)) {
+        $database_schema->createTable($this->table, $this->schemaDefinition());
+        return TRUE;
+      }
+    }
+    // If the table already exists, then attempting to recreate it will throw an
+    // exception. In this case just catch the exception and do nothing.
+    catch (SchemaObjectExistsException $e) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * Act on an exception when the table might not have been created.
+   *
+   * If the table does not yet exist, that's fine, but if the table exists and
+   * something else cause the exception, then propagate it.
+   *
+   * @param \Exception $e
+   *   The exception.
+   *
+   * @throws \Exception
+   */
+  protected function catchException(\Exception $e) {
+    if ($this->connection->schema()->tableExists($this->table)) {
+      throw $e;
+    }
+  }
+
+  /**
+   * Defines the schema for the key_value table.
+   */
+  public static function schemaDefinition() {
+    return [
+      'description' => 'Generic key-value storage table. See the state system for an example.',
+      'fields' => [
+        'collection' => [
+          'description' => 'A named collection of key and value pairs.',
+          'type' => 'varchar_ascii',
+          'length' => 128,
+          'not null' => TRUE,
+          'default' => '',
+        ],
+        'name' => [
+          'description' => 'The key of the key-value pair. As KEY is a SQL reserved keyword, name was chosen instead.',
+          'type' => 'varchar_ascii',
+          'length' => 128,
+          'not null' => TRUE,
+          'default' => '',
+        ],
+        'value' => [
+          'description' => 'The value.',
+          'type' => 'blob',
+          'not null' => TRUE,
+          'size' => 'big',
+        ],
+      ],
+      'primary key' => ['collection', 'name'],
+    ];
   }
 
 }
diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
index 9f3b428..99d970f 100644
--- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
+++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
@@ -34,71 +34,127 @@ public function __construct($collection, SerializationInterface $serializer, Con
    * {@inheritdoc}
    */
   public function has($key) {
-    return (bool) $this->connection->query('SELECT 1 FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND name = :key AND expire > :now', array(
-      ':collection' => $this->collection,
-      ':key' => $key,
-      ':now' => REQUEST_TIME,
-    ))->fetchField();
+    try {
+      return (bool) $this->connection->query('SELECT 1 FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND name = :key AND expire > :now', array(
+        ':collection' => $this->collection,
+        ':key' => $key,
+        ':now' => REQUEST_TIME,
+      ))->fetchField();
+    }
+    catch (\Exception $e) {
+      $this->catchException($e);
+      return FALSE;
+    }
   }
 
   /**
    * {@inheritdoc}
    */
   public function getMultiple(array $keys) {
-    $values = $this->connection->query(
-      'SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE expire > :now AND name IN ( :keys[] ) AND collection = :collection',
-      array(
-        ':now' => REQUEST_TIME,
-        ':keys[]' => $keys,
-        ':collection' => $this->collection,
-      ))->fetchAllKeyed();
-    return array_map(array($this->serializer, 'decode'), $values);
+    if (empty($keys)) {
+      return [];
+    }
+
+    try {
+      $values = $this->connection->query(
+        'SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE expire > :now AND name IN ( :keys[] ) AND collection = :collection',
+        array(
+          ':now' => REQUEST_TIME,
+          ':keys[]' => $keys,
+          ':collection' => $this->collection,
+        ))->fetchAllKeyed();
+      return array_map(array($this->serializer, 'decode'), $values);
+    }
+    catch (\Exception $e) {
+      // @todo: Perhaps if the database is never going to be available,
+      // key/value requests should return FALSE in order to allow exception
+      // handling to occur but for now, keep it an array, always.
+      // https://www.drupal.org/node/2787737
+      $this->catchException($e);
+    }
+    return [];
   }
 
   /**
    * {@inheritdoc}
    */
   public function getAll() {
-    $values = $this->connection->query(
-      'SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND expire > :now',
-      array(
-        ':collection' => $this->collection,
-        ':now' => REQUEST_TIME
-      ))->fetchAllKeyed();
-    return array_map(array($this->serializer, 'decode'), $values);
+    try {
+      $values = $this->connection->query(
+        'SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection = :collection AND expire > :now',
+        array(
+          ':collection' => $this->collection,
+          ':now' => REQUEST_TIME
+        ))->fetchAllKeyed();
+      return array_map(array($this->serializer, 'decode'), $values);
+    }
+    catch (\Exception $e) {
+      $this->catchException($e);
+    }
+    return [];
   }
 
   /**
    * {@inheritdoc}
    */
   function setWithExpire($key, $value, $expire) {
-    $this->connection->merge($this->table)
-      ->keys(array(
-        'name' => $key,
-        'collection' => $this->collection,
-      ))
-      ->fields(array(
-        'value' => $this->serializer->encode($value),
-        'expire' => REQUEST_TIME + $expire,
-      ))
-      ->execute();
+    $try_again = FALSE;
+    try {
+      $this->connection->merge($this->table)
+        ->keys(array(
+          'name' => $key,
+          'collection' => $this->collection,
+        ))
+        ->fields(array(
+          'value' => $this->serializer->encode($value),
+          'expire' => REQUEST_TIME + $expire,
+        ))
+        ->execute();
+    }
+    catch (\Exception $e) {
+      // If there was an exception, try to create the table.
+      if (!$try_again = $this->ensureTableExists()) {
+        // If the exception happened for other reason than the missing bin
+        // table, propagate the exception.
+        throw $e;
+      }
+    }
+    // Now that the bin has been created, try again if necessary.
+    if ($try_again) {
+      $this->setWithExpire($key, $value, $expire);
+    }
   }
 
   /**
    * {@inheritdoc}
    */
   function setWithExpireIfNotExists($key, $value, $expire) {
-    $result = $this->connection->merge($this->table)
-      ->insertFields(array(
-        'collection' => $this->collection,
-        'name' => $key,
-        'value' => $this->serializer->encode($value),
-        'expire' => REQUEST_TIME + $expire,
-      ))
-      ->condition('collection', $this->collection)
-      ->condition('name', $key)
-      ->execute();
-    return $result == Merge::STATUS_INSERT;
+    $try_again = FALSE;
+    try {
+      $result = $this->connection->merge($this->table)
+        ->insertFields(array(
+          'collection' => $this->collection,
+          'name' => $key,
+          'value' => $this->serializer->encode($value),
+          'expire' => REQUEST_TIME + $expire,
+        ))
+        ->condition('collection', $this->collection)
+        ->condition('name', $key)
+        ->execute();
+      return $result == Merge::STATUS_INSERT;
+    }
+    catch (\Exception $e) {
+      // If there was an exception, try to create the table.
+      if (!$try_again = $this->ensureTableExists()) {
+        // If the exception happened for other reason than the missing bin
+        // table, propagate the exception.
+        throw $e;
+      }
+    }
+    // Now that the bin has been created, try again if necessary.
+    if ($try_again) {
+      return $this->setWithExpireIfNotExists($key, $value, $expire);
+    }
   }
 
   /**
@@ -117,4 +173,47 @@ public function deleteMultiple(array $keys) {
     parent::deleteMultiple($keys);
   }
 
+  /**
+   * Defines the schema for the key_value_expire table.
+   */
+  public static function schemaDefinition() {
+    return [
+      'description' => 'Generic key/value storage table with an expiration.',
+      'fields' => [
+        'collection' => [
+          'description' => 'A named collection of key and value pairs.',
+          'type' => 'varchar_ascii',
+          'length' => 128,
+          'not null' => TRUE,
+          'default' => '',
+        ],
+        'name' => [
+          // KEY is an SQL reserved word, so use 'name' as the key's field name.
+          'description' => 'The key of the key/value pair.',
+          'type' => 'varchar_ascii',
+          'length' => 128,
+          'not null' => TRUE,
+          'default' => '',
+        ],
+        'value' => [
+          'description' => 'The value of the key/value pair.',
+          'type' => 'blob',
+          'not null' => TRUE,
+          'size' => 'big',
+        ],
+        'expire' => [
+          'description' => 'The time since Unix epoch in seconds when this item expires. Defaults to the maximum possible time.',
+          'type' => 'int',
+          'not null' => TRUE,
+          'default' => 2147483647,
+        ],
+      ],
+      'primary key' => ['collection', 'name'],
+      'indexes' => [
+        'all' => ['name', 'collection', 'expire'],
+        'expire' => ['expire'],
+      ],
+    ];
+  }
+
 }
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseExpirableFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseExpirableFactory.php
index 5670fe5..1f0822d 100644
--- a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseExpirableFactory.php
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseExpirableFactory.php
@@ -58,9 +58,31 @@ public function get($collection) {
    * Deletes expired items.
    */
   public function garbageCollection() {
-    $this->connection->delete('key_value_expire')
-      ->condition('expire', REQUEST_TIME, '<')
-      ->execute();
+    try {
+      $this->connection->delete('key_value_expire')
+        ->condition('expire', REQUEST_TIME, '<')
+        ->execute();
+    }
+    catch (\Exception $e) {
+      $this->catchException($e);
+    }
+  }
+
+  /**
+   * Act on an exception when the table might not have been created.
+   *
+   * If the table does not yet exist, that's fine, but if the table exists and
+   * something else cause the exception, then propagate it.
+   *
+   * @param \Exception $e
+   *   The exception.
+   *
+   * @throws \Exception
+   */
+  protected function catchException(\Exception $e) {
+    if ($this->connection->schema()->tableExists('key_value_expire')) {
+      throw $e;
+    }
   }
 
 }
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
index d56004e..8035a0e 100644
--- a/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueStoreInterface.php
@@ -48,7 +48,8 @@ public function get($key, $default = NULL);
    * @return array
    *   An associative array of items successfully returned, indexed by key.
    *
-   * @todo What's returned for non-existing keys?
+   * @todo Determine the best return value for non-existing keys in
+   *   https://www.drupal.org/node/2787737
    */
   public function getMultiple(array $keys);
 
diff --git a/core/modules/dblog/tests/src/Kernel/DbLogFormInjectionTest.php b/core/modules/dblog/tests/src/Kernel/DbLogFormInjectionTest.php
index 569cdbf..a997096 100644
--- a/core/modules/dblog/tests/src/Kernel/DbLogFormInjectionTest.php
+++ b/core/modules/dblog/tests/src/Kernel/DbLogFormInjectionTest.php
@@ -79,7 +79,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
   protected function setUp() {
     parent::setUp();
     $this->installSchema('dblog', ['watchdog']);
-    $this->installSchema('system', ['key_value_expire', 'sequences']);
+    $this->installSchema('system', ['sequences']);
     $this->installEntitySchema('user');
     $this->logger = \Drupal::logger('test_logger');
     $test_user = User::create(array(
diff --git a/core/modules/editor/tests/src/Kernel/EditorImageDialogTest.php b/core/modules/editor/tests/src/Kernel/EditorImageDialogTest.php
index 329018b..2496c90 100644
--- a/core/modules/editor/tests/src/Kernel/EditorImageDialogTest.php
+++ b/core/modules/editor/tests/src/Kernel/EditorImageDialogTest.php
@@ -36,7 +36,6 @@ class EditorImageDialogTest extends EntityKernelTestBase {
   protected function setUp() {
     parent::setUp();
     $this->installEntitySchema('file');
-    $this->installSchema('system', ['key_value_expire']);
     $this->installSchema('node', array('node_access'));
     $this->installSchema('file', array('file_usage'));
     $this->installConfig(['node']);
diff --git a/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php b/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php
index 4d6bd51..d66f35e 100644
--- a/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php
+++ b/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php
@@ -47,7 +47,7 @@ protected function setUp() {
 
     $this->installEntitySchema('entity_test');
     $this->installEntitySchema('user');
-    $this->installSchema('system', ['sequences', 'key_value']);
+    $this->installSchema('system', ['sequences']);
 
     // Set default storage backend and configure the theme system.
     $this->installConfig(array('field', 'system'));
diff --git a/core/modules/rest/tests/fixtures/update/rest-export-with-authentication.php b/core/modules/rest/tests/fixtures/update/rest-export-with-authentication.php
index 46285fc..04ce440 100644
--- a/core/modules/rest/tests/fixtures/update/rest-export-with-authentication.php
+++ b/core/modules/rest/tests/fixtures/update/rest-export-with-authentication.php
@@ -66,10 +66,12 @@
   ])
   ->execute();
 
+$config = Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.rest_export_with_authorization.yml'));
+$config['uuid'] = '1D52D29E-2DD8-417A-9CDA-1BBC5A013B1F';
 $connection->merge('config')
   ->condition('name', 'views.view.rest_export_with_authorization')
   ->condition('collection', '')
   ->fields([
-    'data' => serialize(Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.rest_export_with_authorization.yml'))),
+    'data' => serialize($config),
   ])
   ->execute();
diff --git a/core/modules/rest/tests/fixtures/update/rest.resource.entity.comment_2721595.yml b/core/modules/rest/tests/fixtures/update/rest.resource.entity.comment_2721595.yml
index 7e86bab..bae67aa 100644
--- a/core/modules/rest/tests/fixtures/update/rest.resource.entity.comment_2721595.yml
+++ b/core/modules/rest/tests/fixtures/update/rest.resource.entity.comment_2721595.yml
@@ -1,4 +1,5 @@
 id: entity.comment
+uuid: 4093D90C-69E6-4024-B177-25EE075F86D8
 plugin_id: 'entity:comment'
 granularity: method
 configuration:
diff --git a/core/modules/rest/tests/fixtures/update/rest.resource.entity.node_2721595.yml b/core/modules/rest/tests/fixtures/update/rest.resource.entity.node_2721595.yml
index 0cf4d78..7d3da33 100644
--- a/core/modules/rest/tests/fixtures/update/rest.resource.entity.node_2721595.yml
+++ b/core/modules/rest/tests/fixtures/update/rest.resource.entity.node_2721595.yml
@@ -1,4 +1,5 @@
 id: entity.node
+uuid: 63E588C5-B0EA-4156-8EFE-1A288DAA975F
 plugin_id: 'entity:node'
 granularity: method
 configuration:
diff --git a/core/modules/rest/tests/fixtures/update/rest.resource.entity.user_2721595.yml b/core/modules/rest/tests/fixtures/update/rest.resource.entity.user_2721595.yml
index 593a260..8541015 100644
--- a/core/modules/rest/tests/fixtures/update/rest.resource.entity.user_2721595.yml
+++ b/core/modules/rest/tests/fixtures/update/rest.resource.entity.user_2721595.yml
@@ -1,4 +1,5 @@
 id: entity.user
+uuid: A4674E26-9831-40B4-B3E7-A087C8C9B00D
 plugin_id: 'entity:user'
 granularity: method
 configuration:
diff --git a/core/modules/system/src/Tests/Path/UrlAliasFixtures.php b/core/modules/system/src/Tests/Path/UrlAliasFixtures.php
index a527fc5..1f71690 100644
--- a/core/modules/system/src/Tests/Path/UrlAliasFixtures.php
+++ b/core/modules/system/src/Tests/Path/UrlAliasFixtures.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\system\Tests\Path;
 
+use Drupal\Core\KeyValueStore\DatabaseStorage;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Path\AliasStorage;
 
@@ -89,7 +90,7 @@ public function tableDefinition() {
     $schema = system_schema();
 
     $tables['url_alias'] = AliasStorage::schemaDefinition();
-    $tables['key_value'] = $schema['key_value'];
+    $tables['key_value'] = DatabaseStorage::schemaDefinition();
 
     return $tables;
   }
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 3ef24a5..75ca16e 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -890,71 +890,6 @@ function system_install() {
  * Implements hook_schema().
  */
 function system_schema() {
-  $schema['key_value'] = array(
-    'description' => 'Generic key-value storage table. See the state system for an example.',
-    'fields' => array(
-      'collection' => array(
-        'description' => 'A named collection of key and value pairs.',
-        'type' => 'varchar_ascii',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'name' => array(
-        'description' => 'The key of the key-value pair. As KEY is a SQL reserved keyword, name was chosen instead.',
-        'type' => 'varchar_ascii',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'value' => array(
-        'description' => 'The value.',
-        'type' => 'blob',
-        'not null' => TRUE,
-        'size' => 'big',
-      ),
-    ),
-    'primary key' => array('collection', 'name'),
-  );
-
-  $schema['key_value_expire'] = array(
-    'description' => 'Generic key/value storage table with an expiration.',
-    'fields' => array(
-      'collection' => array(
-        'description' => 'A named collection of key and value pairs.',
-        'type' => 'varchar_ascii',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'name' => array(
-        // KEY is an SQL reserved word, so use 'name' as the key's field name.
-        'description' => 'The key of the key/value pair.',
-        'type' => 'varchar_ascii',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'value' => array(
-        'description' => 'The value of the key/value pair.',
-        'type' => 'blob',
-        'not null' => TRUE,
-        'size' => 'big',
-      ),
-      'expire' => array(
-        'description' => 'The time since Unix epoch in seconds when this item expires. Defaults to the maximum possible time.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 2147483647,
-      ),
-    ),
-    'primary key' => array('collection', 'name'),
-    'indexes' => array(
-      'all' => array('name', 'collection', 'expire'),
-      'expire' => array('expire'),
-    ),
-  );
-
   $schema['sequences'] = array(
     'description' => 'Stores IDs.',
     'fields' => array(
diff --git a/core/modules/system/tests/fixtures/update/block.block.testfor2476947.yml b/core/modules/system/tests/fixtures/update/block.block.testfor2476947.yml
index 21cfb2f..a00f938 100644
--- a/core/modules/system/tests/fixtures/update/block.block.testfor2476947.yml
+++ b/core/modules/system/tests/fixtures/update/block.block.testfor2476947.yml
@@ -1,4 +1,5 @@
 langcode: en
+uuid: 1F526BF9-F924-49FD-B45A-61F776F3E9E2
 status: true
 dependencies:
   theme:
diff --git a/core/modules/system/tests/fixtures/update/block.block.testfor2569529.yml b/core/modules/system/tests/fixtures/update/block.block.testfor2569529.yml
index 3339199..5fcdcdd 100644
--- a/core/modules/system/tests/fixtures/update/block.block.testfor2569529.yml
+++ b/core/modules/system/tests/fixtures/update/block.block.testfor2569529.yml
@@ -1,4 +1,5 @@
 langcode: en
+uuid: 8862ACDA-DDBA-4645-B84D-EB346D48A6F1
 status: true
 dependencies:
   theme:
diff --git a/core/modules/system/tests/fixtures/update/drupal-8.block-test-enabled.php b/core/modules/system/tests/fixtures/update/drupal-8.block-test-enabled.php
index f3edf28..3e41810 100644
--- a/core/modules/system/tests/fixtures/update/drupal-8.block-test-enabled.php
+++ b/core/modules/system/tests/fixtures/update/drupal-8.block-test-enabled.php
@@ -39,6 +39,7 @@
 // Install the block configuration.
 $config = file_get_contents(__DIR__ . '/../../../../block/tests/modules/block_test/config/install/block.block.test_block.yml');
 $config = Yaml::parse($config);
+$config['uuid'] = '35B67D42-EF1C-424F-99E6-9DA4E3275A27';
 $connection->insert('config')
   ->fields(['data', 'name', 'collection'])
   ->values([
diff --git a/core/modules/system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.yml b/core/modules/system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.yml
index 585da34..0beeb0b 100644
--- a/core/modules/system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.yml
+++ b/core/modules/system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.yml
@@ -1,4 +1,5 @@
 langcode: en
+uuid: E5456850-153E-43AD-BE72-A1D38991A646
 status: true
 dependencies:
   config:
diff --git a/core/modules/system/tests/src/Kernel/System/CronQueueTest.php b/core/modules/system/tests/src/Kernel/System/CronQueueTest.php
index c51ee5a..286849e 100644
--- a/core/modules/system/tests/src/Kernel/System/CronQueueTest.php
+++ b/core/modules/system/tests/src/Kernel/System/CronQueueTest.php
@@ -38,11 +38,6 @@ class CronQueueTest extends KernelTestBase {
    */
   protected function setUp() {
     parent::setUp();
-
-    // These additional tables are necessary because $this->cron->run() calls
-    // system_cron().
-    $this->installSchema('system', ['key_value_expire']);
-
     $this->connection = Database::getConnection();
     $this->cron = \Drupal::service('cron');
   }
diff --git a/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php b/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php
index 254524a..bab1199 100644
--- a/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php
+++ b/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php
@@ -54,10 +54,6 @@ class TempStoreDatabaseTest extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
 
-    // Install system tables to test the key/value storage without installing a
-    // full Drupal environment.
-    $this->installSchema('system', array('key_value_expire'));
-
     // Create several objects for testing.
     for ($i = 0; $i <= 3; $i++) {
       $this->objects[$i] = $this->randomObject();
diff --git a/core/modules/views/tests/fixtures/update/argument-placeholder.php b/core/modules/views/tests/fixtures/update/argument-placeholder.php
index 2a7cf4b..d213f62 100644
--- a/core/modules/views/tests/fixtures/update/argument-placeholder.php
+++ b/core/modules/views/tests/fixtures/update/argument-placeholder.php
@@ -10,10 +10,12 @@
 
 $connection = Database::getConnection();
 
+$config = Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.test_token_view.yml'));
+$config['uuid'] = '109F8D2E-3A03-4F32-9E56-8A1CBA5F15C5';
 $connection->insert('config')
   ->fields(array(
     'collection' => '',
     'name' => 'views.view.test_token_view',
-    'data' => serialize(Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.test_token_view.yml'))),
+    'data' => serialize($config),
   ))
   ->execute();
diff --git a/core/modules/views/tests/fixtures/update/duplicate-field-handler.php b/core/modules/views/tests/fixtures/update/duplicate-field-handler.php
index 775f75a..6ba3667 100644
--- a/core/modules/views/tests/fixtures/update/duplicate-field-handler.php
+++ b/core/modules/views/tests/fixtures/update/duplicate-field-handler.php
@@ -10,10 +10,12 @@
 
 $connection = Database::getConnection();
 
+$config = Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.test_duplicate_field_handlers.yml'));
+$config['uuid'] = 'F311CC06-F69E-47DB-BBF1-BDD49CD9A669';
 $connection->insert('config')
   ->fields(array(
     'collection' => '',
     'name' => 'views.view.test_duplicate_field_handlers',
-    'data' => serialize(Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.test_duplicate_field_handlers.yml'))),
+    'data' => serialize($config),
   ))
   ->execute();
diff --git a/core/modules/views/tests/fixtures/update/views.view.test_boolean_filter_values.yml b/core/modules/views/tests/fixtures/update/views.view.test_boolean_filter_values.yml
index 65c2847..b573b05 100644
--- a/core/modules/views/tests/fixtures/update/views.view.test_boolean_filter_values.yml
+++ b/core/modules/views/tests/fixtures/update/views.view.test_boolean_filter_values.yml
@@ -1,4 +1,5 @@
 langcode: en
+uuid: 8C0C65A8-7099-4E90-9F6C-C5EE7BD3445D
 status: true
 dependencies:
   module:
@@ -601,4 +602,4 @@ display:
         - 'user.node_grants:view'
         - user.permissions
       max-age: 0
-      tags: {  }
\ No newline at end of file
+      tags: {  }
diff --git a/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php b/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
index f149b7f..d4657e3 100644
--- a/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
+++ b/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
@@ -41,7 +41,7 @@
   protected function setUp($import_test_views = TRUE) {
     parent::setUp();
 
-    $this->installSchema('system', ['router', 'sequences', 'key_value_expire']);
+    $this->installSchema('system', ['router', 'sequences']);
     $this->setUpFixtures();
 
     if ($import_test_views) {
diff --git a/core/tests/Drupal/KernelTests/Core/Command/DbDumpTest.php b/core/tests/Drupal/KernelTests/Core/Command/DbDumpTest.php
index 8129410..9886955 100644
--- a/core/tests/Drupal/KernelTests/Core/Command/DbDumpTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Command/DbDumpTest.php
@@ -83,10 +83,7 @@ protected function setUp() {
     $this->skipTests = Database::getConnection()->databaseType() !== 'mysql';
 
     // Create some schemas so our export contains tables.
-    $this->installSchema('system', [
-      'key_value_expire',
-      'sessions',
-    ]);
+    $this->installSchema('system', ['sessions']);
     $this->installSchema('dblog', ['watchdog']);
     $this->installEntitySchema('block_content');
     $this->installEntitySchema('user');
@@ -126,7 +123,6 @@ protected function setUp() {
       'cache_discovery',
       'cache_entity',
       'file_managed',
-      'key_value_expire',
       'menu_link_content',
       'menu_link_content_data',
       'sequences',
diff --git a/core/tests/Drupal/KernelTests/Core/Element/PathElementFormTest.php b/core/tests/Drupal/KernelTests/Core/Element/PathElementFormTest.php
index ca4e501..4186a9c 100644
--- a/core/tests/Drupal/KernelTests/Core/Element/PathElementFormTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Element/PathElementFormTest.php
@@ -37,7 +37,7 @@ class PathElementFormTest extends KernelTestBase implements FormInterface {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installSchema('system', ['sequences', 'key_value_expire']);
+    $this->installSchema('system', ['sequences']);
     $this->installEntitySchema('user');
     \Drupal::service('router.builder')->rebuild();
     /** @var \Drupal\user\RoleInterface $role */
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php
index ec81f7b..9249f5a 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php
@@ -45,7 +45,6 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
   protected function setUp() {
     parent::setUp();
 
-    $this->installSchema('system', ['key_value_expire']);
     \Drupal::service('router.builder')->rebuild();
 
     $this->testUser = User::create(array(
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php
index ae4925c..6aea1b3 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php
@@ -33,14 +33,6 @@ class EntityAutocompleteTest extends EntityKernelTestBase {
   protected $bundle = 'entity_test';
 
   /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->installSchema('system', ['key_value']);
-  }
-
-  /**
    * Tests autocompletion edge cases with slashes in the names.
    */
   function testEntityReferenceAutocompletion() {
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php b/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php
index 50d173b..81c33d6 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php
@@ -23,7 +23,6 @@ class FieldWidgetConstraintValidatorTest extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
 
-    $this->installSchema('system', ['key_value']);
     $this->container->get('router.builder')->rebuild();
 
     $this->installEntitySchema('user');
diff --git a/core/tests/Drupal/KernelTests/Core/Form/ExternalFormUrlTest.php b/core/tests/Drupal/KernelTests/Core/Form/ExternalFormUrlTest.php
index f3fbc4f..1bc8c48 100644
--- a/core/tests/Drupal/KernelTests/Core/Form/ExternalFormUrlTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Form/ExternalFormUrlTest.php
@@ -53,7 +53,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {}
    */
   protected function setUp() {
     parent::setUp();
-    $this->installSchema('system', ['key_value_expire', 'sequences']);
+    $this->installSchema('system', ['sequences']);
     $this->installEntitySchema('user');
 
     $test_user = User::create([
diff --git a/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php b/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php
index fa86bee..890133a 100644
--- a/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php
@@ -39,7 +39,6 @@ class FormCacheTest extends KernelTestBase {
 
   protected function setUp() {
     parent::setUp();
-    $this->installSchema('system', array('key_value_expire'));
 
     $this->formBuildId = $this->randomMachineName();
     $this->form = array(
diff --git a/core/tests/Drupal/KernelTests/Core/Form/FormDefaultHandlersTest.php b/core/tests/Drupal/KernelTests/Core/Form/FormDefaultHandlersTest.php
index 7f046e9..895ceba 100644
--- a/core/tests/Drupal/KernelTests/Core/Form/FormDefaultHandlersTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Form/FormDefaultHandlersTest.php
@@ -24,14 +24,6 @@ class FormDefaultHandlersTest extends KernelTestBase implements FormInterface {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
-    $this->installSchema('system', ['key_value_expire']);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function getFormId() {
     return 'test_form_handlers';
   }
diff --git a/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageExpirableTest.php b/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageExpirableTest.php
index 1631501..446e714 100644
--- a/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageExpirableTest.php
+++ b/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageExpirableTest.php
@@ -22,7 +22,6 @@ class DatabaseStorageExpirableTest extends StorageTestBase {
   protected function setUp() {
     parent::setUp();
     $this->factory = 'keyvalue.expirable';
-    $this->installSchema('system', array('key_value_expire'));
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageTest.php b/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageTest.php
index 676ab10..adacfce 100644
--- a/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageTest.php
+++ b/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageTest.php
@@ -19,11 +19,6 @@ class DatabaseStorageTest extends StorageTestBase {
    */
   public static $modules = array('system');
 
-  protected function setUp() {
-    parent::setUp();
-    $this->installSchema('system', array('key_value'));
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/tests/Drupal/KernelTests/Core/KeyValueStore/GarbageCollectionTest.php b/core/tests/Drupal/KernelTests/Core/KeyValueStore/GarbageCollectionTest.php
index 4dc9b47..ec16864 100644
--- a/core/tests/Drupal/KernelTests/Core/KeyValueStore/GarbageCollectionTest.php
+++ b/core/tests/Drupal/KernelTests/Core/KeyValueStore/GarbageCollectionTest.php
@@ -21,13 +21,6 @@ class GarbageCollectionTest extends KernelTestBase {
    */
   public static $modules = array('system');
 
-  protected function setUp() {
-    parent::setUp();
-
-    // These additional tables are necessary due to the call to system_cron().
-    $this->installSchema('system', array('key_value_expire'));
-  }
-
   /**
    * Tests garbage collection.
    */
diff --git a/core/tests/Drupal/KernelTests/Core/KeyValueStore/StorageTestBase.php b/core/tests/Drupal/KernelTests/Core/KeyValueStore/StorageTestBase.php
index 48e047d..6b84ee7 100644
--- a/core/tests/Drupal/KernelTests/Core/KeyValueStore/StorageTestBase.php
+++ b/core/tests/Drupal/KernelTests/Core/KeyValueStore/StorageTestBase.php
@@ -94,6 +94,11 @@ public function testCRUD() {
       $this->assertIdenticalObject($value, $result[$j]);
     }
 
+    // Verify that passing in an empty list of keys, returns an empty
+    // array.
+    $result = $stores[0]->getMultiple([]);
+    $this->assertEquals([], $result);
+
     // Verify that the other collection was not affected.
     $this->assertFalse($stores[1]->get('foo'));
     $this->assertFalse($stores[1]->get('bar'));
diff --git a/core/tests/Drupal/KernelTests/Core/Queue/QueueSerializationTest.php b/core/tests/Drupal/KernelTests/Core/Queue/QueueSerializationTest.php
index 3ea4c66..d1d2641 100644
--- a/core/tests/Drupal/KernelTests/Core/Queue/QueueSerializationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Queue/QueueSerializationTest.php
@@ -77,7 +77,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installSchema('system', ['key_value_expire', 'sequences']);
+    $this->installSchema('system', ['sequences']);
     $this->installEntitySchema('user');
     $this->queue = \Drupal::service('queue.database')->get('aggregator_refresh');
     $test_user = User::create(array(
diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php
index 6f02023..98ba84e 100644
--- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php
+++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php
@@ -525,6 +525,7 @@ public function testSaveMismatch() {
     $config_object = $this->getMockBuilder('Drupal\Core\Config\Config')
       ->disableOriginalConstructor()
       ->getMock();
+
     $config_object->expects($this->atLeastOnce())
       ->method('isNew')
       ->will($this->returnValue(TRUE));
@@ -539,14 +540,16 @@ public function testSaveMismatch() {
       ->with('the_config_prefix.foo')
       ->will($this->returnValue($config_object));
 
+    $uuid = '7C1821EF-A96F-4BF0-B654-F683532EECB3';
     $this->entityQuery->expects($this->once())
       ->method('condition')
+      ->with('uuid', $uuid)
       ->will($this->returnSelf());
     $this->entityQuery->expects($this->once())
       ->method('execute')
       ->will($this->returnValue(array('baz')));
 
-    $entity = $this->getMockEntity(array('id' => 'foo'));
+    $entity = $this->getMockEntity(array('id' => 'foo', 'uuid' => $uuid));
     $this->entityStorage->save($entity);
   }
 
@@ -591,7 +594,8 @@ public function testSaveNoMismatch() {
       ->method('execute')
       ->will($this->returnValue(array('baz')));
 
-    $entity = $this->getMockEntity(array('id' => 'foo'));
+    $uuid = '7C1821EF-A96F-4BF0-B654-F683532EECB3';
+    $entity = $this->getMockEntity(array('id' => 'foo', 'uuid' => $uuid));
     $entity->setOriginalId('baz');
     $entity->enforceIsNew();
     $this->entityStorage->save($entity);
