diff --git a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php
index 35b02ed05f303b68a7ab3419ceeaae44252827b8..5baf85fd1f3047139cc8337cccb6523b366e68f3 100644
--- a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php
@@ -172,33 +172,7 @@ public function getChangeSummary() {
    * {@inheritdoc}
    */
   public function applyUpdates() {
-    $complete_change_list = $this->getChangeList();
-    if ($complete_change_list) {
-      // self::getChangeList() only disables the cache and does not invalidate.
-      // In case there are changes, explicitly invalidate caches.
-      $this->clearCachedDefinitions();
-    }
-    foreach ($complete_change_list as $entity_type_id => $change_list) {
-      // Process entity type definition changes before storage definitions ones
-      // this is necessary when you change an entity type from non-revisionable
-      // to revisionable and at the same time add revisionable fields to the
-      // entity type.
-      if (!empty($change_list['entity_type'])) {
-        $this->doEntityUpdate($change_list['entity_type'], $entity_type_id);
-      }
-
-      // Process field storage definition changes.
-      if (!empty($change_list['field_storage_definitions'])) {
-        $storage_definitions = $this->entityFieldManager->getFieldStorageDefinitions($entity_type_id);
-        $original_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type_id);
-
-        foreach ($change_list['field_storage_definitions'] as $field_name => $change) {
-          $storage_definition = isset($storage_definitions[$field_name]) ? $storage_definitions[$field_name] : NULL;
-          $original_storage_definition = isset($original_storage_definitions[$field_name]) ? $original_storage_definitions[$field_name] : NULL;
-          $this->doFieldUpdate($change, $storage_definition, $original_storage_definition);
-        }
-      }
-    }
+    trigger_error('EntityDefinitionUpdateManagerInterface::applyUpdates() is deprecated in 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface::getChangeList() and execute each entity type and field storage update manually instead. See https://www.drupal.org/node/3034742.', E_USER_DEPRECATED);
   }
 
   /**
@@ -298,69 +272,9 @@ public function uninstallFieldStorageDefinition(FieldStorageDefinitionInterface
   }
 
   /**
-   * Performs an entity type definition update.
-   *
-   * @param string $op
-   *   The operation to perform, either static::DEFINITION_CREATED or
-   *   static::DEFINITION_UPDATED.
-   * @param string $entity_type_id
-   *   The entity type ID.
-   */
-  protected function doEntityUpdate($op, $entity_type_id) {
-    $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
-    switch ($op) {
-      case static::DEFINITION_CREATED:
-        $this->entityTypeListener->onEntityTypeCreate($entity_type);
-        break;
-
-      case static::DEFINITION_UPDATED:
-        $original = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id);
-        $this->entityTypeListener->onEntityTypeUpdate($entity_type, $original);
-        break;
-    }
-  }
-
-  /**
-   * Performs a field storage definition update.
-   *
-   * @param string $op
-   *   The operation to perform, possible values are static::DEFINITION_CREATED,
-   *   static::DEFINITION_UPDATED or static::DEFINITION_DELETED.
-   * @param array|null $storage_definition
-   *   The new field storage definition.
-   * @param array|null $original_storage_definition
-   *   The original field storage definition.
-   */
-  protected function doFieldUpdate($op, $storage_definition = NULL, $original_storage_definition = NULL) {
-    switch ($op) {
-      case static::DEFINITION_CREATED:
-        $this->fieldStorageDefinitionListener->onFieldStorageDefinitionCreate($storage_definition);
-        break;
-
-      case static::DEFINITION_UPDATED:
-        $this->fieldStorageDefinitionListener->onFieldStorageDefinitionUpdate($storage_definition, $original_storage_definition);
-        break;
-
-      case static::DEFINITION_DELETED:
-        $this->fieldStorageDefinitionListener->onFieldStorageDefinitionDelete($original_storage_definition);
-        break;
-    }
-  }
-
-  /**
-   * Gets a list of changes to entity type and field storage definitions.
-   *
-   * @return array
-   *   An associative array keyed by entity type id of change descriptors. Every
-   *   entry is an associative array with the following optional keys:
-   *   - entity_type: a scalar having only the DEFINITION_UPDATED value.
-   *   - field_storage_definitions: an associative array keyed by field name of
-   *     scalars having one value among:
-   *     - DEFINITION_CREATED
-   *     - DEFINITION_UPDATED
-   *     - DEFINITION_DELETED
+   * {@inheritdoc}
    */
