diff --git a/core/includes/database.inc b/core/includes/database.inc
index 98041cd..4d924ef 100644
--- a/core/includes/database.inc
+++ b/core/includes/database.inc
@@ -654,9 +654,11 @@ function db_drop_unique_key($table, $name) {
  *   The name of the index.
  * @param $fields
  *   An array of field names.
+ * @param array $spec
+ *   A table specification.
  */
-function db_add_index($table, $name, $fields) {
-  return Database::getConnection()->schema()->addIndex($table, $name, $fields);
+function db_add_index($table, $name, $fields, array $spec) {
+  return Database::getConnection()->schema()->addIndex($table, $name, $fields, $spec);
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
index 8f5b710..c66330f 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -299,14 +299,14 @@ protected function createKeysSql($spec) {
    * Shortens indexes to 191 characters if they apply to utf8mb4-encoded
    * fields, in order to comply with the InnoDB index limitation of 756 bytes.
    *
-   * @param $spec
+   * @param array $spec
    *   The table specification.
    *
    * @return array
    *   List of shortened indexes.
    */
-  protected function getNormalizedIndexes($spec) {
-    $indexes = $spec['indexes'];
+  protected function getNormalizedIndexes(array $spec) {
+    $indexes = parent::getNormalizedIndexes($spec);
     foreach ($indexes as $index_name => $index_fields) {
       foreach ($index_fields as $index_key => $index_field) {
         // Get the name of the field from the index specification.
@@ -486,7 +486,10 @@ public function dropUniqueKey($table, $name) {
     return TRUE;
   }
 
-  public function addIndex($table, $name, $fields) {
+  /**
+   * {@inheritdoc}
+   */
+  public function addIndex($table, $name, $fields, array $spec) {
     if (!$this->tableExists($table)) {
       throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
     }
@@ -494,7 +497,10 @@ public function addIndex($table, $name, $fields) {
       throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ADD INDEX `' . $name . '` (' . $this->createKeySql($fields) . ')');
+    $spec['indexes'][$name] = $fields;
+    $indexes = $this->getNormalizedIndexes($spec);
+
+    $this->connection->query('ALTER TABLE {' . $table . '} ADD INDEX `' . $name . '` (' . $this->createKeySql($indexes[$name]) . ')');
   }
 
   public function dropIndex($table, $name) {
diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
index e3062dd..fc46542 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
@@ -637,7 +637,10 @@ public function dropUniqueKey($table, $name) {
     return TRUE;
   }
 
-  public function addIndex($table, $name, $fields) {
+  /**
+   * {@inheritdoc}
+   */
+  public function addIndex($table, $name, $fields, array $spec) {
     if (!$this->tableExists($table)) {
       throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
     }
@@ -645,6 +648,8 @@ public function addIndex($table, $name, $fields) {
       throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));
     }
 
+    $spec['indexes'][$name] = $fields;
+
     $this->connection->query($this->_createIndexSql($table, $name, $fields));
     $this->resetTableInformation($table);
   }
@@ -779,7 +784,10 @@ protected function _createKeys($table, $new_keys) {
     }
     if (isset($new_keys['indexes'])) {
       foreach ($new_keys['indexes'] as $name => $fields) {
-        $this->addIndex($table, $name, $fields);
+        // Even $new_keys is not a full schema it still has 'indexes' and so is
+        // a partial schema. Technically addIndex() doesn't do anything with it
+        // so passing an empty array would work as well.
+        $this->addIndex($table, $name, $fields, $new_keys);
       }
     }
   }
diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php
index 3ac3811..cf19c48 100644
--- a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php
@@ -582,7 +582,10 @@ protected function mapKeyDefinition(array $key_definition, array $mapping) {
     return $key_definition;
   }
 
-  public function addIndex($table, $name, $fields) {
+  /**
+   * {@inheritdoc}
+   */
+  public function addIndex($table, $name, $fields, array $spec) {
     if (!$this->tableExists($table)) {
       throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
     }
@@ -590,8 +593,9 @@ public function addIndex($table, $name, $fields) {
       throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));
     }
 
-    $schema['indexes'][$name] = $fields;
-    $statements = $this->createIndexSql($table, $schema);
+    $spec['indexes'][$name] = $fields;
+
+    $statements = $this->createIndexSql($table, $spec);
     foreach ($statements as $statement) {
       $this->connection->query($statement);
     }
diff --git a/core/lib/Drupal/Core/Database/Schema.php b/core/lib/Drupal/Core/Database/Schema.php
index 4ebfd40..45c7e5a 100644
--- a/core/lib/Drupal/Core/Database/Schema.php
+++ b/core/lib/Drupal/Core/Database/Schema.php
@@ -413,13 +413,29 @@ public function fieldExists($table, $column) {
    *   @code
    *     $fields = ['foo', ['bar', 4]];
    *   @endcode
+   * @param array $spec
+   *   A table specification, which is used in order to be able to ensure that
+   *   the index length is not too long.
    *
    * @throws \Drupal\Core\Database\SchemaObjectDoesNotExistException
    *   If the specified table doesn't exist.
    * @throws \Drupal\Core\Database\SchemaObjectExistsException
    *   If the specified table already has an index by that name.
    */
-  abstract public function addIndex($table, $name, $fields);
+  abstract public function addIndex($table, $name, $fields, array $spec);
+
+  /**
+   * Gets normalized indexes from a table specification.
+   *
+   * @param array $spec
+   *   The table specification.
+   *
+   * @return array
+   *   List of shortened indexes.
+   */
+  protected function getNormalizedIndexes(array $spec) {
+    return isset($spec['indexes']) ? $spec['indexes'] : [];
+  }
 
   /**
    * Drop an index.
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
index 24f4650..da62d70 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -333,7 +333,7 @@ public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeI
       foreach ($this->getEntitySchemaData($entity_type, $entity_schema) as $table_name => $schema) {
         if (!empty($schema['indexes'])) {
           foreach ($schema['indexes'] as $name => $specifier) {
-            $schema_handler->addIndex($table_name, $name, $specifier);
+            $schema_handler->addIndex($table_name, $name, $specifier, $schema);
           }
         }
         if (!empty($schema['unique keys'])) {
@@ -1140,7 +1140,7 @@ protected function createSharedTableSchema(FieldStorageDefinitionInterface $stor
                 // Check if the index exists because it might already have been
                 // created as part of the earlier entity type update event.
                 if (!$schema_handler->indexExists($table_name, $name)) {
-                  $schema_handler->addIndex($table_name, $name, $specifier);
+                  $schema_handler->addIndex($table_name, $name, $specifier, $schema);
                 }
               }
             }
@@ -1303,8 +1303,8 @@ protected function updateDedicatedTableSchema(FieldStorageDefinitionInterface $s
               $real_columns[] = $table_mapping->getFieldColumnName($storage_definition, $column_name);
             }
           }
-          $this->database->schema()->addIndex($table, $real_name, $real_columns);
-          $this->database->schema()->addIndex($revision_table, $real_name, $real_columns);
+          $this->database->schema()->addIndex($table, $real_name, $real_columns, $schema);
+          $this->database->schema()->addIndex($revision_table, $real_name, $real_columns, $schema);
         }
       }
       $this->saveFieldSchemaData($storage_definition, $this->getDedicatedTableSchema($storage_definition));
@@ -1381,7 +1381,7 @@ protected function updateSharedTableSchema(FieldStorageDefinitionInterface $stor
             // Create new indexes and unique keys.
             if (!empty($schema[$table_name]['indexes'])) {
               foreach ($schema[$table_name]['indexes'] as $name => $specifier) {
-                $schema_handler->addIndex($table_name, $name, $specifier);
+                $schema_handler->addIndex($table_name, $name, $specifier, $schema[$table_name]);
               }
             }
             if (!empty($schema[$table_name]['unique keys'])) {
diff --git a/core/modules/system/src/Tests/Database/SchemaTest.php b/core/modules/system/src/Tests/Database/SchemaTest.php
index 1e77084..e2260d5 100644
--- a/core/modules/system/src/Tests/Database/SchemaTest.php
+++ b/core/modules/system/src/Tests/Database/SchemaTest.php
@@ -99,7 +99,7 @@ function testSchema() {
     $index_exists = Database::getConnection()->schema()->indexExists('test_table', 'test_field');
     $this->assertIdentical($index_exists, FALSE, 'Fake index does not exists');
     // Add index.
-    db_add_index('test_table', 'test_field', array('test_field'));
+    db_add_index('test_table', 'test_field', array('test_field'), $table_specification);
     // Test for created index and test for the boolean result of indexExists().
     $index_exists = Database::getConnection()->schema()->indexExists('test_table', 'test_field');
     $this->assertIdentical($index_exists, TRUE, 'Index created.');
@@ -295,6 +295,30 @@ function testIndexLength() {
     );
     db_create_table('test_table_index_length', $table_specification);
 
+    // Add a separate index.
+    $schema_object = Database::getConnection()->schema();
+    $schema_object->addIndex('test_table_index_length', 'test_separate', [['test_field_text', 200]], $table_specification);
+    $table_specification_with_new_index = $table_specification;
+    $table_specification_with_new_index['indexes']['test_separate'] = [['test_field_text', 200]];
+
+    // Ensure that the exceptions of addIndex are thrown as expected.
+
+    try {
+      $schema_object->addIndex('test_table_index_length', 'test_separate', [['test_field_text', 200]], $table_specification);
+      $this->fail('\Drupal\Core\Database\SchemaObjectExistsException exception missed.');
+    }
+    catch (SchemaObjectExistsException $e) {
+      $this->pass('\Drupal\Core\Database\SchemaObjectExistsException thrown when index already exists.');
+    }
+
+    try {
+      $schema_object->addIndex('test_table_non_existing', 'test_separate', [['test_field_text', 200]], $table_specification);
+      $this->fail('\Drupal\Core\Database\SchemaObjectDoesNotExistException exception missed.');
+    }
+    catch (SchemaObjectDoesNotExistException $e) {
+      $this->pass('\Drupal\Core\Database\SchemaObjectDoesNotExistException thrown when index already exists.');
+    }
+
     // Get index information.
     $results = db_query('SHOW INDEX FROM {test_table_index_length}');
     $expected_lengths = array(
@@ -316,11 +340,14 @@ function testIndexLength() {
         'test_field_string_ascii_long' => 200,
         'test_field_string_short' => NULL,
       ),
+      'test_separate' => array(
+        'test_field_text' => 191,
+      ),
     );
 
     // Count the number of columns defined in the indexes.
     $column_count = 0;
-    foreach ($table_specification['indexes'] as $index) {
+    foreach ($table_specification_with_new_index['indexes'] as $index) {
       foreach ($index as $field) {
         $column_count++;
       }
diff --git a/core/modules/system/tests/modules/update_test_schema/update_test_schema.install b/core/modules/system/tests/modules/update_test_schema/update_test_schema.install
index b6aa9c3..972f901 100644
--- a/core/modules/system/tests/modules/update_test_schema/update_test_schema.install
+++ b/core/modules/system/tests/modules/update_test_schema/update_test_schema.install
@@ -35,7 +35,14 @@ function update_test_schema_schema() {
    * Schema version 8001.
    */
   function update_test_schema_update_8001() {
+    $table = [
+      'fields' => [
+        'a' => ['type' => 'int', 'not null' => TRUE],
+        'b' => ['type' => 'blob', 'not null' => FALSE],
+      ],
+    ];
+
     // Add a column.
-    db_add_index('update_test_schema_table', 'test', ['a']);
+    db_add_index('update_test_schema_table', 'test', ['a'], $table);
   }
 }