-  protected function getChangeList() {
+  public function getChangeList() {
     $this->entityTypeManager->useCaches(FALSE);
     $this->entityFieldManager->useCaches(FALSE);
     $change_list = [];
diff --git a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php
index 02cbe2cf1341795ea8e8c085dee9a9bae084d1eb..89ef413125ea956ecbdda4adfc6589b43ad79f82 100644
--- a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php
@@ -79,6 +79,23 @@ public function needsUpdates();
    */
   public function getChangeSummary();
 
+  /**
+   * Gets a list of changes to entity type and field storage definitions.
+   *
+   * @return array
+   *   An associative array keyed by entity type ID of change descriptors. Every
+   *   entry is an associative array with the following optional keys:
+   *   - entity_type: a scalar having one value among:
+   *     - EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED
+   *     - EntityDefinitionUpdateManagerInterface::DEFINITION_UPDATED
+   *   - field_storage_definitions: an associative array keyed by field name of
+   *     scalars having one value among:
+   *     - EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED
+   *     - EntityDefinitionUpdateManagerInterface::DEFINITION_UPDATED
+   *     - EntityDefinitionUpdateManagerInterface::DEFINITION_DELETED
+   */
+  public function getChangeList();
+
   /**
    * Applies all the detected valid changes.
    *
@@ -90,6 +107,12 @@ public function getChangeSummary();
    *   unacceptable data loss. In such a case, the site administrator needs to
    *   apply some other process, such as a custom update function or a
    *   migration via the Migrate module.
+   *
+   * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0. Use
+   *    \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface::getChangeList()
+   *    and execute each entity type and field storage update manually instead.
+   *
+   * @see https://www.drupal.org/node/3034742
    */
   public function applyUpdates();
 
diff --git a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
index 8c9d9f41045f28ad60ae96c249b3a2cb444ba8d3..4b0e752da2e8d2f28de7a247e3fe2b00bda8823d 100644
--- a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
+++ b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
@@ -184,6 +184,7 @@ public static function create(ContentEntityTypeInterface $entity_type, array $st
     $all_fields = array_merge($key_fields, array_diff($all_fields, $key_fields));
 
     $revision_metadata_fields = $revisionable ? array_values($entity_type->getRevisionMetadataKeys()) : [];
+    $revision_metadata_fields = array_intersect($revision_metadata_fields, array_keys($storage_definitions));
 
     if (!$revisionable && !$translatable) {
       // The base layout stores all the base field values in the base table.
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
index d721fbf997384e073ba4034113769c81614f898a..1459f01c0575804ff79452e06350c29af8f44b0d 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -3,7 +3,6 @@
 namespace Drupal\Core\Entity\Sql;
 
 use Drupal\Core\Database\Connection;
-use Drupal\Core\Database\DatabaseExceptionWrapper;
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
 use Drupal\Core\Entity\ContentEntityTypeInterface;
@@ -48,6 +47,13 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage
    */
   protected $entityTypeManager;
 
+  /**
+   * The entity field manager service.
+   *
+   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
+   */
+  protected $entityFieldManager;
+
   /**
    * The entity last installed schema repository.
    *
@@ -69,14 +75,6 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage
    */
   protected $fieldStorageDefinitions;
 
-  /**
-   * The original storage field definitions for this entity type. Used during
-   * field schema updates.
-   *
-   * @var \Drupal\Core\Field\FieldDefinitionInterface[]
-   */
-  protected $originalDefinitions;
-
   /**
    * The storage object for the given entity type.
    *
@@ -130,19 +128,21 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage
    */
   public function __construct(EntityTypeManagerInterface $entity_type_manager, ContentEntityTypeInterface $entity_type, SqlContentEntityStorage $storage, Connection $database, EntityFieldManagerInterface $entity_field_manager = NULL, EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository = NULL) {
     $this->entityTypeManager = $entity_type_manager;
-    $this->entityType = $entity_type;
+    $this->storage = $storage;
+    $this->database = $database;
     if (!$entity_field_manager) {
       @trigger_error('Calling SqlContentEntityStorageSchema::__construct() with the $entity_field_manager argument is supported in drupal:8.7.0 and will be required before drupal:9.0.0. See https://www.drupal.org/node/2549139.', E_USER_DEPRECATED);
       $entity_field_manager = \Drupal::service('entity_field.manager');
     }
-    $this->fieldStorageDefinitions = $entity_field_manager->getFieldStorageDefinitions($entity_type->id());
-    $this->storage = $storage;
-    $this->database = $database;
+    $this->entityFieldManager = $entity_field_manager;
     if (!$entity_last_installed_schema_repository) {
       @trigger_error('Calling SqlContentEntityStorageSchema::__construct() with the $entity_last_installed_schema_repository argument is supported in drupal:8.7.0 and will be required before drupal:9.0.0. See https://www.drupal.org/node/2549139.', E_USER_DEPRECATED);
       $entity_last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository');
     }
     $this->entityLastInstalledSchemaRepository = $entity_last_installed_schema_repository;
+
+    $this->entityType = $entity_last_installed_schema_repository->getLastInstalledDefinition($entity_type->id());
+    $this->fieldStorageDefinitions = $entity_last_installed_schema_repository->getLastInstalledFieldStorageDefinitions($entity_type->id());
   }
 
   /**
@@ -178,6 +178,31 @@ protected function deletedFieldsRepository() {
     return $this->deletedFieldsRepository;
   }
 
+  /**
+   * Refreshes the table mapping with updated definitions.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+   *   An entity type definition.
+   * @param \Drupal\Core\Field\FieldStorageDefinitionInterface[]|null $storage_definitions
+   *   (optional) An array of field storage definitions. Defaults to the last
+   *   installed field storage definition.
+   *
+   * @return \Drupal\Core\Entity\Sql\DefaultTableMapping
+   *   A table mapping object.
+   */
+  protected function getTableMapping(EntityTypeInterface $entity_type, array $storage_definitions = NULL) {
+    // Allow passing a single field storage definition when updating a field.
+    if ($storage_definitions && count($storage_definitions) === 1) {
+      $storage_definition = reset($storage_definitions);
+      $field_storage_definitions = [$storage_definition->getName() => $storage_definition] + $this->fieldStorageDefinitions;
+    }
+    else {
+      $field_storage_definitions = $storage_definitions ?: $this->fieldStorageDefinitions;
+    }
+
+    return $this->storage->getCustomTableMapping($entity_type, $field_storage_definitions);
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -238,7 +263,7 @@ protected function hasSharedTableNameChanges(EntityTypeInterface $entity_type, E
    * {@inheritdoc}
    */
   public function requiresFieldStorageSchemaChanges(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) {
-    $table_mapping = $this->storage->getTableMapping();
+    $table_mapping = $this->getTableMapping($this->entityType);
 
     if (
       $storage_definition->hasCustomStorage() != $original->hasCustomStorage() ||
@@ -278,7 +303,7 @@ public function requiresFieldStorageSchemaChanges(FieldStorageDefinitionInterfac
    */
   protected function getSchemaFromStorageDefinition(FieldStorageDefinitionInterface $storage_definition) {
     assert(!$storage_definition->hasCustomStorage());
-    $table_mapping = $this->storage->getTableMapping();
+    $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
     $schema = [];
     if ($table_mapping->requiresDedicatedTableStorage($storage_definition)) {
       $schema = $this->getDedicatedTableSchema($storage_definition);
@@ -299,12 +324,6 @@ protected function getSchemaFromStorageDefinition(FieldStorageDefinitionInterfac
    * {@inheritdoc}
    */
   public function requiresEntityDataMigration(EntityTypeInterface $entity_type, EntityTypeInterface $original) {
-    // Check if the entity type specifies that data migration is being handled
-    // elsewhere.
-    if ($entity_type->get('requires_data_migration') === FALSE) {
-      return FALSE;
-    }
-
     // If the original storage has existing entities, or it is impossible to
     // determine if that is the case, require entity data to be migrated.
     $original_storage_class = $original->getStorageClass();
@@ -334,6 +353,11 @@ public function requiresFieldDataMigration(FieldStorageDefinitionInterface $stor
    * {@inheritdoc}
    */
   public function onEntityTypeCreate(EntityTypeInterface $entity_type) {
+    // When installing an entity type, we have to use the live (in-code) entity
+    // type and field storage definitions.
+    $this->entityType = $entity_type;
+    $this->fieldStorageDefinitions = $this->entityFieldManager->getFieldStorageDefinitions($entity_type->id());
+
     $this->checkEntityType($entity_type);
     $schema_handler = $this->database->schema();
 
@@ -346,7 +370,7 @@ public function onEntityTypeCreate(EntityTypeInterface $entity_type) {
     }
 
     // Create dedicated field tables.
-    $table_mapping = $this->storage->getTableMapping($this->fieldStorageDefinitions);
+    $table_mapping = $this->getTableMapping($this->entityType);
     foreach ($this->fieldStorageDefinitions as $field_storage_definition) {
       if ($table_mapping->requiresDedicatedTableStorage($field_storage_definition)) {
         $this->createDedicatedTableSchema($field_storage_definition);
@@ -374,44 +398,20 @@ public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeI
       return;
     }
 
-    // If a migration is required, we can't proceed.
-    if ($this->requiresEntityDataMigration($entity_type, $original)) {
-      throw new EntityStorageException('The SQL storage cannot change the schema for an existing entity type (' . $entity_type->id() . ') with data.');
+    // If shared table schema changes are needed, we can't proceed.
+    if (!class_exists($original->getStorageClass()) || $this->hasSharedTableStructureChange($entity_type, $original)) {
+      throw new EntityStorageException('It is not possible to change the entity type schema outside of a batch context. Use EntityDefinitionUpdateManagerInterface::updateFieldableEntityType() instead.');
     }
 
-    // If we have no data just recreate the entity schema from scratch.
-    if ($this->isTableEmpty($this->storage->getBaseTable())) {
-      if ($this->database->supportsTransactionalDDL()) {
-        // If the database supports transactional DDL, we can go ahead and rely
-        // on it. If not, we will have to rollback manually if something fails.
-        $transaction = $this->database->startTransaction();
-      }
-      try {
-        $this->onEntityTypeDelete($original);
-        $this->onEntityTypeCreate($entity_type);
-      }
-      catch (\Exception $e) {
-        if ($this->database->supportsTransactionalDDL()) {
-          $transaction->rollBack();
-        }
-        else {
-          // Recreate original schema.
-          $this->onEntityTypeCreate($original);
-        }
-        throw $e;
-      }
-    }
-    else {
-      // Drop original indexes and unique keys.
-      $this->deleteEntitySchemaIndexes($this->loadEntitySchemaData($entity_type));
+    // Drop original indexes and unique keys.
+    $this->deleteEntitySchemaIndexes($this->loadEntitySchemaData($entity_type));
 
-      // Create new indexes and unique keys.
-      $entity_schema = $this->getEntitySchema($entity_type, TRUE);
-      $this->createEntitySchemaIndexes($entity_schema);
+    // Create new indexes and unique keys.
+    $entity_schema = $this->getEntitySchema($entity_type, TRUE);
+    $this->createEntitySchemaIndexes($entity_schema);
 
-      // Store the updated entity schema.
-      $this->saveEntitySchemaData($entity_type, $entity_schema);
-    }
+    // Store the updated entity schema.
+    $this->saveEntitySchemaData($entity_type, $entity_schema);
   }
 
   /**
@@ -421,18 +421,15 @@ public function onEntityTypeDelete(EntityTypeInterface $entity_type) {
     $this->checkEntityType($entity_type);
     $schema_handler = $this->database->schema();
 
-    $field_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type->id());
-    $table_mapping = $this->storage->getCustomTableMapping($entity_type, $field_storage_definitions);
-
     // Delete entity and field tables.
-    foreach ($table_mapping->getTableNames() as $table_name) {
+    foreach ($this->getTableMapping($entity_type)->getTableNames() as $table_name) {
       if ($schema_handler->tableExists($table_name)) {
         $schema_handler->dropTable($table_name);
       }
     }
 
     // Delete the field schema data.
-    foreach ($field_storage_definitions as $field_storage_definition) {
+    foreach ($this->fieldStorageDefinitions as $field_storage_definition) {
       $this->deleteFieldSchemaData($field_storage_definition);
     }
 
@@ -485,7 +482,7 @@ protected function preUpdateEntityTypeSchema(EntityTypeInterface $entity_type, E
     // Create dedicated field tables.
     foreach ($field_storage_definitions as $field_storage_definition) {
       if ($temporary_table_mapping->requiresDedicatedTableStorage($field_storage_definition)) {
-        $schema = $this->getDedicatedTableSchema($field_storage_definition);
+        $schema = $this->getDedicatedTableSchema($field_storage_definition, $entity_type);
 
         // Filter out tables which are not part of the table mapping.
         $schema = array_intersect_key($schema, $temporary_table_names);
@@ -620,6 +617,7 @@ public static function getTemporaryTableMappingPrefix(EntityTypeInterface $entit
    * {@inheritdoc}
    */
   public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $storage_definition) {
+    $this->fieldStorageDefinitions[$storage_definition->getName()] = $storage_definition;
     $this->performFieldSchemaOperation('create', $storage_definition);
   }
 
@@ -627,8 +625,6 @@ public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $
    * {@inheritdoc}
    */
   public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) {
-    // Store original definitions so that switching between shared and dedicated
-    // field table layout works.
     $this->performFieldSchemaOperation('update', $storage_definition, $original);
   }
 
@@ -636,20 +632,9 @@ public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $
    * {@inheritdoc}
    */
   public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition) {
-    try {
-      $has_data = $this->storage->countFieldData($storage_definition, TRUE);
-    }
-    catch (DatabaseExceptionWrapper $e) {
-      // This may happen when changing field storage schema, since we are not
-      // able to use a table mapping matching the passed storage definition.
-      // @todo Revisit this once we are able to instantiate the table mapping
-      //   properly. See https://www.drupal.org/node/2274017.
-      return;
-    }
-
     // If the field storage does not have any data, we can safely delete its
     // schema.
-    if (!$has_data) {
+    if (!$this->storage->countFieldData($storage_definition, TRUE)) {
       $this->performFieldSchemaOperation('delete', $storage_definition);
       return;
     }
@@ -659,9 +644,7 @@ public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $
       return;
     }
 
-    // Retrieve a table mapping which contains the deleted field still.
-    $storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($this->entityType->id());
-    $table_mapping = $this->storage->getTableMapping($storage_definitions);
+    $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
     $field_table_name = $table_mapping->getFieldTableName($storage_definition->getName());
 
     if ($table_mapping->requiresDedicatedTableStorage($storage_definition)) {
@@ -683,8 +666,7 @@ public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $
 
       // Refresh the table mapping to use the deleted storage definition.
       $deleted_storage_definition = $this->deletedFieldsRepository()->getFieldStorageDefinitions()[$storage_definition->getUniqueStorageIdentifier()];
-      $original_storage_definitions = [$storage_definition->getName() => $deleted_storage_definition] + $storage_definitions;
-      $table_mapping = $this->storage->getTableMapping($original_storage_definitions);
+      $table_mapping = $this->getTableMapping($this->entityType, [$deleted_storage_definition]);
 
       $dedicated_table_field_schema = $this->getDedicatedTableSchema($deleted_storage_definition);
       $dedicated_table_field_columns = $table_mapping->getColumnNames($deleted_storage_definition->getName());
@@ -873,7 +855,7 @@ protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $res
     if (!isset($this->schema[$entity_type_id]) || $reset) {
       // Prepare basic information about the entity type.
       /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
-      $table_mapping = $this->storage->getCustomTableMapping($entity_type, $this->fieldStorageDefinitions);
+      $table_mapping = $this->getTableMapping($entity_type, $this->fieldStorageDefinitions);
       $tables = $this->getEntitySchemaTables($table_mapping);
 
       // Initialize the table schema.
@@ -922,7 +904,9 @@ protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $res
       // Add an index for the 'published' entity key.
       if (is_subclass_of($entity_type->getClass(), EntityPublishedInterface::class)) {
         $published_key = $entity_type->getKey('published');
-        if ($published_key && !$this->fieldStorageDefinitions[$published_key]->hasCustomStorage()) {
+        if ($published_key
+            && isset($this->fieldStorageDefinitions[$published_key])
+            && !$this->fieldStorageDefinitions[$published_key]->hasCustomStorage()) {
           $published_field_table = $table_mapping->getFieldTableName($published_key);
           $id_key = $entity_type->getKey('id');
           if ($bundle_key = $entity_type->getKey('bundle')) {
@@ -981,7 +965,7 @@ protected function getEntitySchemaData(ContentEntityTypeInterface $entity_type,
     // Collect all possible field schema identifiers for shared table fields.
     // These will be used to detect entity schema data in the subsequent loop.
     $field_schema_identifiers = [];
-    $table_mapping = $this->storage->getTableMapping($this->fieldStorageDefinitions);
+    $table_mapping = $this->getTableMapping($entity_type);
     foreach ($this->fieldStorageDefinitions as $field_name => $storage_definition) {
       if ($table_mapping->allowsSharedTableStorage($storage_definition)) {
         // Make sure both base identifier names and suffixed names are listed.
@@ -1490,7 +1474,7 @@ protected function processFieldStorageSchema(array &$field_storage_schema) {
    *   required) only for updates. Defaults to NULL.
    */
   protected function performFieldSchemaOperation($operation, FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original = NULL) {
-    $table_mapping = $this->storage->getTableMapping();
+    $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
     if ($table_mapping->requiresDedicatedTableStorage($storage_definition)) {
       $this->{$operation . 'DedicatedTableSchema'}($storage_definition, $original);
     }
@@ -1538,7 +1522,7 @@ protected function createDedicatedTableSchema(FieldStorageDefinitionInterface $s
    */
   protected function createSharedTableSchema(FieldStorageDefinitionInterface $storage_definition, $only_save = FALSE) {
     $created_field_name = $storage_definition->getName();
-    $table_mapping = $this->storage->getTableMapping();
+    $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
     $column_names = $table_mapping->getColumnNames($created_field_name);
     $schema_handler = $this->database->schema();
     $shared_table_names = array_diff($table_mapping->getTableNames(), $table_mapping->getDedicatedTableNames());
@@ -1595,7 +1579,11 @@ protected function createSharedTableSchema(FieldStorageDefinitionInterface $stor
     if (!$only_save) {
       // Make sure any entity index involving this field is re-created if
       // needed.
-      $this->createEntitySchemaIndexes($this->getEntitySchema($this->entityType), $storage_definition);
+      $entity_schema = $this->getEntitySchema($this->entityType);
+      $this->createEntitySchemaIndexes($entity_schema, $storage_definition);
+
+      // Store the updated entity schema.
+      $this->saveEntitySchemaData($this->entityType, $entity_schema);
     }
   }
 
@@ -1606,7 +1594,7 @@ protected function createSharedTableSchema(FieldStorageDefinitionInterface $stor
    *   The storage definition of the field being deleted.
    */
   protected function deleteDedicatedTableSchema(FieldStorageDefinitionInterface $storage_definition) {
-    $table_mapping = $this->storage->getTableMapping();
+    $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
     $table_name = $table_mapping->getDedicatedDataTableName($storage_definition, $storage_definition->isDeleted());
     if ($this->database->schema()->tableExists($table_name)) {
       $this->database->schema()->dropTable($table_name);
@@ -1631,9 +1619,7 @@ protected function deleteSharedTableSchema(FieldStorageDefinitionInterface $stor
     $this->deleteEntitySchemaIndexes($this->loadEntitySchemaData($this->entityType), $storage_definition);
 
     $deleted_field_name = $storage_definition->getName();
-    $table_mapping = $this->storage->getTableMapping(
-      $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($this->entityType->id())
-    );
+    $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
     $column_names = $table_mapping->getColumnNames($deleted_field_name);
     $schema_handler = $this->database->schema();
     $shared_table_names = array_diff($table_mapping->getTableNames(), $table_mapping->getDedicatedTableNames());
@@ -1714,7 +1700,7 @@ protected function updateDedicatedTableSchema(FieldStorageDefinitionInterface $s
       // There is data, so there are no column changes. Drop all the prior
       // indexes and create all the new ones, except for all the priors that
       // exist unchanged.
-      $table_mapping = $this->storage->getTableMapping();
+      $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
       $table = $table_mapping->getDedicatedDataTableName($original);
       $revision_table = $table_mapping->getDedicatedRevisionTableName($original);
 
@@ -1804,7 +1790,7 @@ protected function updateSharedTableSchema(FieldStorageDefinitionInterface $stor
       }
 
       $updated_field_name = $storage_definition->getName();
-      $table_mapping = $this->storage->getTableMapping();
+      $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
       $column_names = $table_mapping->getColumnNames($updated_field_name);
       $schema_handler = $this->database->schema();
 
@@ -1879,7 +1865,7 @@ protected function createEntitySchemaIndexes(array $entity_schema, FieldStorageD
     $schema_handler = $this->database->schema();
 
     if ($storage_definition) {
-      $table_mapping = $this->storage->getTableMapping();
+      $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
       $column_names = $table_mapping->getColumnNames($storage_definition->getName());
     }
 
@@ -1938,7 +1924,7 @@ protected function deleteEntitySchemaIndexes(array $entity_schema_data, FieldSto
     $schema_handler = $this->database->schema();
 
     if ($storage_definition) {
-      $table_mapping = $this->storage->getTableMapping();
+      $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
       $column_names = $table_mapping->getColumnNames($storage_definition->getName());
     }
 
@@ -2012,7 +1998,7 @@ protected function hasNullFieldPropertyData($table_name, $column_name) {
    */
   protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $storage_definition, $table_name, array $column_mapping) {
     $schema = [];
-    $table_mapping = $this->storage->getTableMapping();
+    $table_mapping = $this->getTableMapping($this->entityType, [$storage_definition]);
     $field_schema = $storage_definition->getSchema();
 
     // Check that the schema does not include forbidden column names.
@@ -2036,20 +2022,16 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st
       }
 
       if ($initial_value_field_name = $storage_definition->getInitialValueFromField()) {
-        // Check that the field used for populating initial values is valid. We
-        // must use the last installed version of that, as the new field might
-        // be created in an update function and the storage definition of the
-        // "from" field might get changed later.
-        $last_installed_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($this->entityType->id());
-        if (!isset($last_installed_storage_definitions[$initial_value_field_name])) {
+        // Check that the field used for populating initial values is valid.
+        if (!isset($this->fieldStorageDefinitions[$initial_value_field_name])) {
           throw new FieldException("Illegal initial value definition on {$storage_definition->getName()}: The field $initial_value_field_name does not exist.");
         }
 
-        if ($storage_definition->getType() !== $last_installed_storage_definitions[$initial_value_field_name]->getType()) {
+        if ($storage_definition->getType() !== $this->fieldStorageDefinitions[$initial_value_field_name]->getType()) {
           throw new FieldException("Illegal initial value definition on {$storage_definition->getName()}: The field types do not match.");
         }
 
-        if (!$table_mapping->allowsSharedTableStorage($last_installed_storage_definitions[$initial_value_field_name])) {
+        if (!$table_mapping->allowsSharedTableStorage($this->fieldStorageDefinitions[$initial_value_field_name])) {
           throw new FieldException("Illegal initial value definition on {$storage_definition->getName()}: Both fields have to be stored in the shared entity tables.");
         }
 
@@ -2278,7 +2260,7 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor
     // Check that the schema does not include forbidden column names.
     $schema = $storage_definition->getSchema();
     $properties = $storage_definition->getPropertyDefinitions();
-    $table_mapping = $this->storage->getTableMapping();
+    $table_mapping = $this->getTableMapping($entity_type, [$storage_definition]);
     if (array_intersect(array_keys($schema['columns']), $table_mapping->getReservedColumns())) {
       throw new FieldException("Illegal field column names on {$storage_definition->getName()}");
     }
diff --git a/core/lib/Drupal/Core/Field/FieldStorageDefinitionListener.php b/core/lib/Drupal/Core/Field/FieldStorageDefinitionListener.php
index e67629b75932beb6e2829d3361585231995ed7df..6ef363cf2d1bc2c78d614999613e5b9be681e19d 100644
--- a/core/lib/Drupal/Core/Field/FieldStorageDefinitionListener.php
+++ b/core/lib/Drupal/Core/Field/FieldStorageDefinitionListener.php
@@ -7,7 +7,6 @@
 use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\FieldableEntityStorageInterface;
-use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
@@ -82,16 +81,7 @@ public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $
 
     // @todo Forward this to all interested handlers, not only storage, once
     //   iterating handlers is possible: https://www.drupal.org/node/2332857.
-    $storage = clone $this->entityTypeManager->getStorage($entity_type_id);
-
-    // Entity type definition updates can change the schema by adding or
-    // removing entity tables (for example when switching an entity type from
-    // non-revisionable to revisionable), so CRUD operations on a field storage
-    // definition need to use the last installed entity type schema.
-    if ($storage instanceof SqlContentEntityStorage
-       && ($last_installed_entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id))) {
-      $storage->setEntityType($last_installed_entity_type);
-    }
+    $storage = $this->entityTypeManager->getStorage($entity_type_id);
 
     if ($storage instanceof FieldStorageDefinitionListenerInterface) {
       $storage->onFieldStorageDefinitionCreate($storage_definition);
@@ -111,16 +101,7 @@ public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $
 
     // @todo Forward this to all interested handlers, not only storage, once
     //   iterating handlers is possible: https://www.drupal.org/node/2332857.
-    $storage = clone $this->entityTypeManager->getStorage($entity_type_id);
-
-    // Entity type definition updates can change the schema by adding or
-    // removing entity tables (for example when switching an entity type from
-    // non-revisionable to revisionable), so CRUD operations on a field storage
-    // definition need to use the last installed entity type schema.
-    if ($storage instanceof SqlContentEntityStorage
-       && ($last_installed_entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id))) {
-      $storage->setEntityType($last_installed_entity_type);
-    }
+    $storage = $this->entityTypeManager->getStorage($entity_type_id);
 
     if ($storage instanceof FieldStorageDefinitionListenerInterface) {
       $storage->onFieldStorageDefinitionUpdate($storage_definition, $original);
@@ -140,16 +121,7 @@ public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $
 
     // @todo Forward this to all interested handlers, not only storage, once
     //   iterating handlers is possible: https://www.drupal.org/node/2332857.
-    $storage = clone $this->entityTypeManager->getStorage($entity_type_id);
-
-    // Entity type definition updates can change the schema by adding or
-    // removing entity tables (for example when switching an entity type from
-    // non-revisionable to revisionable), so CRUD operations on a field storage
-    // definition need to use the last installed entity type schema.
-    if ($storage instanceof SqlContentEntityStorage
-       && ($last_installed_entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id))) {
-      $storage->setEntityType($last_installed_entity_type);
-    }
+    $storage = $this->entityTypeManager->getStorage($entity_type_id);
 
     // Keep the field definition in the deleted fields repository so we can use
     // it later during field_purge_batch(), but only if the field has data.
diff --git a/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockContentTranslationTest.php b/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockContentTranslationTest.php
index 4078782143baec2b27852c774878b6e358e3c8ec..db255d79f8a8c77f5b2c6b2be68551e091b558f1 100644
--- a/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockContentTranslationTest.php
+++ b/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockContentTranslationTest.php
@@ -35,9 +35,9 @@ class MigrateBlockContentTranslationTest extends MigrateDrupal6TestBase {
    */
   protected function setUp() {
     parent::setUp();
+    $this->installEntitySchema('block_content');
     $this->installConfig(['block']);
     $this->installConfig(['block_content']);
-    $this->installEntitySchema('block_content');
 
     $this->executeMigrations([
       'd6_filter_format',
diff --git a/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockTest.php b/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockTest.php
index feecea04c60ada09fa02c897c720a42a18375f3d..6ea998b0c9ea3405659569fb0f8bed7fa296948e 100644
--- a/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockTest.php
+++ b/core/modules/block/tests/src/Kernel/Migrate/d6/MigrateBlockTest.php
@@ -38,8 +38,8 @@ protected function setUp() {
     // Install the themes used for this test.
     $this->container->get('theme_installer')->install(['bartik', 'test_theme']);
 
-    $this->installConfig(['block_content']);
     $this->installEntitySchema('block_content');
+    $this->installConfig(['block_content']);
 
     // Set Bartik as the default public theme.
     $config = $this->config('system.theme');
diff --git a/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockContentTranslationTest.php b/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockContentTranslationTest.php
index 374d06164ff30b8936dd8320e9c93588c3825906..3201d02b16420d285c1e76837021d9d740abe00a 100644
--- a/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockContentTranslationTest.php
+++ b/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockContentTranslationTest.php
@@ -39,9 +39,9 @@ class MigrateBlockContentTranslationTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
+    $this->installEntitySchema('block_content');
     $this->installConfig(['block']);
     $this->installConfig(['block_content']);
-    $this->installEntitySchema('block_content');
 
     $this->executeMigrations([
       'language',
diff --git a/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockTest.php b/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockTest.php
index d56b9ed19625ff0173bbbf200a93abd46cbdd07e..929854165a3c95b5ebfeaafb78a883215da0139f 100644
--- a/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockTest.php
+++ b/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockTest.php
@@ -37,8 +37,8 @@ protected function setUp() {
     // Install the themes used for this test.
     $this->container->get('theme_installer')->install(['bartik', 'seven']);
 
-    $this->installConfig(static::$modules);
     $this->installEntitySchema('block_content');
+    $this->installConfig(static::$modules);
 
     // Set Bartik and Seven as the default public and admin theme.
     $config = $this->config('system.theme');
diff --git a/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentBodyFieldTest.php b/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentBodyFieldTest.php
index 7d343738c9b7106d08bb62321366393b5f0fbbbc..8eb60a6c446cae9a424b96266ef0ba62fa1f2d02 100644
--- a/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentBodyFieldTest.php
+++ b/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentBodyFieldTest.php
@@ -22,8 +22,8 @@ class MigrateBlockContentBodyFieldTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installConfig(['block_content']);
     $this->installEntitySchema('block_content');
+    $this->installConfig(['block_content']);
     $this->executeMigrations([
       'block_content_type',
       'block_content_body_field',
diff --git a/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentEntityDisplayTest.php b/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentEntityDisplayTest.php
index 5eb9e413d9fb2518d4ba7e808652197aa929322c..5a05637a1c2bfb154b1a93ff857123f5113f59ee 100644
--- a/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentEntityDisplayTest.php
+++ b/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentEntityDisplayTest.php
@@ -22,6 +22,7 @@ class MigrateBlockContentEntityDisplayTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
+    $this->installEntitySchema('block_content');
     $this->installConfig(static::$modules);
     $this->executeMigrations([
       'block_content_type',
diff --git a/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentEntityFormDisplayTest.php b/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentEntityFormDisplayTest.php
index 8fed90584815fcb5bd5b54427bfa357e2f7dc25f..645f70bc97d3225a1a21b6081df7cfaec775bafc 100644
--- a/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentEntityFormDisplayTest.php
+++ b/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentEntityFormDisplayTest.php
@@ -22,6 +22,7 @@ class MigrateBlockContentEntityFormDisplayTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
+    $this->installEntitySchema('block_content');
     $this->installConfig(static::$modules);
     $this->executeMigrations([
       'block_content_type',
diff --git a/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentTypeTest.php b/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentTypeTest.php
index 4accc2040b7011c2a94691ea0aded3472dfd13c9..046284dbf065cd0b334c1cfd792ee82142a22f21 100644
--- a/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentTypeTest.php
+++ b/core/modules/block_content/tests/src/Kernel/Migrate/MigrateBlockContentTypeTest.php
@@ -20,8 +20,8 @@ class MigrateBlockContentTypeTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installConfig(['block_content']);
     $this->installEntitySchema('block_content');
+    $this->installConfig(['block_content']);
     $this->executeMigration('block_content_type');
   }
 
diff --git a/core/modules/block_content/tests/src/Kernel/Migrate/d6/MigrateBlockContentTest.php b/core/modules/block_content/tests/src/Kernel/Migrate/d6/MigrateBlockContentTest.php
index 87e6fac89346331075358b874ada38f7e04ecbc7..40c30a6715ad8d9554ac92963924461714117946 100644
--- a/core/modules/block_content/tests/src/Kernel/Migrate/d6/MigrateBlockContentTest.php
+++ b/core/modules/block_content/tests/src/Kernel/Migrate/d6/MigrateBlockContentTest.php
@@ -22,8 +22,8 @@ class MigrateBlockContentTest extends MigrateDrupal6TestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installConfig(['block_content']);
     $this->installEntitySchema('block_content');
+    $this->installConfig(['block_content']);
 
     $this->executeMigrations([
       'd6_filter_format',
diff --git a/core/modules/block_content/tests/src/Kernel/Migrate/d6/MigrateCustomBlockContentTranslationTest.php b/core/modules/block_content/tests/src/Kernel/Migrate/d6/MigrateCustomBlockContentTranslationTest.php
index 2847e35d5e17dc0c6165cb3fa8708b15b6eecf6e..99bbc4285557335e7fd6bd347fbf507f8e37f020 100644
--- a/core/modules/block_content/tests/src/Kernel/Migrate/d6/MigrateCustomBlockContentTranslationTest.php
+++ b/core/modules/block_content/tests/src/Kernel/Migrate/d6/MigrateCustomBlockContentTranslationTest.php
@@ -28,8 +28,8 @@ class MigrateCustomBlockContentTranslationTest extends MigrateDrupal6TestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installConfig(['block_content']);
     $this->installEntitySchema('block_content');
+    $this->installConfig(['block_content']);
     $this->executeMigrations([
       'language',
       'd6_filter_format',
diff --git a/core/modules/block_content/tests/src/Kernel/Migrate/d7/MigrateCustomBlockContentTranslationTest.php b/core/modules/block_content/tests/src/Kernel/Migrate/d7/MigrateCustomBlockContentTranslationTest.php
index 092eb0a853d44fcda40ae3ebbcb3c4c1fa4b9a97..5f3b98b9c173ca592fb5edeab83ca59c302d5b01 100644
--- a/core/modules/block_content/tests/src/Kernel/Migrate/d7/MigrateCustomBlockContentTranslationTest.php
+++ b/core/modules/block_content/tests/src/Kernel/Migrate/d7/MigrateCustomBlockContentTranslationTest.php
@@ -30,8 +30,8 @@ class MigrateCustomBlockContentTranslationTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installConfig(['block_content']);
     $this->installEntitySchema('block_content');
+    $this->installConfig(['block_content']);
     $this->executeMigrations([
       'language',
       'd7_filter_format',
diff --git a/core/modules/block_content/tests/src/Kernel/Migrate/d7/MigrateCustomBlockTest.php b/core/modules/block_content/tests/src/Kernel/Migrate/d7/MigrateCustomBlockTest.php
index 706a7ccf05cb69d6467035a380d76c6806723136..9147b382e9fdd3f525d040b87d39ad0d16637ced 100644
--- a/core/modules/block_content/tests/src/Kernel/Migrate/d7/MigrateCustomBlockTest.php
+++ b/core/modules/block_content/tests/src/Kernel/Migrate/d7/MigrateCustomBlockTest.php
@@ -24,8 +24,8 @@ class MigrateCustomBlockTest extends MigrateDrupal7TestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installConfig(static::$modules);
     $this->installEntitySchema('block_content');
+    $this->installConfig(static::$modules);
 
     $this->executeMigrations([
       'd7_filter_format',
diff --git a/core/modules/book/tests/src/Kernel/Migrate/d6/MigrateBookTest.php b/core/modules/book/tests/src/Kernel/Migrate/d6/MigrateBookTest.php
index cab65e39c25cd9fc14a7b8695180354d1b501235..c5baf6d032bc98a1a552cbeed716e24db26ef0ce 100644
--- a/core/modules/book/tests/src/Kernel/Migrate/d6/MigrateBookTest.php
+++ b/core/modules/book/tests/src/Kernel/Migrate/d6/MigrateBookTest.php
@@ -15,7 +15,7 @@ class MigrateBookTest extends MigrateDrupal6TestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['book', 'menu_ui'];
+  public static $modules = ['book', 'node', 'menu_ui'];
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/comment/tests/src/Kernel/CommentItemTest.php b/core/modules/comment/tests/src/Kernel/CommentItemTest.php
index 93ccab68db31b9440e0a020165d3f6360d8c7c16..9d6e1644b4b86e7a186031e293b607833ed85348 100644
--- a/core/modules/comment/tests/src/Kernel/CommentItemTest.php
+++ b/core/modules/comment/tests/src/Kernel/CommentItemTest.php
@@ -27,6 +27,7 @@ class CommentItemTest extends FieldKernelTestBase {
 
   protected function setUp() {
     parent::setUp();
+    $this->installEntitySchema('comment');
     $this->installSchema('comment', ['comment_entity_statistics']);
     $this->installConfig(['comment']);
   }
diff --git a/core/modules/comment/tests/src/Kernel/CommentStringIdEntitiesTest.php b/core/modules/comment/tests/src/Kernel/CommentStringIdEntitiesTest.php
index adbe1b08d5ec070b8b19e10f9290419a926408d9..6d72cfe53af3840aaa5b03dc273bd6db84d263f3 100644
--- a/core/modules/comment/tests/src/Kernel/CommentStringIdEntitiesTest.php
+++ b/core/modules/comment/tests/src/Kernel/CommentStringIdEntitiesTest.php
@@ -30,6 +30,7 @@ class CommentStringIdEntitiesTest extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
     $this->installEntitySchema('comment');
+    $this->installEntitySchema('entity_test_string_id');
     $this->installSchema('comment', ['comment_entity_statistics']);
     // Create the comment body field storage.
     $this->installConfig(['field']);
diff --git a/core/modules/contact/tests/modules/contact_storage_test/contact_storage_test.install b/core/modules/contact/tests/modules/contact_storage_test/contact_storage_test.install
index 2468dba6a9897563059cbfc4efd454b3396775b5..324d4330a0d30bbccd530c4e4db3e9b3913ed3de 100644
--- a/core/modules/contact/tests/modules/contact_storage_test/contact_storage_test.install
+++ b/core/modules/contact/tests/modules/contact_storage_test/contact_storage_test.install
@@ -5,19 +5,24 @@
  * Contains install and update hooks.
  */
 
+use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
+
 /**
  * Implements hook_install().
  */
 function contact_storage_test_install() {
-  $entity_type_manager = \Drupal::entityTypeManager();
-  $entity_type = $entity_type_manager->getDefinition('contact_message');
+  $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
 
-  // Recreate the original entity type definition, in order to notify the
-  // manager of what changed. The change of storage backend will trigger
-  // schema installation.
-  // @see contact_storage_test_entity_type_alter()
-  $original = clone $entity_type;
-  $original->setStorageClass('Drupal\Core\Entity\ContentEntityNullStorage');
+  $original = $entity_definition_update_manager->getEntityType('contact_message');
+  $entity_definition_update_manager->uninstallEntityType($original);
 
-  \Drupal::service('entity_type.listener')->onEntityTypeUpdate($entity_type, $original);
+  // Update the entity type definition and make it use the default SQL storage.
+  // @see contact_storage_test_entity_type_alter()
+  $entity_type = clone $original;
+  $entity_type->setStorageClass(SqlContentEntityStorage::class);
+  $keys = $entity_type->getKeys();
+  $keys['id'] = 'id';
+  $entity_type->set('entity_keys', $keys);
+  $entity_type->set('base_table', 'contact_message');
+  $entity_definition_update_manager->installEntityType($entity_type);
 }
diff --git a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
index 1a1b6e46e908aa9e52bf7e94d8b8173605a24ed9..eaa4ad64d9e3705a677d9d2a6731c9bf4103056d 100644
--- a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
+++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
@@ -13,6 +13,7 @@
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
 use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
+use Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait;
 use Drupal\workflows\Entity\Workflow;
 
 /**
@@ -23,6 +24,7 @@
 class ContentModerationStateTest extends KernelTestBase {
 
   use ContentModerationTestTrait;
+  use EntityDefinitionTestTrait;
 
   /**
    * {@inheritdoc}
@@ -529,7 +531,7 @@ public function testNonLangcodeEntityTypeModeration() {
     \Drupal::state()->set('entity_test_rev.entity_type', $entity_type);
 
     // Update the entity type in order to remove the 'langcode' field.
-    \Drupal::entityDefinitionUpdateManager()->applyUpdates();
+    $this->applyEntityUpdates('entity_test_rev');
 
     $workflow = $this->createEditorialWorkflow();
     $workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationTestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationTestBase.php
index e5d04d34187e29349f5f313261252c4bd4a58e8d..e831649c3390b4d91c3249a126d1db76d715c07d 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationTestBase.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationTestBase.php
@@ -177,7 +177,6 @@ protected function enableTranslation() {
 
     \Drupal::entityManager()->clearCachedDefinitions();
     \Drupal::service('router.builder')->rebuild();
-    \Drupal::service('entity.definition_update_manager')->applyUpdates();
   }
 
   /**
diff --git a/core/modules/content_translation/tests/src/Functional/ContentTranslationOperationsTest.php b/core/modules/content_translation/tests/src/Functional/ContentTranslationOperationsTest.php
index 96153d932308b06c1e449f605f094ab21bf48cdd..fc0f788a6a94e045bf8a83a3f6396e9ee9be893b 100644
--- a/core/modules/content_translation/tests/src/Functional/ContentTranslationOperationsTest.php
+++ b/core/modules/content_translation/tests/src/Functional/ContentTranslationOperationsTest.php
@@ -51,7 +51,6 @@ protected function setUp() {
     \Drupal::service('content_translation.manager')->setEnabled('node', 'article', TRUE);
 
     \Drupal::service('router.builder')->rebuild();
-    \Drupal::service('entity.definition_update_manager')->applyUpdates();
 
     $this->baseUser1 = $this->drupalCreateUser(['access content overview']);
     $this->baseUser2 = $this->drupalCreateUser(['access content overview', 'create content translations', 'update content translations', 'delete content translations']);
diff --git a/core/modules/content_translation/tests/src/Functional/ContentTranslationTestBase.php b/core/modules/content_translation/tests/src/Functional/ContentTranslationTestBase.php
index 044e341ea071281f039c46f15ea28a36d49ae5d5..de6cef999c16dd7315b260860e3c246783b7e748 100644
--- a/core/modules/content_translation/tests/src/Functional/ContentTranslationTestBase.php
+++ b/core/modules/content_translation/tests/src/Functional/ContentTranslationTestBase.php
@@ -170,7 +170,6 @@ protected function enableTranslation() {
     \Drupal::service('content_translation.manager')->setEnabled($this->entityTypeId, $this->bundle, TRUE);
 
     \Drupal::service('router.builder')->rebuild();
-    \Drupal::service('entity.definition_update_manager')->applyUpdates();
   }
 
   /**
diff --git a/core/modules/field/tests/modules/field_test/field_test.entity.inc b/core/modules/field/tests/modules/field_test/field_test.entity.inc
index f3fcff4b4865e4729d9c2d00fcc2d4b1e97cfac0..f62b3252c6442292876ec897462a60ef5bf33ade 100644
--- a/core/modules/field/tests/modules/field_test/field_test.entity.inc
+++ b/core/modules/field/tests/modules/field_test/field_test.entity.inc
@@ -21,13 +21,13 @@ function field_test_entity_type_alter(array &$entity_types) {
 function field_test_entity_info_translatable($entity_type_id = NULL, $translatable = NULL) {
   $stored_value = &drupal_static(__FUNCTION__, []);
   if (isset($entity_type_id)) {
-    $entity_type_manager = \Drupal::entityTypeManager();
-    $original = $entity_type_manager->getDefinition($entity_type_id);
+    $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
+    $entity_type = $entity_definition_update_manager->getEntityType($entity_type_id);
     $stored_value[$entity_type_id] = $translatable;
-    if ($translatable != $original->isTranslatable()) {
-      $entity_type_manager->clearCachedDefinitions();
-      $entity_type = $entity_type_manager->getDefinition($entity_type_id);
-      \Drupal::service('entity_type.listener')->onEntityTypeUpdate($entity_type, $original);
+    if ($translatable != $entity_type->isTranslatable()) {
+      $entity_definition_update_manager->uninstallEntityType($entity_type);
+      $entity_type->set('translatable', $translatable);
+      $entity_definition_update_manager->installEntityType($entity_type);
     }
   }
   return $stored_value;
diff --git a/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceFieldTranslatedReferenceViewTest.php b/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceFieldTranslatedReferenceViewTest.php
index 4719c29cdb08f7d4f25e32c62d03d5befd9db766..56945d962d8114c8d3eb860280ac2b282a9c2b1d 100644
--- a/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceFieldTranslatedReferenceViewTest.php
+++ b/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceFieldTranslatedReferenceViewTest.php
@@ -224,7 +224,6 @@ protected function enableTranslation() {
     \Drupal::service('content_translation.manager')->setEnabled($this->testEntityTypeName, $this->referencedType->id(), TRUE);
 
     \Drupal::service('router.builder')->rebuild();
-    \Drupal::service('entity.definition_update_manager')->applyUpdates();
   }
 
   /**
diff --git a/core/modules/field/tests/src/Kernel/ConfigFieldDefinitionTest.php b/core/modules/field/tests/src/Kernel/ConfigFieldDefinitionTest.php
index a2a2c21d1e6b836658b4c9e33290ae7d6a3900fb..988998f7745d3af0f6c008a0a5413d666536437f 100644
--- a/core/modules/field/tests/src/Kernel/ConfigFieldDefinitionTest.php
+++ b/core/modules/field/tests/src/Kernel/ConfigFieldDefinitionTest.php
@@ -43,6 +43,7 @@ protected function setUp() {
     $this->entityManager = $this->container->get('entity.manager');
 
     // Create a second field on 'entity_test_rev'.
+    $this->installEntitySchema('entity_test_rev');
     $this->createFieldWithStorage('_rev', 'entity_test_rev', 'entity_test_rev');
   }
 
diff --git a/core/modules/field/tests/src/Kernel/Entity/Update/SqlContentEntityStorageSchemaColumnTest.php b/core/modules/field/tests/src/Kernel/Entity/Update/SqlContentEntityStorageSchemaColumnTest.php
index 05db0dc5ccf693c4576e388b13e374c42b139875..cd79d843a088f4edd5533714e161bb079740d9cd 100644
--- a/core/modules/field/tests/src/Kernel/Entity/Update/SqlContentEntityStorageSchemaColumnTest.php
+++ b/core/modules/field/tests/src/Kernel/Entity/Update/SqlContentEntityStorageSchemaColumnTest.php
@@ -7,6 +7,7 @@
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\KernelTests\KernelTestBase;
+use Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait;
 
 /**
  * Tests that schema changes in fields with data are detected during updates.
@@ -15,6 +16,8 @@
  */
 class SqlContentEntityStorageSchemaColumnTest extends KernelTestBase {
 
+  use EntityDefinitionTestTrait;
+
   /**
    * {@inheritdoc}
    */
@@ -88,7 +91,9 @@ public function testColumnUpdate() {
     // Now attempt to run automatic updates. An exception should be thrown
     // since there is data in the table.
     try {
-      \Drupal::service('entity.definition_update_manager')->applyUpdates();
+      $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
+      $field_storage_definition = $entity_definition_update_manager->getFieldStorageDefinition('test', 'entity_test_rev');
+      $entity_definition_update_manager->updateFieldStorageDefinition($field_storage_definition);
       $this->fail('Failed to detect a schema change in a field with data.');
     }
     catch (FieldStorageDefinitionUpdateForbiddenException $e) {
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldFormatterSettingsTest.php b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldFormatterSettingsTest.php
index 7347c0470db171f9b3c07c64fe2cade0fa2a0c80..220be8c2fc4f4f48666177a5f0e01f04680a88f7 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldFormatterSettingsTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldFormatterSettingsTest.php
@@ -15,7 +15,7 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal6TestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['menu_ui'];
+  public static $modules = ['menu_ui', 'node'];
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php
index c01aa2f2a9dc0f5375a8ba1e1efe3939fa3e69e3..6f2ef1d32a98f57f5b1cec1909f61f663dd19c1a 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceTest.php
@@ -17,7 +17,7 @@ class MigrateFieldInstanceTest extends MigrateDrupal6TestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['menu_ui'];
+  public static $modules = ['menu_ui', 'node'];
 
   /**
    * Tests migration of file variables to file.settings.yml.
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateViewModesTest.php b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateViewModesTest.php
index 0a7e9dcc0dd33556051e31fb8a51d5796be6ab09..518720ceb7190cb2d758cd39283211504f33bd48 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateViewModesTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d7/MigrateViewModesTest.php
@@ -13,7 +13,7 @@
  */
 class MigrateViewModesTest extends MigrateDrupal7TestBase {
 
-  public static $modules = ['comment', 'node', 'taxonomy'];
+  public static $modules = ['comment', 'node', 'taxonomy', 'text'];
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/field/tests/src/Kernel/Migrate/d7/RollbackViewModesTest.php b/core/modules/field/tests/src/Kernel/Migrate/d7/RollbackViewModesTest.php
index b069387cfc6a8caefef56c34b5bb25bb54a361f8..8c454792d0e8301b690c564a607e335a0fb0322a 100644
--- a/core/modules/field/tests/src/Kernel/Migrate/d7/RollbackViewModesTest.php
+++ b/core/modules/field/tests/src/Kernel/Migrate/d7/RollbackViewModesTest.php
@@ -12,6 +12,11 @@
  */
 class RollbackViewModesTest extends MigrateViewModesTest {
 
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['text'];
+
   /**
    * Tests migrating D7 view modes, then rolling back.
    */
diff --git a/core/modules/field/tests/src/Kernel/TranslationTest.php b/core/modules/field/tests/src/Kernel/TranslationTest.php
index 5d03f6917144af0c74093396ef5611161988332f..1a101b79ee38ed624ea936a1f5d2d90093921215 100644
--- a/core/modules/field/tests/src/Kernel/TranslationTest.php
+++ b/core/modules/field/tests/src/Kernel/TranslationTest.php
@@ -72,6 +72,7 @@ class TranslationTest extends FieldKernelTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->installEntitySchema('node');
     $this->installConfig(['language']);
 
     $this->fieldName = mb_strtolower($this->randomMachineName());
diff --git a/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
index 5ee2d406d28ecff0a3ef822cfd93d16c880ce833..5f0b5f1f1b17dd660fe1cabdaec7139de43c1dec 100644
--- a/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
+++ b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
@@ -32,6 +32,7 @@ class EntityDisplayTest extends KernelTestBase {
 
   protected function setUp() {
     parent::setUp();
+    $this->installEntitySchema('entity_test');
     $this->installEntitySchema('node');
     $this->installEntitySchema('user');
     $this->installConfig(['field', 'node', 'user']);
diff --git a/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php b/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php
index c1d22b7423491a786fac07ad77a129682072b58f..2baee4df6aa6674ff3526027d3454915f7d1ca03 100644
--- a/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php
+++ b/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php
@@ -24,6 +24,7 @@ class EntityFormDisplayTest extends KernelTestBase {
 
   protected function setUp() {
     parent::setUp();
+    $this->installEntitySchema('entity_test');
   }
 
   /**
diff --git a/core/modules/file/tests/src/Kernel/FileItemValidationTest.php b/core/modules/file/tests/src/Kernel/FileItemValidationTest.php
index ba763b665411e7217fa49415821f1ef0379c7027..6fbc82f39afd02f44c531ee481be6164fd728bff 100644
--- a/core/modules/file/tests/src/Kernel/FileItemValidationTest.php
+++ b/core/modules/file/tests/src/Kernel/FileItemValidationTest.php
@@ -35,6 +35,7 @@ class FileItemValidationTest extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->installEntitySchema('entity_test');
     $this->installEntitySchema('user');
     $this->installEntitySchema('file');
     $this->installSchema('file', 'file_usage');
diff --git a/core/modules/image/tests/src/Kernel/ImageStyleIntegrationTest.php b/core/modules/image/tests/src/Kernel/ImageStyleIntegrationTest.php
index 9898ad309ceb0deaa2e98ebf1df4903e39daa18a..74fa6431b5d365cace260529b7231601e61b5c4b 100644
--- a/core/modules/image/tests/src/Kernel/ImageStyleIntegrationTest.php
+++ b/core/modules/image/tests/src/Kernel/ImageStyleIntegrationTest.php
@@ -22,6 +22,14 @@ class ImageStyleIntegrationTest extends KernelTestBase {
    */
   public static $modules = ['image', 'file', 'field', 'system', 'user', 'node'];
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('node');
+  }
+
   /**
    * Tests the dependency between ImageStyle and entity display components.
    */
diff --git a/core/modules/image/tests/src/Kernel/Views/ImageViewsDataTest.php b/core/modules/image/tests/src/Kernel/Views/ImageViewsDataTest.php
index a324d5ead346947c54703185ad7115f318b347af..b7fe074a6b217df2f377669a70de00b214a4f463 100644
--- a/core/modules/image/tests/src/Kernel/Views/ImageViewsDataTest.php
+++ b/core/modules/image/tests/src/Kernel/Views/ImageViewsDataTest.php
@@ -21,6 +21,15 @@ class ImageViewsDataTest extends ViewsKernelTestBase {
    */
   public static $modules = ['image', 'file', 'views', 'entity_test', 'user', 'field'];
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+    $this->installEntitySchema('entity_test');
+    $this->installEntitySchema('entity_test_mul');
+  }
+
   /**
    * Tests views data generated for image field relationship.
    *
diff --git a/core/modules/locale/tests/src/Functional/LocaleTranslatedSchemaDefinitionTest.php b/core/modules/locale/tests/src/Functional/LocaleTranslatedSchemaDefinitionTest.php
index 39d7c3d53360a7fce2003a42bcd57105b11cc3b3..3e39f74626a43451b6da9ffbe38e8f4f5c6b274d 100644
--- a/core/modules/locale/tests/src/Functional/LocaleTranslatedSchemaDefinitionTest.php
+++ b/core/modules/locale/tests/src/Functional/LocaleTranslatedSchemaDefinitionTest.php
@@ -26,8 +26,7 @@ protected function setUp() {
     parent::setUp();
     ConfigurableLanguage::createFromLangcode('fr')->save();
     $this->config('system.site')->set('default_langcode', 'fr')->save();
-    // Make sure new entity type definitions are processed.
-    \Drupal::service('entity.definition_update_manager')->applyUpdates();
+
     // Clear all caches so that the base field definition, its cache in the
     // entity manager, the t() cache, etc. are all cleared.
     drupal_flush_all_caches();
diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/EntityRevisionTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/EntityRevisionTest.php
index d15446fbad90974c1184aa7a72f814c29764716d..e2b6052d1afaa9c78714ca3197e5fa830af35d84 100644
--- a/core/modules/migrate/tests/src/Kernel/Plugin/EntityRevisionTest.php
+++ b/core/modules/migrate/tests/src/Kernel/Plugin/EntityRevisionTest.php
@@ -35,10 +35,10 @@ class EntityRevisionTest extends MigrateTestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installConfig('node');
-    $this->installSchema('node', ['node_access']);
     $this->installEntitySchema('node');
     $this->installEntitySchema('user');
+    $this->installConfig('node');
+    $this->installSchema('node', ['node_access']);
   }
 
   /**
diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationPluginListTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationPluginListTest.php
index b256e3f3a3eaff7b95ae12bb828283177615a04a..1a340e4e43fcafdc3ded621c06340893089c3027 100644
--- a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationPluginListTest.php
+++ b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationPluginListTest.php
@@ -60,6 +60,15 @@ class MigrationPluginListTest extends KernelTestBase {
     'user',
   ];
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installEntitySchema('user');
+  }
+
   /**
    * @covers ::getDefinitions
    */
diff --git a/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php b/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php
index 063c99cb36473f234336648ed0f4515a5d20f400..f361fb16ef705203a1ea6130d3cff24fa06be5bf 100644
--- a/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php
+++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php
@@ -22,7 +22,21 @@ abstract class MigrateDrupalTestBase extends MigrateTestBase {
    */
   protected function setUp() {
     parent::setUp();
-    $this->installEntitySchema('user');
+
+    $module_handler = \Drupal::moduleHandler();
+    if ($module_handler->moduleExists('node')) {
+      $this->installEntitySchema('node');
+    }
+    if ($module_handler->moduleExists('comment')) {
+      $this->installEntitySchema('comment');
+    }
+    if ($module_handler->moduleExists('taxonomy')) {
+      $this->installEntitySchema('taxonomy_term');
+    }
+    if ($module_handler->moduleExists('user')) {
+      $this->installEntitySchema('user');
+    }
+
     $this->installConfig(['migrate_drupal', 'system']);
   }
 
diff --git a/core/modules/options/tests/src/Kernel/Views/FileViewsDataTest.php b/core/modules/options/tests/src/Kernel/Views/FileViewsDataTest.php
index c5f2902d055d1c351cd71a31c4f74adca8e1e8e0..416af440e4cdca013887c5ce68c9906a85c7cb75 100644
--- a/core/modules/options/tests/src/Kernel/Views/FileViewsDataTest.php
+++ b/core/modules/options/tests/src/Kernel/Views/FileViewsDataTest.php
@@ -21,6 +21,15 @@ class FileViewsDataTest extends ViewsKernelTestBase {
    */
   public static $modules = ['file', 'views', 'entity_test', 'user', 'field'];
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+    $this->installEntitySchema('entity_test');
+    $this->installEntitySchema('entity_test_mul');
+  }
+
   /**
    * Tests views data generated for file field relationship.
    *
diff --git a/core/modules/options/tests/src/Kernel/Views/ViewsDataTest.php b/core/modules/options/tests/src/Kernel/Views/ViewsDataTest.php
index d0235986c4273f7e09ca515b9f6b0b2ae1f25f30..31554f852a66bd68218b3f6bea939045fb194c46 100644
--- a/core/modules/options/tests/src/Kernel/Views/ViewsDataTest.php
+++ b/core/modules/options/tests/src/Kernel/Views/ViewsDataTest.php
@@ -30,6 +30,7 @@ class ViewsDataTest extends OptionsTestBase {
   protected function setUp($import_test_views = TRUE) {
     parent::setUp();
 
+    $this->installEntitySchema('entity_test');
     $field_name = 'test_options';
     $this->fieldStorage = FieldStorageConfig::create([
       'field_name' => $field_name,
diff --git a/core/modules/responsive_image/tests/src/Kernel/ResponsiveImageIntegrationTest.php b/core/modules/responsive_image/tests/src/Kernel/ResponsiveImageIntegrationTest.php
index d48129122b8e929e16862a189b14acf9ba5e20f4..f935a4e2de2cc257990bfdc372c3bc3e59220b01 100644
--- a/core/modules/responsive_image/tests/src/Kernel/ResponsiveImageIntegrationTest.php
+++ b/core/modules/responsive_image/tests/src/Kernel/ResponsiveImageIntegrationTest.php
@@ -18,7 +18,15 @@ class ResponsiveImageIntegrationTest extends KernelTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['responsive_image', 'field', 'image', 'file', 'entity_test', 'breakpoint', 'responsive_image_test_module'];
+  public static $modules = ['responsive_image', 'field', 'image', 'file', 'entity_test', 'breakpoint', 'responsive_image_test_module', 'user'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('entity_test');
+  }
 
   /**
    * Tests integration with entity view display.
diff --git a/core/modules/simpletest/src/Tests/KernelTestBaseTest.php b/core/modules/simpletest/src/Tests/KernelTestBaseTest.php
index fc0d918b8af58ea6bbdf0b8cdbbec89f2e2502ba..2be141b4076d1f719a228b2f529ad67b0e86b2d7 100644
--- a/core/modules/simpletest/src/Tests/KernelTestBaseTest.php
+++ b/core/modules/simpletest/src/Tests/KernelTestBaseTest.php
@@ -270,6 +270,7 @@ public function testEnableModulesFixedList() {
     $this->enableModules(['field_test']);
 
     // Create a field.
+    $this->installEntitySchema('entity_test');
     $display = EntityViewDisplay::create([
       'targetEntityType' => 'entity_test',
       'bundle' => 'entity_test',
diff --git a/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.module b/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.module
index 5931b9b598bc8285670afad1130fcbe123116f27..2cf69167d08a2e59366ffa827ab75374a4fec0f1 100644
--- a/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.module
+++ b/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.module
@@ -18,10 +18,10 @@
 function entity_schema_test_entity_type_alter(array &$entity_types) {
   // Allow a test to tell us whether or not to alter the entity type.
   if (\Drupal::state()->get('entity_schema_update')) {
-    $entity_type = $entity_types['entity_test'];
+    $entity_type = $entity_types['entity_test_update'];
     if ($entity_type instanceof ContentEntityTypeInterface) {
       $entity_type->set('translatable', TRUE);
-      $entity_type->set('data_table', 'entity_test_field_data');
+      $entity_type->set('data_table', 'entity_test_update_data');
       // Update the keys with a revision ID.
       $keys = $entity_type->getKeys();
       $keys['revision'] = 'revision_id';
@@ -40,7 +40,7 @@ function entity_schema_test_entity_type_alter(array &$entity_types) {
  * Implements hook_entity_base_field_info().
  */
 function entity_schema_test_entity_base_field_info(EntityTypeInterface $entity_type) {
-  if ($entity_type->id() == 'entity_test') {
+  if ($entity_type->id() == 'entity_test_update') {
     $definitions['custom_base_field'] = BaseFieldDefinition::create('string')
       ->setName('custom_base_field')
       ->setLabel(t('A custom base field'));
@@ -60,10 +60,11 @@ function entity_schema_test_entity_base_field_info(EntityTypeInterface $entity_t
  * Implements hook_entity_field_storage_info().
  */
 function entity_schema_test_entity_field_storage_info(EntityTypeInterface $entity_type) {
-  if ($entity_type->id() == 'entity_test') {
+  if ($entity_type->id() == 'entity_test_update') {
     $definitions['custom_bundle_field'] = FieldStorageDefinition::create('string')
       ->setName('custom_bundle_field')
       ->setLabel(t('A custom bundle field'))
+      ->setRevisionable(TRUE)
       ->setTargetEntityTypeId($entity_type->id());
     return $definitions;
   }
@@ -73,7 +74,7 @@ function entity_schema_test_entity_field_storage_info(EntityTypeInterface $entit
  * Implements hook_entity_bundle_field_info().
  */
 function entity_schema_test_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle) {
-  if ($entity_type->id() == 'entity_test' && $bundle == 'custom') {
+  if ($entity_type->id() == 'entity_test_update' && $bundle == 'custom') {
     /** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $custom_bundle_field_storage */
     $custom_bundle_field_storage = entity_schema_test_entity_field_storage_info($entity_type)['custom_bundle_field'];
     $definitions[$custom_bundle_field_storage->getName()] = FieldDefinition::createFromFieldStorageDefinition($custom_bundle_field_storage);
@@ -85,7 +86,7 @@ function entity_schema_test_entity_bundle_field_info(EntityTypeInterface $entity
  * Implements hook_entity_bundle_create().
  */
 function entity_schema_test_entity_bundle_create($entity_type_id, $bundle) {
-  if ($entity_type_id == 'entity_test' && $bundle == 'custom') {
+  if ($entity_type_id == 'entity_test_update' && $bundle == 'custom') {
     $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_type_id, $bundle);
     // Notify the entity storage that we just created a new field.
     \Drupal::service('field_definition.listener')->onFieldDefinitionCreate($field_definitions['custom_bundle_field']);
@@ -96,7 +97,7 @@ function entity_schema_test_entity_bundle_create($entity_type_id, $bundle) {
  * Implements hook_entity_bundle_delete().
  */
 function entity_schema_test_entity_bundle_delete($entity_type_id, $bundle) {
-  if ($entity_type_id == 'entity_test' && $bundle == 'custom') {
+  if ($entity_type_id == 'entity_test_update' && $bundle == 'custom') {
     $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_type_id, $bundle);
     // Notify the entity storage that our field is gone.
     \Drupal::service('field_definition.listener')->onFieldDefinitionDelete($field_definitions['custom_bundle_field']);
diff --git a/core/modules/system/tests/modules/entity_test/tests/src/Functional/Rest/EntityTestResourceTestBase.php b/core/modules/system/tests/modules/entity_test/tests/src/Functional/Rest/EntityTestResourceTestBase.php
index 2210f97d6fc6919bad88e906bb8124d7281b5b06..6ea99984795dc5ddf35920a800230bda0babcbae 100644
--- a/core/modules/system/tests/modules/entity_test/tests/src/Functional/Rest/EntityTestResourceTestBase.php
+++ b/core/modules/system/tests/modules/entity_test/tests/src/Functional/Rest/EntityTestResourceTestBase.php
@@ -5,12 +5,14 @@
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
 use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
+use Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait;
 use Drupal\Tests\Traits\ExpectDeprecationTrait;
 use Drupal\user\Entity\User;
 
 abstract class EntityTestResourceTestBase extends EntityResourceTestBase {
 
   use BcTimestampNormalizerUnixTestTrait;
+  use EntityDefinitionTestTrait;
   use ExpectDeprecationTrait;
 
   /**
@@ -58,7 +60,7 @@ protected function createEntity() {
     // Set flag so that internal field 'internal_string_field' is created.
     // @see entity_test_entity_base_field_info()
     $this->container->get('state')->set('entity_test.internal_field', TRUE);
-    \Drupal::entityDefinitionUpdateManager()->applyUpdates();
+    $this->applyEntityUpdates('entity_test');
 
     $entity_test = EntityTest::create([
       'name' => 'Llama',
diff --git a/core/modules/system/tests/src/Functional/Entity/Traits/EntityDefinitionTestTrait.php b/core/modules/system/tests/src/Functional/Entity/Traits/EntityDefinitionTestTrait.php
index 6d42ed936ab06eb97afee4ab9921d4630fc434fb..00148b466baba5117159af0eb2a0d532be83b08a 100644
--- a/core/modules/system/tests/src/Functional/Entity/Traits/EntityDefinitionTestTrait.php
+++ b/core/modules/system/tests/src/Functional/Entity/Traits/EntityDefinitionTestTrait.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\system\Functional\Entity\Traits;
 
+use Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\entity_test\FieldStorageDefinition;
@@ -11,98 +12,208 @@
  */
 trait EntityDefinitionTestTrait {
 
+  /**
+   * Applies all the detected valid changes.
+   *
+   * Use this with care, as it will apply updates for any module, which will
+   * lead to unpredictable results.
+   *
+   * @param string $entity_type_id
+   *   (optional) Applies changes only for the specified entity type ID.
+   *   Defaults to NULL.
+   */
+  protected function applyEntityUpdates($entity_type_id = NULL) {
+    $complete_change_list = \Drupal::entityDefinitionUpdateManager()->getChangeList();
+    if ($complete_change_list) {
+      // In case there are changes, explicitly invalidate caches.
+      \Drupal::entityTypeManager()->clearCachedDefinitions();
+      \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
+    }
+
+    if ($entity_type_id) {
+      $complete_change_list = array_intersect_key($complete_change_list, [$entity_type_id => TRUE]);
+    }
+
+    foreach ($complete_change_list as $entity_type_id => $change_list) {
+      // Process entity type definition changes before storage definitions ones
+      // this is necessary when you change an entity type from non-revisionable
+      // to revisionable and at the same time add revisionable fields to the
+      // entity type.
+      if (!empty($change_list['entity_type'])) {
+        $this->doEntityUpdate($change_list['entity_type'], $entity_type_id);
+      }
+
+      // Process field storage definition changes.
+      if (!empty($change_list['field_storage_definitions'])) {
+        $storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type_id);
+        $original_storage_definitions = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledFieldStorageDefinitions($entity_type_id);
+
+        foreach ($change_list['field_storage_definitions'] as $field_name => $change) {
+          $storage_definition = isset($storage_definitions[$field_name]) ? $storage_definitions[$field_name] : NULL;
+          $original_storage_definition = isset($original_storage_definitions[$field_name]) ? $original_storage_definitions[$field_name] : NULL;
+          $this->doFieldUpdate($change, $storage_definition, $original_storage_definition);
+        }
+      }
+    }
+  }
+
+  /**
+   * Performs an entity type definition update.
+   *
+   * @param string $op
+   *   The operation to perform, either static::DEFINITION_CREATED or
+   *   static::DEFINITION_UPDATED.
+   * @param string $entity_type_id
+   *   The entity type ID.
+   */
+  protected function doEntityUpdate($op, $entity_type_id) {
+    $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_type_id);
+    $field_storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type_id);
+    switch ($op) {
+      case EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED:
+        \Drupal::service('entity_type.listener')->onEntityTypeCreate($entity_type);
+        break;
+
+      case EntityDefinitionUpdateManagerInterface::DEFINITION_UPDATED:
+        $original = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledDefinition($entity_type_id);
+        $original_field_storage_definitions = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledFieldStorageDefinitions($entity_type_id);
+
+        \Drupal::service('entity_type.listener')->onFieldableEntityTypeUpdate($entity_type, $original, $field_storage_definitions, $original_field_storage_definitions);
+        break;
+    }
+  }
+
+  /**
+   * Performs a field storage definition update.
+   *
+   * @param string $op
+   *   The operation to perform, possible values are static::DEFINITION_CREATED,
+   *   static::DEFINITION_UPDATED or static::DEFINITION_DELETED.
+   * @param array|null $storage_definition
+   *   The new field storage definition.
+   * @param array|null $original_storage_definition
+   *   The original field storage definition.
+   */
+  protected function doFieldUpdate($op, $storage_definition = NULL, $original_storage_definition = NULL) {
+    switch ($op) {
+      case EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED:
+        \Drupal::service('field_storage_definition.listener')->onFieldStorageDefinitionCreate($storage_definition);
+        break;
+
+      case EntityDefinitionUpdateManagerInterface::DEFINITION_UPDATED:
+        \Drupal::service('field_storage_definition.listener')->onFieldStorageDefinitionUpdate($storage_definition, $original_storage_definition);
+        break;
+
+      case EntityDefinitionUpdateManagerInterface::DEFINITION_DELETED:
+        \Drupal::service('field_storage_definition.listener')->onFieldStorageDefinitionDelete($original_storage_definition);
+        break;
+    }
+  }
+
   /**
    * Enables a new entity type definition.
    */
   protected function enableNewEntityType() {
     $this->state->set('entity_test_new', TRUE);
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates('entity_test_new');
   }
 
   /**
    * Resets the entity type definition.
    */
   protected function resetEntityType() {
-    $this->state->set('entity_test_update.entity_type', NULL);
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $updated_entity_type = $this->getUpdatedEntityTypeDefinition(FALSE, FALSE);
+    $updated_field_storage_definitions = $this->getUpdatedFieldStorageDefinitions(FALSE, FALSE);
+    $this->entityDefinitionUpdateManager->updateFieldableEntityType($updated_entity_type, $updated_field_storage_definitions);
   }
 
   /**
    * Updates the 'entity_test_update' entity type to revisionable.
+   *
+   * @param bool $perform_update
+   *   (optional) Whether the change should be performed by the entity
+   *   definition update manager.
    */
-  protected function updateEntityTypeToRevisionable() {
-    $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_update');
+  protected function updateEntityTypeToRevisionable($perform_update = FALSE) {
+    $translatable = $this->entityDefinitionUpdateManager->getEntityType('entity_test_update')->isTranslatable();
 
-    $keys = $entity_type->getKeys();
-    $keys['revision'] = 'revision_id';
-    $entity_type->set('entity_keys', $keys);
-    $entity_type->set('revision_table', 'entity_test_update_revision');
+    $updated_entity_type = $this->getUpdatedEntityTypeDefinition(TRUE, $translatable);
+    $updated_field_storage_definitions = $this->getUpdatedFieldStorageDefinitions(TRUE, $translatable);
 
-    $this->state->set('entity_test_update.entity_type', $entity_type);
+    if ($perform_update) {
+      $this->entityDefinitionUpdateManager->updateFieldableEntityType($updated_entity_type, $updated_field_storage_definitions);
+    }
   }
 
   /**
    * Updates the 'entity_test_update' entity type not revisionable.
+   *
+   * @param bool $perform_update
+   *   (optional) Whether the change should be performed by the entity
+   *   definition update manager.
    */
-  protected function updateEntityTypeToNotRevisionable() {
-    $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_update');
+  protected function updateEntityTypeToNotRevisionable($perform_update = FALSE) {
+    $translatable = $this->entityDefinitionUpdateManager->getEntityType('entity_test_update')->isTranslatable();
 
-    $keys = $entity_type->getKeys();
-    unset($keys['revision']);
-    $entity_type->set('entity_keys', $keys);
-    $entity_type->set('revision_table', NULL);
+    $updated_entity_type = $this->getUpdatedEntityTypeDefinition(FALSE, $translatable);
+    $updated_field_storage_definitions = $this->getUpdatedFieldStorageDefinitions(FALSE, $translatable);
 
-    $this->state->set('entity_test_update.entity_type', $entity_type);
+    if ($perform_update) {
+      $this->entityDefinitionUpdateManager->updateFieldableEntityType($updated_entity_type, $updated_field_storage_definitions);
+    }
   }
 
   /**
    * Updates the 'entity_test_update' entity type to translatable.
+   *
+   * @param bool $perform_update
+   *   (optional) Whether the change should be performed by the entity
+   *   definition update manager.
    */
-  protected function updateEntityTypeToTranslatable() {
-    $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_update');
+  protected function updateEntityTypeToTranslatable($perform_update = FALSE) {
+    $revisionable = $this->entityDefinitionUpdateManager->getEntityType('entity_test_update')->isRevisionable();
 
-    $entity_type->set('translatable', TRUE);
-    $entity_type->set('data_table', 'entity_test_update_data');
+    $updated_entity_type = $this->getUpdatedEntityTypeDefinition($revisionable, TRUE);
+    $updated_field_storage_definitions = $this->getUpdatedFieldStorageDefinitions($revisionable, TRUE);
 
-    if ($entity_type->isRevisionable()) {
-      $entity_type->set('revision_data_table', 'entity_test_update_revision_data');
+    if ($perform_update) {
+      $this->entityDefinitionUpdateManager->updateFieldableEntityType($updated_entity_type, $updated_field_storage_definitions);
     }
-
-    $this->state->set('entity_test_update.entity_type', $entity_type);
   }
 
   /**
    * Updates the 'entity_test_update' entity type to not translatable.
+   *
+   * @param bool $perform_update
+   *   (optional) Whether the change should be performed by the entity
+   *   definition update manager.
    */
-  protected function updateEntityTypeToNotTranslatable() {
-    $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_update');
+  protected function updateEntityTypeToNotTranslatable($perform_update = FALSE) {
+    $revisionable = $this->entityDefinitionUpdateManager->getEntityType('entity_test_update')->isRevisionable();
 
-    $entity_type->set('translatable', FALSE);
-    $entity_type->set('data_table', NULL);
+    $updated_entity_type = $this->getUpdatedEntityTypeDefinition($revisionable, FALSE);
+    $updated_field_storage_definitions = $this->getUpdatedFieldStorageDefinitions($revisionable, FALSE);
 
-    if ($entity_type->isRevisionable()) {
-      $entity_type->set('revision_data_table', NULL);
+    if ($perform_update) {
+      $this->entityDefinitionUpdateManager->updateFieldableEntityType($updated_entity_type, $updated_field_storage_definitions);
     }
-
-    $this->state->set('entity_test_update.entity_type', $entity_type);
   }
 
   /**
    * Updates the 'entity_test_update' entity type to revisionable and
    * translatable.
+   *
+   * @param bool $perform_update
+   *   (optional) Whether the change should be performed by the entity
+   *   definition update manager.
    */
-  protected function updateEntityTypeToRevisionableAndTranslatable() {
-    $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_update');
-
-    $keys = $entity_type->getKeys();
-    $keys['revision'] = 'revision_id';
-    $entity_type->set('entity_keys', $keys);
-    $entity_type->set('translatable', TRUE);
-    $entity_type->set('data_table', 'entity_test_update_data');
-    $entity_type->set('revision_table', 'entity_test_update_revision');
-    $entity_type->set('revision_data_table', 'entity_test_update_revision_data');
+  protected function updateEntityTypeToRevisionableAndTranslatable($perform_update = FALSE) {
+    $updated_entity_type = $this->getUpdatedEntityTypeDefinition(TRUE, TRUE);
+    $updated_field_storage_definitions = $this->getUpdatedFieldStorageDefinitions(TRUE, TRUE);
 
-    $this->state->set('entity_test_update.entity_type', $entity_type);
+    if ($perform_update) {
+      $this->entityDefinitionUpdateManager->updateFieldableEntityType($updated_entity_type, $updated_field_storage_definitions);
+    }
   }
 
   /**
@@ -309,7 +420,7 @@ protected function deleteEntityType() {
    *   An entity type definition.
    */
   protected function getUpdatedEntityTypeDefinition($revisionable = FALSE, $translatable = FALSE) {
-    $entity_type = clone $this->entityManager->getDefinition('entity_test_update');
+    $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_update');
 
     if ($revisionable) {
       $keys = $entity_type->getKeys();
@@ -364,7 +475,8 @@ protected function getUpdatedEntityTypeDefinition($revisionable = FALSE, $transl
    *   An array of field storage definition objects.
    */
   protected function getUpdatedFieldStorageDefinitions($revisionable = FALSE, $translatable = FALSE) {
-    $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions('entity_test_update');
+    /** @var \Drupal\Core\Field\BaseFieldDefinition[] $field_storage_definitions */
+    $field_storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('entity_test_update');
 
     if ($revisionable) {
       // The 'langcode' is already available for the 'entity_test_update' entity
diff --git a/core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php b/core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php
index 38672c4d590e8e38f545529edb24680f2a153d7f..07352cbc07e9ec5829ccbb1b56d3988e5dca4c8d 100644
--- a/core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php
+++ b/core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait;
 use Drupal\Tests\system\Functional\Update\DbUpdatesTrait;
 
 /**
@@ -14,27 +15,19 @@
 class UpdateApiEntityDefinitionUpdateTest extends BrowserTestBase {
 
   use DbUpdatesTrait;
+  use EntityDefinitionTestTrait;
 
   /**
    * {@inheritdoc}
    */
   protected static $modules = ['entity_test'];
 
-  /**
-   * The entity definition update manager.
-   *
-   * @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface
-   */
-  protected $updatesManager;
-
   /**
    * {@inheritdoc}
    */
   protected function setUp() {
     parent::setUp();
 
-    $this->updatesManager = $this->container->get('entity.definition_update_manager');
-
     $admin = $this->drupalCreateUser([], FALSE, TRUE);
     $this->drupalLogin($admin);
   }
@@ -157,7 +150,7 @@ public function testStatusReport() {
 
     // Apply the entity updates and check that the entity update status report
     // item is no longer displayed.
-    $this->updatesManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->drupalGet('admin/reports/status');
     $this->assertNoRaw('Out of date');
     $this->assertNoRaw('Mismatched entity and/or field definitions');
diff --git a/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php b/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php
index 8f538795ef7de0c7a0c7d310698bfd5130e28c4b..da215d4c7d6f4f7c70e838b9570b41572afd0109 100644
--- a/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php
+++ b/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php
@@ -43,7 +43,6 @@ protected function setUp() {
     parent::setUp();
     $this->updateUrl = Url::fromRoute('system.db_update');
     $this->updateUser = $this->drupalCreateUser(['administer software updates', 'access site in maintenance mode']);
-    \Drupal::service('entity.definition_update_manager')->applyUpdates();
   }
 
   /**
diff --git a/core/modules/system/tests/src/Kernel/Entity/EntityReferenceSelectionReferenceableTest.php b/core/modules/system/tests/src/Kernel/Entity/EntityReferenceSelectionReferenceableTest.php
index 15a53decf8caf00a654ff00c24d4ff3b8d85b85b..0a33a88c6459682660ad2eca14f3d8891bfc58ba 100644
--- a/core/modules/system/tests/src/Kernel/Entity/EntityReferenceSelectionReferenceableTest.php
+++ b/core/modules/system/tests/src/Kernel/Entity/EntityReferenceSelectionReferenceableTest.php
@@ -50,6 +50,7 @@ protected function setUp() {
     parent::setUp();
 
     $this->installEntitySchema('entity_test_no_label');
+    $this->installEntitySchema('node');
 
     /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
     $storage = $this->container->get('entity.manager')
diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php b/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php
index 98d5906fb9bee64f2e29dcb9850a1f96a881798d..84e4a0b01b51e3efac5b6fa0a7f8da025f7f3ffa 100644
--- a/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php
+++ b/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php
@@ -73,7 +73,6 @@ protected function enableTranslation() {
     drupal_static_reset();
     \Drupal::entityManager()->clearCachedDefinitions();
     \Drupal::service('router.builder')->rebuild();
-    \Drupal::service('entity.definition_update_manager')->applyUpdates();
   }
 
   /**
diff --git a/core/modules/taxonomy/tests/src/Functional/TaxonomyTranslationTestTrait.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyTranslationTestTrait.php
index 3b0490218032cd9dfe93497a895588cd0ae9f7e9..f81b4606f15bf794df1d0371c5d55834c710a91c 100644
--- a/core/modules/taxonomy/tests/src/Functional/TaxonomyTranslationTestTrait.php
+++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyTranslationTestTrait.php
@@ -67,7 +67,6 @@ protected function enableTranslation() {
     \Drupal::service('content_translation.manager')->setEnabled('taxonomy_term', $this->vocabulary->id(), TRUE);
     drupal_static_reset();
     \Drupal::service('router.builder')->rebuild();
-    \Drupal::service('entity.definition_update_manager')->applyUpdates();
   }
 
   /**
diff --git a/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermViewTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermViewTest.php
index 6e56881716701921c8615cbd1e9ed002c5a6c684..5e537e5126320b07ac0ee231ef5debd5d56b6185 100644
--- a/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermViewTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermViewTest.php
@@ -102,7 +102,6 @@ public function testTaxonomyTermView() {
       ->save();
     drupal_static_reset();
     \Drupal::service('router.builder')->rebuild();
-    \Drupal::service('entity.definition_update_manager')->applyUpdates();
 
     $edit['title[0][value]'] = $translated_title = $this->randomMachineName();
 
diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyVocabularyTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyVocabularyTest.php
index 189394d66bf3eb8374c22396a2a85beb75c39d70..3aae9a3593851af5399cbe51906e10a196afa2d7 100644
--- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyVocabularyTest.php
+++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyVocabularyTest.php
@@ -16,7 +16,7 @@ class MigrateTaxonomyVocabularyTest extends MigrateDrupal7TestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['taxonomy'];
+  public static $modules = ['taxonomy', 'text'];
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/taxonomy/tests/src/Kernel/Views/TaxonomyTestBase.php b/core/modules/taxonomy/tests/src/Kernel/Views/TaxonomyTestBase.php
index d45df78d56483ff74e591f44e1c2f8db66dcf2bf..3512b7760769c0a1bb0f89a005b17fa6954c416a 100644
--- a/core/modules/taxonomy/tests/src/Kernel/Views/TaxonomyTestBase.php
+++ b/core/modules/taxonomy/tests/src/Kernel/Views/TaxonomyTestBase.php
@@ -78,6 +78,7 @@ protected function setUp($import_test_views = TRUE) {
     parent::setUp($import_test_views);
 
     // Install node config to create body field.
+    $this->installEntitySchema('node');
     $this->installConfig(['node', 'filter']);
     $this->installEntitySchema('user');
     $this->installEntitySchema('taxonomy_term');
diff --git a/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
index 179dbf38d64bdf89481e7fd7bec501ca840d7639..7a75c3cb2fd60c0d7916fc2e7c2aec5ab097c94a 100644
--- a/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
@@ -34,9 +34,7 @@ class BaseFieldAccessTest extends ViewTestBase {
    */
   protected function setUp($import_test_views = TRUE) {
     parent::setUp($import_test_views);
-    /** @var \Drupal\Core\Entity\EntityDefinitionUpdateManager $update_manager */
-    $update_manager = $this->container->get('entity.definition_update_manager');
-    $update_manager->applyUpdates();
+
     ViewTestData::createTestViews(get_class($this), ['comment_test_views']);
     \Drupal::state()->set('entity_test.views_data', [
       'entity_test' => [
diff --git a/core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php b/core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php
index 192dc2f75fb2626a5f85012574fa4e2d16d7962c..d2230a0efe7425aafd00971ff996d8867d6ce137 100644
--- a/core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php
+++ b/core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php
@@ -91,8 +91,7 @@ public function testDeleteEntityType() {
     $entity_storage = $this->entityTypeManager->getStorage('view');
 
     // Make the test entity type revisionable.
-    $this->updateEntityTypeToRevisionable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToRevisionable(TRUE);
 
     $views = $entity_storage->loadMultiple();
 
@@ -128,7 +127,7 @@ public function testDeleteEntityType() {
    */
   public function testBaseTableRename() {
     $this->renameBaseTable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates('entity_test_update');
 
     /** @var \Drupal\views\Entity\View $view */
     $entity_storage = $this->entityTypeManager->getStorage('view');
@@ -145,8 +144,7 @@ public function testBaseTableRename() {
    * Tests that renaming data tables adapts the views.
    */
   public function testDataTableRename() {
-    $this->updateEntityTypeToTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToTranslatable(TRUE);
 
     $entity_storage = $this->entityTypeManager->getStorage('view');
     $view = $entity_storage->load('test_view_entity_test_data');
@@ -157,7 +155,7 @@ public function testDataTableRename() {
     $this->assertEqual('entity_test_update_data', $display['display_options']['fields']['name']['table']);
 
     $this->renameDataTable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates('entity_test_update');
 
     /** @var \Drupal\views\Entity\View $view */
     $entity_storage = $this->entityTypeManager->getStorage('view');
@@ -174,8 +172,7 @@ public function testDataTableRename() {
    * Tests that renaming revision tables adapts the views.
    */
   public function testRevisionBaseTableRename() {
-    $this->updateEntityTypeToRevisionable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToRevisionable(TRUE);
 
     /** @var \Drupal\views\Entity\View $view */
     $entity_storage = $this->entityTypeManager->getStorage('view');
@@ -186,7 +183,7 @@ public function testRevisionBaseTableRename() {
     $this->assertEqual('entity_test_update_revision', $display['display_options']['fields']['name']['table']);
 
     $this->renameRevisionBaseTable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates('entity_test_update');
 
     /** @var \Drupal\views\Entity\View $view */
     $entity_storage = $this->entityTypeManager->getStorage('view');
@@ -203,12 +200,7 @@ public function testRevisionBaseTableRename() {
    * Tests that renaming revision tables adapts the views.
    */
   public function testRevisionDataTableRename() {
-    $this->updateEntityTypeToRevisionable();
-    // Multiple changes, so we have to invalidate the caches, otherwise
-    // the second update will revert the first.
-    $this->entityTypeManager->clearCachedDefinitions();
-    $this->updateEntityTypeToTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToRevisionableAndTranslatable(TRUE);
 
     /** @var \Drupal\views\Entity\View $view */
     $entity_storage = $this->entityTypeManager->getStorage('view');
@@ -219,7 +211,7 @@ public function testRevisionDataTableRename() {
     $this->assertEqual('entity_test_update_revision_data', $display['display_options']['fields']['name']['table']);
 
     $this->renameRevisionDataTable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates('entity_test_update');
 
     /** @var \Drupal\views\Entity\View $view */
     $entity_storage = $this->entityTypeManager->getStorage('view');
@@ -236,8 +228,7 @@ public function testRevisionDataTableRename() {
    * Tests that adding data tables adapts the views.
    */
   public function testDataTableAddition() {
-    $this->updateEntityTypeToTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToTranslatable(TRUE);
 
     /** @var \Drupal\views\Entity\View $view */
     $entity_storage = $this->entityTypeManager->getStorage('view');
@@ -254,8 +245,7 @@ public function testDataTableAddition() {
    * Tests that enabling revisions doesn't do anything.
    */
   public function testRevisionEnabling() {
-    $this->updateEntityTypeToRevisionable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToRevisionable(TRUE);
 
     /** @var \Drupal\views\Entity\View $view */
     $entity_storage = $this->entityTypeManager->getStorage('view');
@@ -272,11 +262,8 @@ public function testRevisionEnabling() {
    * Tests that removing revision support disables the view.
    */
   public function testRevisionDisabling() {
-    $this->updateEntityTypeToRevisionable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
-
-    $this->updateEntityTypeToNotRevisionable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToRevisionable(TRUE);
+    $this->updateEntityTypeToNotRevisionable(TRUE);
 
     /** @var \Drupal\views\Entity\View $view */
     $entity_storage = $this->entityTypeManager->getStorage('view');
@@ -297,16 +284,14 @@ public function testVariousTableUpdates() {
     // base <-> base + translation + revision
 
     // base <-> base + translation
-    $this->updateEntityTypeToTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToTranslatable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
     $this->assertEqual('entity_test_update', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update_data', $display['display_options']['fields']['name']['table']);
 
-    $this->updateEntityTypeToNotTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToNotTranslatable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
@@ -316,24 +301,21 @@ public function testVariousTableUpdates() {
     $this->resetEntityType();
 
     // base + translation <-> base + translation + revision
-    $this->updateEntityTypeToTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToTranslatable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
     $this->assertEqual('entity_test_update', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update_data', $display['display_options']['fields']['name']['table']);
 
-    $this->updateEntityTypeToRevisionable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToRevisionable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
     $this->assertEqual('entity_test_update', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update_data', $display['display_options']['fields']['name']['table']);
 
-    $this->updateEntityTypeToNotRevisionable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToNotRevisionable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
@@ -350,16 +332,14 @@ public function testVariousTableUpdates() {
     $this->assertEqual('entity_test_update', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update', $display['display_options']['fields']['name']['table']);
 
-    $this->updateEntityTypeToTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToTranslatable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
     $this->assertEqual('entity_test_update', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update_data', $display['display_options']['fields']['name']['table']);
 
-    $this->updateEntityTypeToNotTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToNotTranslatable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
@@ -369,16 +349,14 @@ public function testVariousTableUpdates() {
     $this->resetEntityType();
 
     // base <-> base + revision
-    $this->updateEntityTypeToRevisionable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToRevisionable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
     $this->assertEqual('entity_test_update', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update', $display['display_options']['fields']['name']['table']);
 
-    $this->updateEntityTypeToNotRevisionable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToNotRevisionable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
@@ -388,18 +366,16 @@ public function testVariousTableUpdates() {
     $this->resetEntityType();
 
     // base <-> base + translation + revision
-    $this->updateEntityTypeToRevisionable();
-    $this->updateEntityTypeToTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToRevisionable(TRUE);
+    $this->updateEntityTypeToTranslatable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
     $this->assertEqual('entity_test_update', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update_data', $display['display_options']['fields']['name']['table']);
 
-    $this->updateEntityTypeToNotRevisionable();
-    $this->updateEntityTypeToNotTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToNotRevisionable(TRUE);
+    $this->updateEntityTypeToNotTranslatable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay();
 
     $this->assertEqual('entity_test_update', $view->get('base_table'));
@@ -412,10 +388,7 @@ public function testVariousTableUpdates() {
    */
   public function testVariousTableUpdatesForRevisionView() {
     // base + revision <-> base + translation + revision
-    $this->updateEntityTypeToRevisionable();
-    // Multiple changes, so we have to invalidate the caches, otherwise
-    // the second update will revert the first.
-    $this->entityTypeManager->clearCachedDefinitions();
+    $this->updateEntityTypeToRevisionable(TRUE);
 
     list($view, $display) = $this->getUpdatedViewAndDisplay(TRUE);
 
@@ -423,23 +396,19 @@ public function testVariousTableUpdatesForRevisionView() {
     $this->assertEqual('entity_test_update_revision', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update_revision', $display['display_options']['fields']['name']['table']);
 
-    $this->updateEntityTypeToTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToTranslatable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay(TRUE);
 
     $this->assertEqual('entity_test_update_revision', $view->get('base_table'));
     $this->assertEqual('entity_test_update_revision', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update_revision_data', $display['display_options']['fields']['name']['table']);
 
-    $this->updateEntityTypeToNotTranslatable();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToNotTranslatable(TRUE);
     list($view, $display) = $this->getUpdatedViewAndDisplay(TRUE);
 
     $this->assertEqual('entity_test_update_revision', $view->get('base_table'));
     $this->assertEqual('entity_test_update_revision', $display['display_options']['fields']['id']['table']);
     $this->assertEqual('entity_test_update_revision', $display['display_options']['fields']['name']['table']);
-
-    $this->resetEntityType();
   }
 
   /**
diff --git a/core/modules/views/tests/src/Kernel/ModuleTest.php b/core/modules/views/tests/src/Kernel/ModuleTest.php
index 1333c6225b9828357988ecb5a22fe97d36354428..3ea46f0dd06f1ae14932b9454c76e7993eea944c 100644
--- a/core/modules/views/tests/src/Kernel/ModuleTest.php
+++ b/core/modules/views/tests/src/Kernel/ModuleTest.php
@@ -139,6 +139,7 @@ public function customErrorHandler($error_level, $message, $filename, $line, $co
    */
   public function testLoadFunctions() {
     $this->enableModules(['text', 'node']);
+    $this->installEntitySchema('node');
     $this->installConfig(['node']);
     $storage = $this->container->get('entity.manager')->getStorage('view');
 
diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php
index 294bb0f44c2efd356eafe8a50ba5cf0acabd08c5..5d6b078ead416f96cb3986a5475783f27915a632 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php
@@ -31,6 +31,7 @@ class ViewsConfigDependenciesIntegrationTest extends ViewsKernelTestBase {
   protected function setUp($import_test_views = TRUE) {
     parent::setUp($import_test_views);
 
+    $this->installEntitySchema('entity_test');
     $this->installEntitySchema('user');
     $this->installSchema('user', ['users_data']);
   }
diff --git a/core/modules/workspaces/tests/src/Kernel/WorkspaceIntegrationTest.php b/core/modules/workspaces/tests/src/Kernel/WorkspaceIntegrationTest.php
index 1252a672b36dcc8c7dc1275f1b32ca2628bde730..2678d899904c84659ac97907b39a71ac15852d5b 100644
--- a/core/modules/workspaces/tests/src/Kernel/WorkspaceIntegrationTest.php
+++ b/core/modules/workspaces/tests/src/Kernel/WorkspaceIntegrationTest.php
@@ -65,16 +65,16 @@ protected function setUp() {
 
     $this->entityTypeManager = \Drupal::entityTypeManager();
 
-    $this->installConfig(['filter', 'node', 'system']);
-
-    $this->installSchema('system', ['key_value_expire', 'sequences']);
-    $this->installSchema('node', ['node_access']);
-
     $this->installEntitySchema('entity_test_mulrev');
     $this->installEntitySchema('entity_test_mulrevpub');
     $this->installEntitySchema('node');
     $this->installEntitySchema('user');
 
+    $this->installConfig(['filter', 'node', 'system']);
+
+    $this->installSchema('system', ['key_value_expire', 'sequences']);
+    $this->installSchema('node', ['node_access']);
+
     $this->createContentType(['type' => 'page']);
 
     $this->setCurrentUser($this->createUser(['administer nodes']));
diff --git a/core/tests/Drupal/KernelTests/Core/Datetime/TimestampSchemaTest.php b/core/tests/Drupal/KernelTests/Core/Datetime/TimestampSchemaTest.php
index 43fbd42f4cb9971f63ef39c8324facd2cb7b4248..977f8af20b1654a73f17ef829e77bcadf5e2ccc4 100644
--- a/core/tests/Drupal/KernelTests/Core/Datetime/TimestampSchemaTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Datetime/TimestampSchemaTest.php
@@ -14,7 +14,15 @@ class TimestampSchemaTest extends KernelTestBase {
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['entity_test', 'field', 'field_timestamp_test'];
+  protected static $modules = ['entity_test', 'field', 'field_timestamp_test', 'user'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('entity_test');
+  }
 
   /**
    * Tests if the timestamp field schema is validated.
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNonRevisionableFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNonRevisionableFieldTest.php
index 99c99b068836e79fcbeeb1fdc0e914cc1eeaeab6..510369b941938e66a2100dd40dfca7ea3fc0cfec 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNonRevisionableFieldTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNonRevisionableFieldTest.php
@@ -5,6 +5,7 @@
 use Drupal\entity_test\Entity\EntityTestMulRev;
 use Drupal\entity_test\Entity\EntityTestRev;
 use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait;
 
 /**
  * Tests non-revisionable fields on revisionable (and translatable) entities.
@@ -13,6 +14,8 @@
  */
 class ContentEntityNonRevisionableFieldTest extends EntityKernelTestBase {
 
+  use EntityDefinitionTestTrait;
+
   /**
    * Modules to enable.
    *
@@ -179,7 +182,7 @@ public function testNonRevisionableField() {
    */
   public function testMultiColumnNonRevisionableBaseField() {
     \Drupal::state()->set('entity_test.multi_column', TRUE);
-    \Drupal::entityDefinitionUpdateManager()->applyUpdates();
+    $this->applyEntityUpdates('entity_test_mulrev');
     // Refresh the storage.
     $this->mulRev = $this->entityManager->getStorage('entity_test_mulrev');
     $user1 = $this->createUser();
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php
index baa97845755ebccd8e615dbaaf7884a9aa1fbf67..a484b974e3f94135e51af803b053d9cb205fdd25 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait;
 
 /**
  * Tests the default table mapping class for content entities stored in SQL.
@@ -16,6 +17,8 @@
  */
 class DefaultTableMappingIntegrationTest extends EntityKernelTestBase {
 
+  use EntityDefinitionTestTrait;
+
   /**
    * The table mapping for the tested entity type.
    *
@@ -49,7 +52,7 @@ protected function setUp() {
     $this->tableMapping = $this->entityTypeManager->getStorage('entity_test_mulrev')->getTableMapping();
 
     // Ensure that the tables for the new field are created.
-    \Drupal::entityDefinitionUpdateManager()->applyUpdates();
+    $this->applyEntityUpdates('entity_test_mulrev');
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityBundleFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityBundleFieldTest.php
index 16c555d0e7068d43b4b538199a844ceb7a2831e6..774db4b36b6b584bb6a00bf05722bcafab0426a0 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityBundleFieldTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityBundleFieldTest.php
@@ -14,7 +14,7 @@ class EntityBundleFieldTest extends EntityKernelTestBase {
    *
    * @var array
    */
-  public static $modules = ['entity_schema_test'];
+  public static $modules = ['entity_schema_test', 'entity_test_update'];
 
   /**
    * The module handler.
@@ -36,6 +36,7 @@ class EntityBundleFieldTest extends EntityKernelTestBase {
   protected function setUp() {
     parent::setUp();
     $this->installSchema('user', ['users_data']);
+    $this->installEntitySchema('entity_test_update');
     $this->moduleHandler = $this->container->get('module_handler');
     $this->database = $this->container->get('database');
   }
@@ -44,13 +45,13 @@ protected function setUp() {
    * Tests making use of a custom bundle field.
    */
   public function testCustomBundleFieldUsage() {
-    entity_test_create_bundle('custom');
+    entity_test_create_bundle('custom', NULL, 'entity_test_update');
 
     // Check that an entity with bundle entity_test does not have the custom
     // field.
-    $storage = $this->entityManager->getStorage('entity_test');
+    $storage = $this->entityManager->getStorage('entity_test_update');
     $entity = $storage->create([
-      'type' => 'entity_test',
+      'type' => 'entity_test_update',
     ]);
     $this->assertFalse($entity->hasField('custom_bundle_field'));
 
@@ -63,7 +64,7 @@ public function testCustomBundleFieldUsage() {
 
     // Ensure that the field exists in the field map.
     $field_map = \Drupal::entityManager()->getFieldMap();
-    $this->assertEqual($field_map['entity_test']['custom_bundle_field'], ['type' => 'string', 'bundles' => ['custom' => 'custom']]);
+    $this->assertEqual($field_map['entity_test_update']['custom_bundle_field'], ['type' => 'string', 'bundles' => ['custom' => 'custom']]);
 
     $entity->custom_bundle_field->value = 'swanky';
     $entity->save();
@@ -91,7 +92,7 @@ public function testCustomBundleFieldUsage() {
     // bundle is deleted.
     $entity = $storage->create(['type' => 'custom', 'custom_bundle_field' => 'new']);
     $entity->save();
-    entity_test_delete_bundle('custom');
+    entity_test_delete_bundle('custom', 'entity_test_update');
 
     $table = $table_mapping->getDedicatedDataTableName($entity->getFieldDefinition('custom_bundle_field')->getFieldStorageDefinition(), TRUE);
     $result = $this->database->select($table, 'f')
@@ -103,7 +104,7 @@ public function testCustomBundleFieldUsage() {
 
     // Ensure that the field no longer exists in the field map.
     $field_map = \Drupal::entityManager()->getFieldMap();
-    $this->assertFalse(isset($field_map['entity_test']['custom_bundle_field']));
+    $this->assertFalse(isset($field_map['entity_test_update']['custom_bundle_field']));
 
     // Purge field data, and check that the storage definition has been
     // completely removed once the data is purged.
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
index 39c24d2f25043236cbbaba4950317b74e7b810a9..f33d6a3ce87d1f22805e899eca4fcb01ca5c0552 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
@@ -91,10 +91,7 @@ public function testNoUpdates() {
     // Ensure that the definition update manager reports no updates.
     $this->assertFalse($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that no updates are needed.');
     $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), [], 'EntityDefinitionUpdateManager reports an empty change summary.');
-
-    // Ensure that applyUpdates() runs without error (it's not expected to do
-    // anything when there aren't updates).
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeList(), [], 'EntityDefinitionUpdateManager reports an empty change list.');
   }
 
   /**
@@ -121,26 +118,23 @@ public function testEntityTypeUpdateWithoutData() {
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
 
     // Run the update and ensure the revision table is created.
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->updateEntityTypeToRevisionable(TRUE);
     $this->assertTrue($this->database->schema()->tableExists('entity_test_update_revision'), 'Revision table created for entity_test_update.');
   }
 
   /**
-   * Tests updating entity schema when there are existing entities.
+   * Tests updating entity schema when there are entity storage changes.
    */
-  public function testEntityTypeUpdateWithData() {
-    // Save an entity.
-    $this->entityManager->getStorage('entity_test_update')->create()->save();
-
+  public function testEntityTypeUpdateWithEntityStorageChange() {
     // Update the entity type to be revisionable and try to apply the update.
     // It's expected to throw an exception.
-    $this->updateEntityTypeToRevisionable();
+    $entity_type = $this->getUpdatedEntityTypeDefinition(TRUE, FALSE);
     try {
-      $this->entityDefinitionUpdateManager->applyUpdates();
-      $this->fail('EntityStorageException thrown when trying to apply an update that requires data migration.');
+      $this->entityDefinitionUpdateManager->updateEntityType($entity_type);
+      $this->fail('EntityStorageException thrown when trying to apply an update that requires shared table schema changes.');
     }
     catch (EntityStorageException $e) {
-      $this->pass('EntityStorageException thrown when trying to apply an update that requires data migration.');
+      $this->pass('EntityStorageException thrown when trying to apply an update that requires shared table schema changes.');
     }
   }
 
@@ -158,7 +152,7 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() {
       ],
     ];
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertTrue($this->database->schema()->fieldExists('entity_test_update', 'new_base_field'), 'Column created in shared table for new_base_field.');
 
     // Add an index on the base field, ensure the update manager reports it,
@@ -171,7 +165,7 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() {
       ],
     ];
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update_field__new_base_field'), 'Index created.');
 
     // Remove the above index, ensure the update manager reports it, and the
@@ -184,7 +178,7 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() {
       ],
     ];
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertFalse($this->database->schema()->indexExists('entity_test_update', 'entity_test_update_field__new_base_field'), 'Index deleted.');
 
     // Update the type of the base field from 'string' to 'text', ensure the
@@ -198,7 +192,7 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() {
       ],
     ];
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertFalse($this->database->schema()->fieldExists('entity_test_update', 'new_base_field'), 'Original column deleted in shared table for new_base_field.');
     $this->assertTrue($this->database->schema()->fieldExists('entity_test_update', 'new_base_field__value'), 'Value column created in shared table for new_base_field.');
     $this->assertTrue($this->database->schema()->fieldExists('entity_test_update', 'new_base_field__format'), 'Format column created in shared table for new_base_field.');
@@ -213,7 +207,7 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() {
       ],
     ];
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertFalse($this->database->schema()->fieldExists('entity_test_update', 'new_base_field_value'), 'Value column deleted from shared table for new_base_field.');
     $this->assertFalse($this->database->schema()->fieldExists('entity_test_update', 'new_base_field_format'), 'Format column deleted from shared table for new_base_field.');
   }
@@ -232,7 +226,7 @@ public function testBundleFieldCreateUpdateDeleteWithoutData() {
       ],
     ];
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertTrue($this->database->schema()->tableExists('entity_test_update__new_bundle_field'), 'Dedicated table created for new_bundle_field.');
 
     // Update the type of the base field from 'string' to 'text', ensure the
@@ -246,7 +240,7 @@ public function testBundleFieldCreateUpdateDeleteWithoutData() {
       ],
     ];
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertTrue($this->database->schema()->fieldExists('entity_test_update__new_bundle_field', 'new_bundle_field_format'), 'Format column created in dedicated table for new_base_field.');
 
     // Remove the bundle field, ensure the update manager reports it, and the
@@ -259,7 +253,7 @@ public function testBundleFieldCreateUpdateDeleteWithoutData() {
       ],
     ];
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertFalse($this->database->schema()->tableExists('entity_test_update__new_bundle_field'), 'Dedicated table deleted for new_bundle_field.');
   }
 
@@ -281,7 +275,7 @@ public function testBaseFieldCreateDeleteWithExistingEntities() {
     // Add a base field and run the update. Ensure the base field's column is
     // created and the prior saved entity data is still there.
     $this->addBaseField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $schema_handler = $this->database->schema();
     $this->assertTrue($schema_handler->fieldExists('entity_test_update', 'new_base_field'), 'Column created in shared table for new_base_field.');
     $entity = $this->entityManager->getStorage('entity_test_update')->load($entity->id());
@@ -290,7 +284,7 @@ public function testBaseFieldCreateDeleteWithExistingEntities() {
     // Remove the base field and run the update. Ensure the base field's column
     // is deleted and the prior saved entity data is still there.
     $this->removeBaseField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertFalse($schema_handler->fieldExists('entity_test_update', 'new_base_field'), 'Column deleted from shared table for new_base_field.');
     $entity = $this->entityManager->getStorage('entity_test_update')->load($entity->id());
     $this->assertIdentical($entity->name->value, $name, 'Entity data preserved during field deletion.');
@@ -298,7 +292,7 @@ public function testBaseFieldCreateDeleteWithExistingEntities() {
     // Add a base field with a required property and run the update. Ensure
     // 'not null' is not applied and thus no exception is thrown.
     $this->addBaseField('shape_required');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $assert = $schema_handler->fieldExists('entity_test_update', 'new_base_field__shape') && $schema_handler->fieldExists('entity_test_update', 'new_base_field__color');
     $this->assertTrue($assert, 'Columns created in shared table for new_base_field.');
 
@@ -308,11 +302,11 @@ public function testBaseFieldCreateDeleteWithExistingEntities() {
     //   definitions. See https://www.drupal.org/node/2390495.
     $entity->delete();
     $this->removeBaseField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $assert = !$schema_handler->fieldExists('entity_test_update', 'new_base_field__shape') && !$schema_handler->fieldExists('entity_test_update', 'new_base_field__color');
     $this->assert($assert, 'Columns removed from the shared table for new_base_field.');
     $this->addBaseField('shape_required');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $assert = $schema_handler->fieldExists('entity_test_update', 'new_base_field__shape') && $schema_handler->fieldExists('entity_test_update', 'new_base_field__color');
     $this->assertTrue($assert, 'Columns created again in shared table for new_base_field.');
     $entity = $storage->create(['name' => $name]);
@@ -338,7 +332,7 @@ public function testBundleFieldCreateDeleteWithExistingEntities() {
     // Add a bundle field and run the update. Ensure the bundle field's table
     // is created and the prior saved entity data is still there.
     $this->addBundleField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $schema_handler = $this->database->schema();
     $this->assertTrue($schema_handler->tableExists('entity_test_update__new_bundle_field'), 'Dedicated table created for new_bundle_field.');
     $entity = $this->entityManager->getStorage('entity_test_update')->load($entity->id());
@@ -347,14 +341,14 @@ public function testBundleFieldCreateDeleteWithExistingEntities() {
     // Remove the base field and run the update. Ensure the bundle field's
     // table is deleted and the prior saved entity data is still there.
     $this->removeBundleField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertFalse($schema_handler->tableExists('entity_test_update__new_bundle_field'), 'Dedicated table deleted for new_bundle_field.');
     $entity = $this->entityManager->getStorage('entity_test_update')->load($entity->id());
     $this->assertIdentical($entity->name->value, $name, 'Entity data preserved during field deletion.');
 
     // Test that required columns are created as 'not null'.
     $this->addBundleField('shape_required');
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $message = 'The new_bundle_field_shape column is not nullable.';
     $values = [
       'bundle' => $entity->bundle(),
@@ -407,7 +401,7 @@ public function testBaseFieldDeleteWithExistingData($entity_type_id, $create_ent
 
     // Add the base field and run the update.
     $this->addBaseField('string', $entity_type_id, $base_field_revisionable);
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
 
     /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
     $table_mapping = $storage->getTableMapping();
@@ -425,7 +419,7 @@ public function testBaseFieldDeleteWithExistingData($entity_type_id, $create_ent
 
     // Remove the base field and apply updates.
     $this->removeBaseField($entity_type_id);
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
 
     // Check that the base field's column is deleted.
     $this->assertFalse($schema_handler->fieldExists($entity_type_id, 'new_base_field'), 'Column deleted from shared table for new_base_field.');
@@ -570,7 +564,7 @@ public function testBundleFieldDeleteWithExistingData() {
 
     // Add the bundle field and run the update.
     $this->addBundleField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
 
     /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
     $table_mapping = $storage->getTableMapping();
@@ -587,7 +581,7 @@ public function testBundleFieldDeleteWithExistingData() {
 
     // Remove the bundle field and apply updates.
     $this->removeBundleField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
 
     // Check that the table of the bundle field has been renamed to use a
     // 'deleted' table name.
@@ -641,7 +635,7 @@ public function testBundleFieldDeleteWithExistingData() {
   public function testBaseFieldUpdateWithExistingData() {
     // Add the base field and run the update.
     $this->addBaseField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
 
     // Save an entity with the base field populated.
     $this->entityManager->getStorage('entity_test_update')->create(['new_base_field' => 'foo'])->save();
@@ -650,7 +644,7 @@ public function testBaseFieldUpdateWithExistingData() {
     // throw an exception.
     $this->modifyBaseField();
     try {
-      $this->entityDefinitionUpdateManager->applyUpdates();
+      $this->applyEntityUpdates();
       $this->fail('FieldStorageDefinitionUpdateForbiddenException thrown when trying to update a field schema that has data.');
     }
     catch (FieldStorageDefinitionUpdateForbiddenException $e) {
@@ -664,7 +658,7 @@ public function testBaseFieldUpdateWithExistingData() {
   public function testBundleFieldUpdateWithExistingData() {
     // Add the bundle field and run the update.
     $this->addBundleField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
 
     // Save an entity with the bundle field populated.
     entity_test_create_bundle('custom');
@@ -674,7 +668,7 @@ public function testBundleFieldUpdateWithExistingData() {
     // throw an exception.
     $this->modifyBundleField();
     try {
-      $this->entityDefinitionUpdateManager->applyUpdates();
+      $this->applyEntityUpdates();
       $this->fail('FieldStorageDefinitionUpdateForbiddenException thrown when trying to update a field schema that has data.');
     }
     catch (FieldStorageDefinitionUpdateForbiddenException $e) {
@@ -698,7 +692,9 @@ public function testEntityIndexCreateDeleteWithoutData() {
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
 
     // Run the update and ensure the new index is created.
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $entity_type = \Drupal::entityTypeManager()->getDefinition('entity_test_update');
+    $original = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledDefinition('entity_test_update');
+    \Drupal::service('entity_type.listener')->onEntityTypeUpdate($entity_type, $original);
     $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index created.');
 
     // Remove the index and ensure the update manager reports that as an
@@ -713,13 +709,18 @@ public function testEntityIndexCreateDeleteWithoutData() {
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.');
 
     // Run the update and ensure the index is deleted.
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $entity_type = \Drupal::entityTypeManager()->getDefinition('entity_test_update');
+    $original = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledDefinition('entity_test_update');
+    \Drupal::service('entity_type.listener')->onEntityTypeUpdate($entity_type, $original);
     $this->assertFalse($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index deleted.');
 
     // Test that composite indexes are handled correctly when dropping and
     // re-creating one of their columns.
     $this->addEntityIndex();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $entity_type = \Drupal::entityTypeManager()->getDefinition('entity_test_update');
+    $original = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledDefinition('entity_test_update');
+    \Drupal::service('entity_type.listener')->onEntityTypeUpdate($entity_type, $original);
+
     $storage_definition = $this->entityDefinitionUpdateManager->getFieldStorageDefinition('name', 'entity_test_update');
     $this->entityDefinitionUpdateManager->updateFieldStorageDefinition($storage_definition);
     $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index created.');
@@ -741,7 +742,9 @@ public function testEntityIndexCreateWithData() {
     // Add an entity index, run the update. Ensure that the index is created
     // despite having data.
     $this->addEntityIndex();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $entity_type = \Drupal::entityTypeManager()->getDefinition('entity_test_update');
+    $original = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledDefinition('entity_test_update');
+    \Drupal::service('entity_type.listener')->onEntityTypeUpdate($entity_type, $original);
     $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index added.');
   }
 
@@ -778,52 +781,6 @@ public function testDefinitionEvents() {
     $this->assertTrue($event_subscriber->hasEventFired(EntityTypeEvents::DELETE), 'Entity type delete event successfully dispatched.');
   }
 
-  /**
-   * Tests updating entity schema and creating a base field.
-   *
-   * This tests updating entity schema and creating a base field at the same
-   * time when there are no existing entities.
-   */
-  public function testEntityTypeSchemaUpdateAndBaseFieldCreateWithoutData() {
-    $this->updateEntityTypeToRevisionable();
-    $this->addBaseField();
-    $message = 'Successfully updated entity schema and created base field at the same time.';
-    // Entity type updates create base fields as well, thus make sure doing both
-    // at the same time does not lead to errors due to the base field being
-    // created twice.
-    try {
-      $this->entityDefinitionUpdateManager->applyUpdates();
-      $this->pass($message);
-    }
-    catch (\Exception $e) {
-      $this->fail($message);
-      throw $e;
-    }
-  }
-
-  /**
-   * Tests updating entity schema and creating a revisionable base field.
-   *
-   * This tests updating entity schema and creating a revisionable base field
-   * at the same time when there are no existing entities.
-   */
-  public function testEntityTypeSchemaUpdateAndRevisionableBaseFieldCreateWithoutData() {
-    $this->updateEntityTypeToRevisionable();
-    $this->addRevisionableBaseField();
-    $message = 'Successfully updated entity schema and created revisionable base field at the same time.';
-    // Entity type updates create base fields as well, thus make sure doing both
-    // at the same time does not lead to errors due to the base field being
-    // created twice.
-    try {
-      $this->entityDefinitionUpdateManager->applyUpdates();
-      $this->pass($message);
-    }
-    catch (\Exception $e) {
-      $this->fail($message);
-      throw $e;
-    }
-  }
-
   /**
    * Tests applying single updates.
    */
@@ -853,13 +810,6 @@ public function testSingleActionCalls() {
       $this->pass($message);
     }
 
-    // Ensure that a non-existing field cannot be installed.
-    $storage_definition = BaseFieldDefinition::create('string')
-      ->setLabel(t('A new revisionable base field'))
-      ->setRevisionable(TRUE);
-    $this->entityDefinitionUpdateManager->installFieldStorageDefinition('bar', 'entity_test_update', 'entity_test', $storage_definition);
-    $this->assertFalse($db_schema->fieldExists('entity_test_update', 'bar'), "A non-existing field cannot be installed.");
-
     // Ensure that installing an existing entity type is a no-op.
     $entity_type = $this->entityDefinitionUpdateManager->getEntityType('entity_test_update');
     $this->entityDefinitionUpdateManager->installEntityType($entity_type);
@@ -902,11 +852,8 @@ public function testSingleActionCalls() {
     // Make the entity type revisionable.
     $this->updateEntityTypeToRevisionable();
     $this->assertFalse($db_schema->tableExists('entity_test_update_revision'), "The 'entity_test_update_revision' does not exist before applying the update.");
-    $entity_type = $this->entityDefinitionUpdateManager->getEntityType('entity_test_update');
-    $keys = $entity_type->getKeys();
-    $keys['revision'] = 'revision_id';
-    $entity_type->set('entity_keys', $keys);
-    $this->entityDefinitionUpdateManager->updateEntityType($entity_type);
+
+    $this->updateEntityTypeToRevisionable(TRUE);
     $this->assertTrue($db_schema->tableExists('entity_test_update_revision'), "The 'entity_test_update_revision' table has been created.");
   }
 
@@ -918,7 +865,7 @@ public function testSingleActionCalls() {
   public function testCreateFieldAndIndexOnSharedTable() {
     $this->addBaseField();
     $this->addBaseFieldIndex();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->assertTrue($this->database->schema()->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' has been created on the 'entity_test_update' table.");
     $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update_field__new_base_field'), "New index 'entity_test_update_field__new_base_field' has been created on the 'entity_test_update' table.");
     // Check index size in for MySQL.
@@ -945,7 +892,10 @@ public function testCreateIndexUsingEntityStorageSchemaWithData() {
       'entity_test_update__type_index' => ['type'],
     ];
     $this->state->set('entity_test_update.additional_entity_indexes', $indexes);
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $entity_type = \Drupal::entityTypeManager()->getDefinition('entity_test_update');
+    $original = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledDefinition('entity_test_update');
+    \Drupal::service('entity_type.listener')->onEntityTypeUpdate($entity_type, $original);
+
     $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__type_index'), "New index 'entity_test_update__type_index' has been created on the 'entity_test_update' table.");
     // Check index size in for MySQL.
     if (Database::getConnection()->driver() == 'mysql') {
@@ -960,7 +910,7 @@ public function testCreateIndexUsingEntityStorageSchemaWithData() {
   public function testBaseFieldEntityKeyUpdateWithExistingData() {
     // Add the base field and run the update.
     $this->addBaseField();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
 
     // Save an entity with the base field populated.
     $this->entityManager->getStorage('entity_test_update')->create(['new_base_field' => $this->randomString()])->save();
@@ -982,7 +932,7 @@ public function testBaseFieldEntityKeyUpdateWithExistingData() {
     // Try to apply the update and verify they fail since we have a NULL value.
     $message = 'An error occurs when trying to enabling NOT NULL constraints with NULL data.';
     try {
-      $this->entityDefinitionUpdateManager->applyUpdates();
+      $this->applyEntityUpdates();
       $this->fail($message);
     }
     catch (EntityStorageException $e) {
@@ -992,7 +942,7 @@ public function testBaseFieldEntityKeyUpdateWithExistingData() {
     // Check that the update is correctly applied when no NULL data is left.
     $entity->set('new_base_field', $this->randomString());
     $entity->save();
-    $this->entityDefinitionUpdateManager->applyUpdates();
+    $this->applyEntityUpdates();
     $this->pass('The update is correctly performed when no NULL data exists.');
 
     // Check that the update actually applied a NOT NULL constraint.
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php
index ec1a55cbbe49d6bbdf2e667b9e83f16dacae89b1..258301f6fe9da0eab6d7bc742a0569299d08c4f4 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php
@@ -18,7 +18,17 @@ class EntityDisplayBaseTest extends KernelTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['entity_test', 'entity_test_third_party', 'field', 'system', 'comment'];
+  public static $modules = ['entity_test', 'entity_test_third_party', 'field', 'system', 'comment', 'user'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('comment');
+    $this->installEntitySchema('entity_test');
+    $this->installSchema('user', ['users_data']);
+  }
 
   /**
    * @covers ::preSave
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php
index a71e692cb5c81a26ab957bd57253fa54eabb2c1a..8666a97dea169d6fec3c72f906768da28b5ec078 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php
@@ -78,8 +78,8 @@ protected function setUp() {
             // enabled in. The comment, node and taxonomy config and the
             // taxonomy_term schema need to be installed before the forum config
             // which in turn needs to be installed before field config.
-            $this->installConfig(['comment', 'node', 'taxonomy']);
             $this->installEntitySchema('taxonomy_term');
+            $this->installConfig(['comment', 'node', 'taxonomy']);
             $this->installConfig(['forum']);
           }
         }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php
index 36a67d9255fd3e8d0e92fe75a7d32324dd6e3853..9dab3359b79f3732889e6ab0ac1e041e540f3251 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait;
 
 /**
  * Tests the default entity storage schema handler.
@@ -13,6 +14,15 @@
  */
 class EntitySchemaTest extends EntityKernelTestBase {
 
+  use EntityDefinitionTestTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['entity_test_update'];
+
   /**
    * The database connection used.
    *
@@ -26,6 +36,7 @@ class EntitySchemaTest extends EntityKernelTestBase {
   protected function setUp() {
     parent::setUp();
     $this->installSchema('user', ['users_data']);
+    $this->installEntitySchema('entity_test_update');
     $this->database = $this->container->get('database');
   }
 
@@ -35,7 +46,7 @@ protected function setUp() {
   public function testCustomFieldCreateDelete() {
     // Install the module which adds the field.
     $this->installModule('entity_schema_test');
-    $storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('entity_test');
+    $storage_definitions = $this->entityManager->getFieldStorageDefinitions('entity_test_update');
     $this->assertNotNull($storage_definitions['custom_base_field'], 'Base field definition found.');
     $this->assertNotNull($storage_definitions['custom_bundle_field'], 'Bundle field definition found.');
 
@@ -43,7 +54,7 @@ public function testCustomFieldCreateDelete() {
     \Drupal::service('field_storage_definition.listener')->onFieldStorageDefinitionCreate($storage_definitions['custom_base_field']);
     \Drupal::service('field_storage_definition.listener')->onFieldStorageDefinitionCreate($storage_definitions['custom_bundle_field']);
     /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
-    $table_mapping = $this->entityTypeManager->getStorage('entity_test')->getTableMapping();
+    $table_mapping = $this->entityTypeManager->getStorage('entity_test_update')->getTableMapping();
     $base_table = current($table_mapping->getTableNames());
     $base_column = current($table_mapping->getColumnNames('custom_base_field'));
     $this->assertTrue($this->database->schema()->fieldExists($base_table, $base_column), 'Table column created');
@@ -64,12 +75,10 @@ public function testCustomFieldCreateDelete() {
    *   Whether the original definition should be altered or not.
    */
   protected function updateEntityType($alter) {
-    $entity_test_id = 'entity_test';
-    $original = $this->entityManager->getDefinition($entity_test_id);
-    $this->entityTypeManager->clearCachedDefinitions();
     $this->state->set('entity_schema_update', $alter);
-    $entity_type = $this->entityManager->getDefinition($entity_test_id);
-    \Drupal::service('entity_type.listener')->onEntityTypeUpdate($entity_type, $original);
+    $updated_entity_type = $this->getUpdatedEntityTypeDefinition($alter, $alter);
+    $updated_field_storage_definitions = $this->getUpdatedFieldStorageDefinitions($alter, $alter);
+    $this->container->get('entity.definition_update_manager')->updateFieldableEntityType($updated_entity_type, $updated_field_storage_definitions);
   }
 
   /**
@@ -77,12 +86,12 @@ protected function updateEntityType($alter) {
    */
   public function testEntitySchemaUpdate() {
     $this->installModule('entity_schema_test');
-    $storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('entity_test');
+    $storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('entity_test_update');
     \Drupal::service('field_storage_definition.listener')->onFieldStorageDefinitionCreate($storage_definitions['custom_base_field']);
     \Drupal::service('field_storage_definition.listener')->onFieldStorageDefinitionCreate($storage_definitions['custom_bundle_field']);
     $schema_handler = $this->database->schema();
-    $tables = ['entity_test', 'entity_test_revision', 'entity_test_field_data', 'entity_test_field_revision'];
-    $dedicated_tables = ['entity_test__custom_bundle_field', 'entity_test_revision__custom_bundle_field'];
+    $tables = ['entity_test_update', 'entity_test_update_revision', 'entity_test_update_data', 'entity_test_update_revision_data'];
+    $dedicated_tables = ['entity_test_update__custom_bundle_field', 'entity_test_update_revision__custom_bundle_field'];
 
     // Initially only the base table and the dedicated field data table should
     // exist.
@@ -298,10 +307,10 @@ public function testModifyingTranslatableColumnSchema() {
     $this->updateEntityType(TRUE);
     $fields = ['revision_log', 'uuid'];
     foreach ($fields as $field_name) {
-      $original_definition = $this->entityManager->getBaseFieldDefinitions('entity_test')[$field_name];
+      $original_definition = $this->entityManager->getBaseFieldDefinitions('entity_test_update')[$field_name];
       $new_definition = clone $original_definition;
       $new_definition->setLabel($original_definition->getLabel() . ', the other one');
-      $this->assertTrue($this->entityManager->getStorage('entity_test')
+      $this->assertTrue($this->entityManager->getStorage('entity_test_update')
         ->requiresFieldDataMigration($new_definition, $original_definition));
     }
   }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php
index 2a6dfed6c2d3590bb1616df09bfac17b6e6908ba..4a16305362ad362de5cd0665a91545952f9fe1a3 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php
@@ -44,6 +44,13 @@ protected function setUp() {
     ConfigurableLanguage::createFromLangcode('de')
       ->save();
 
+    $this->installEntitySchema('entity_test_mul');
+    $this->installEntitySchema('entity_test_mul_langcode_key');
+    $this->installEntitySchema('entity_test_mul_changed');
+    $this->installEntitySchema('entity_test_rev');
+    $this->installEntitySchema('entity_test_mulrev');
+    $this->installEntitySchema('entity_test_mulrev_changed');
+
     // Create the test field.
     module_load_install('entity_test');
     entity_test_install();
diff --git a/core/tests/Drupal/KernelTests/Core/Field/FieldAccessTest.php b/core/tests/Drupal/KernelTests/Core/Field/FieldAccessTest.php
index f273029bf2d2de89bf2a09f1aa05fdb33476d613..3b88a97473362f1d464cb9781dc7282be0ca4191 100644
--- a/core/tests/Drupal/KernelTests/Core/Field/FieldAccessTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Field/FieldAccessTest.php
@@ -35,6 +35,15 @@ protected function setUp() {
     parent::setUp();
     // Install field configuration.
     $this->installConfig(['field']);
+
+    $this->installEntitySchema('entity_test');
+    $this->installEntitySchema('entity_test_mul');
+    $this->installEntitySchema('entity_test_mul_langcode_key');
+    $this->installEntitySchema('entity_test_mul_changed');
+    $this->installEntitySchema('entity_test_rev');
+    $this->installEntitySchema('entity_test_mulrev');
+    $this->installEntitySchema('entity_test_mulrev_changed');
+
     // The users table is needed for creating dummy user accounts.
     $this->installEntitySchema('user');
     // Register entity_test text field.
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityDefinitionUpdateManagerTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityDefinitionUpdateManagerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..af1f5a2057d4b613e8e68cec452979601f19c6d5
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityDefinitionUpdateManagerTest.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Drupal\Tests\Core\Entity;
+
+use Drupal\Core\Entity\EntityDefinitionUpdateManager;
+use Drupal\Core\Entity\EntityFieldManagerInterface;
+use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
+use Drupal\Core\Entity\EntityTypeListenerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Field\FieldStorageDefinitionListenerInterface;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Entity\EntityDefinitionUpdateManager
+ * @group Entity
+ * @group legacy
+ */
+class EntityDefinitionUpdateManagerTest extends UnitTestCase {
+
+  /**
+   * @expectedDeprecation Unsilenced deprecation: EntityDefinitionUpdateManagerInterface::applyUpdates() is deprecated in 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface::getChangeList() and execute each entity type and field storage update manually instead. See https://www.drupal.org/node/3034742.
+   */
+  public function testDeprecatedApplyUpdates() {
+    $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class)->reveal();
+    $entity_last_installed_schema_repository = $this->prophesize(EntityLastInstalledSchemaRepositoryInterface::class)->reveal();
+    $entity_field_manager = $this->prophesize(EntityFieldManagerInterface::class)->reveal();
+    $entity_type_listener = $this->prophesize(EntityTypeListenerInterface::class)->reveal();
+    $field_storage_definition_listener = $this->prophesize(FieldStorageDefinitionListenerInterface::class)->reveal();
+
+    $entity_definition_update_manager = new EntityDefinitionUpdateManager($entity_type_manager, $entity_last_installed_schema_repository, $entity_field_manager, $entity_type_listener, $field_storage_definition_listener);
+
+    $this->assertNull($entity_definition_update_manager->applyUpdates());
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php
index a59a33229b4a01fddb95e1a8167010296833a886..f3dec947b884e356c58005af471773dff1ff632f 100644
--- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php
@@ -386,12 +386,9 @@ public function testGetSchemaBase() {
     $table_mapping->setFieldNames('entity_test', array_keys($this->storageDefinitions));
     $table_mapping->setExtraColumns('entity_test', ['default_langcode']);
 
-    $this->storage->expects($this->any())
+    $this->storageSchema->expects($this->any())
       ->method('getTableMapping')
       ->will($this->returnValue($table_mapping));
-    $this->storage->expects($this->any())
-      ->method('getCustomTableMapping')
-      ->will($this->returnValue($table_mapping));
 
     $this->assertNull(
       $this->storageSchema->onEntityTypeCreate($this->entityType)
@@ -497,12 +494,9 @@ public function testGetSchemaRevisionable() {
     $table_mapping->setFieldNames('entity_test', array_keys($this->storageDefinitions));
     $table_mapping->setFieldNames('entity_test_revision', array_keys($this->storageDefinitions));
 
-    $this->storage->expects($this->any())
+    $this->storageSchema->expects($this->any())
       ->method('getTableMapping')
       ->will($this->returnValue($table_mapping));
-    $this->storage->expects($this->any())
-      ->method('getCustomTableMapping')
-      ->will($this->returnValue($table_mapping));
 
     $this->storageSchema->onEntityTypeCreate($this->entityType);
   }
@@ -609,12 +603,9 @@ public function testGetSchemaTranslatable() {
     $table_mapping->setFieldNames('entity_test', $non_data_fields);
     $table_mapping->setFieldNames('entity_test_field_data', array_keys($this->storageDefinitions));
 
-    $this->storage->expects($this->any())
+    $this->storageSchema->expects($this->any())
       ->method('getTableMapping')
       ->will($this->returnValue($table_mapping));
-    $this->storage->expects($this->any())
-      ->method('getCustomTableMapping')
-      ->will($this->returnValue($table_mapping));
 
     $this->assertNull(
       $this->storageSchema->onEntityTypeCreate($this->entityType)
@@ -830,12 +821,9 @@ public function testGetSchemaRevisionableTranslatable() {
     $table_mapping->setFieldNames('entity_test_field_data', array_keys($this->storageDefinitions));
     $table_mapping->setFieldNames('entity_test_revision_field_data', array_keys($this->storageDefinitions));
 
-    $this->storage->expects($this->any())
+    $this->storageSchema->expects($this->any())
       ->method('getTableMapping')
       ->will($this->returnValue($table_mapping));
-    $this->storage->expects($this->any())
-      ->method('getCustomTableMapping')
-      ->will($this->returnValue($table_mapping));
 
     $this->storageSchema->onEntityTypeCreate($this->entityType);
   }
@@ -1008,7 +996,7 @@ public function testDedicatedTableSchema() {
     $table_mapping->setFieldNames($entity_type_id, array_keys($this->storageDefinitions));
     $table_mapping->setExtraColumns($entity_type_id, ['default_langcode']);
 
-    $this->storage->expects($this->any())
+    $this->storageSchema->expects($this->any())
       ->method('getTableMapping')
       ->will($this->returnValue($table_mapping));
 
@@ -1153,7 +1141,7 @@ public function testDedicatedTableSchemaForEntityWithStringIdentifier() {
     $table_mapping->setFieldNames($entity_type_id, array_keys($this->storageDefinitions));
     $table_mapping->setExtraColumns($entity_type_id, ['default_langcode']);
 
-    $this->storage->expects($this->any())
+    $this->storageSchema->expects($this->any())
       ->method('getTableMapping')
       ->will($this->returnValue($table_mapping));
 
@@ -1235,6 +1223,15 @@ public function testRequiresEntityDataMigration($updated_entity_type_definition,
       ->method('createHandlerInstance')
       ->willReturn($original_storage);
 
+    $this->entityLastInstalledSchemaRepository
+      ->expects($this->any())
+      ->method('getLastInstalledDefinition')
+      ->willReturn($this->entityType);
+    $this->entityLastInstalledSchemaRepository
+      ->expects($this->any())
+      ->method('getLastInstalledFieldStorageDefinitions')
+      ->willReturn($this->storageDefinitions);
+
     $this->storageSchema = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema')
       ->setConstructorArgs([$this->entityTypeManager, $this->entityType, $this->storage, $connection, $this->entityFieldManager, $this->entityLastInstalledSchemaRepository])
       ->setMethods(['installedStorageSchema', 'hasSharedTableStructureChange'])
@@ -1330,12 +1327,9 @@ public function testRequiresEntityStorageSchemaChanges(ContentEntityTypeInterfac
     $table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
     $table_mapping->setFieldNames('entity_test', array_keys($this->storageDefinitions));
     $table_mapping->setExtraColumns('entity_test', ['default_langcode']);
-    $this->storage->expects($this->any())
+    $this->storageSchema->expects($this->any())
       ->method('getTableMapping')
       ->will($this->returnValue($table_mapping));
-    $this->storage->expects($this->any())
-      ->method('getCustomTableMapping')
-      ->will($this->returnValue($table_mapping));
 
     // Setup storage schema.
     if ($change_schema) {
@@ -1415,9 +1409,19 @@ protected function setUpStorageSchema(array $expected = []) {
       ->will($this->returnValue($this->dbSchemaHandler));
 
     $key_value = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreInterface');
+
+    $this->entityLastInstalledSchemaRepository
+      ->expects($this->any())
+      ->method('getLastInstalledDefinition')
+      ->willReturn($this->entityType);
+    $this->entityLastInstalledSchemaRepository
+      ->expects($this->any())
+      ->method('getLastInstalledFieldStorageDefinitions')
+      ->willReturn($this->storageDefinitions);
+
     $this->storageSchema = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema')
       ->setConstructorArgs([$this->entityTypeManager, $this->entityType, $this->storage, $connection, $this->entityFieldManager, $this->entityLastInstalledSchemaRepository])
-      ->setMethods(['installedStorageSchema', 'loadEntitySchemaData', 'hasSharedTableNameChanges', 'isTableEmpty'])
+      ->setMethods(['installedStorageSchema', 'loadEntitySchemaData', 'hasSharedTableNameChanges', 'isTableEmpty', 'getTableMapping'])
       ->getMock();
     $this->storageSchema
       ->expects($this->any())
@@ -1517,12 +1521,9 @@ public function testonEntityTypeUpdateWithNewIndex() {
     $table_mapping->setFieldNames('entity_test', array_keys($this->storageDefinitions));
     $table_mapping->setExtraColumns('entity_test', ['default_langcode']);
 
-    $this->storage->expects($this->any())
+    $this->storageSchema->expects($this->any())
       ->method('getTableMapping')
       ->will($this->returnValue($table_mapping));
-    $this->storage->expects($this->any())
-      ->method('getCustomTableMapping')
-      ->will($this->returnValue($table_mapping));
 
     $this->storageSchema->expects($this->any())
       ->method('loadEntitySchemaData')
diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
index 025ff57c93d49639efa2a5b744174c6c52c3860e..4ff4e3ad6b8b4f7e1769436f104b33eb8ef215b4 100644
--- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
@@ -147,6 +147,7 @@ protected function setUp() {
 
     $this->container->set('entity_type.manager', $this->entityTypeManager);
     $this->container->set('entity_field.manager', $this->entityFieldManager);
+    $this->container->set('entity.last_installed_schema.repository', $this->entityLastInstalledSchemaRepository);
   }
 
   /**
@@ -875,6 +876,8 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys)
       ->method('getRevisionMetadataKeys')
       ->will($this->returnValue($revision_metadata_keys));
 
+    $this->fieldDefinitions = $this->mockFieldDefinitions(array_values($revision_metadata_keys), ['isRevisionable' => TRUE]);
+
     $this->setUpEntityStorage();
 
     $mapping = $this->entityStorage->getTableMapping();