diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
index 56e4f2d..ed97514 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
@@ -64,7 +64,7 @@ public static function open(array &$connection_options = array()) {
     // Character set is added to dsn to ensure PDO uses the proper character
     // set when escaping. This has security implications. See
     // https://www.drupal.org/node/1201452 for further discussion.
-    $dsn .= ';charset=utf8';
+    $dsn .= ';charset=utf8mb4';
     if (!empty($connection_options['database'])) {
       $dsn .= ';dbname=' . $connection_options['database'];
     }
@@ -92,13 +92,13 @@ public static function open(array &$connection_options = array()) {
     $pdo = new \PDO($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
 
     // Force MySQL to use the UTF-8 character set. Also set the collation, if a
-    // certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
-    // for UTF-8.
+    // certain one has been set; otherwise, MySQL defaults to
+    // 'utf8mb4_general_ci' for utf8mb4.
     if (!empty($connection_options['collation'])) {
-      $pdo->exec('SET NAMES utf8 COLLATE ' . $connection_options['collation']);
+      $pdo->exec('SET NAMES utf8mb4 COLLATE ' . $connection_options['collation']);
     }
     else {
-      $pdo->exec('SET NAMES utf8');
+      $pdo->exec('SET NAMES utf8mb4');
     }
 
     // Set MySQL init_commands if not already defined.  Default Drupal's MySQL
diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
index 8237c79..6326bcf 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -87,7 +87,7 @@ protected function createTableSql($name, $table) {
     // Provide defaults if needed.
     $table += array(
       'mysql_engine' => 'InnoDB',
-      'mysql_character_set' => 'utf8',
+      'mysql_character_set' => 'utf8mb4',
     );
 
     $sql = "CREATE TABLE {" . $name . "} (\n";
@@ -108,8 +108,8 @@ protected function createTableSql($name, $table) {
 
     $sql .= 'ENGINE = ' . $table['mysql_engine'] . ' DEFAULT CHARACTER SET ' . $table['mysql_character_set'];
     // By default, MySQL uses the default collation for new tables, which is
-    // 'utf8_general_ci' for utf8. If an alternate collation has been set, it
-    // needs to be explicitly specified.
+    // 'utf8mb4_general_ci' for utf8mb4. If an alternate collation has been
+    // set, it needs to be explicitly specified.
     // @see DatabaseConnection_mysql
     if (!empty($info['collation'])) {
       $sql .= ' COLLATE ' . $info['collation'];
diff --git a/core/modules/aggregator/src/Entity/Feed.php b/core/modules/aggregator/src/Entity/Feed.php
index a5ed081..b5f9096 100644
--- a/core/modules/aggregator/src/Entity/Feed.php
+++ b/core/modules/aggregator/src/Entity/Feed.php
@@ -145,7 +145,9 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setLabel(t('Title'))
       ->setDescription(t('The name of the feed (or the name of the website providing the feed).'))
       ->setRequired(TRUE)
-      ->setSetting('max_length', 255)
+      // We have a unique constraint on the title field, which has the utf8mb4
+      // character set in MySQL so we can't have more than 191 characters.
+      ->setSetting('max_length', 191)
       ->setDisplayOptions('form', array(
         'type' => 'string_textfield',
         'weight' => -5,
diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php
index 046640c..19d416f 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -187,7 +187,10 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
         'type' => 'string_textfield',
         'weight' => -5,
       ))
-      ->setDisplayConfigurable('form', TRUE);
+      ->setDisplayConfigurable('form', TRUE)
+      // We have a unique constraint on the info field, which has the utf8mb4
+      // character set in MySQL so we can't have more than 191 characters.
+      ->setSetting('max_length', 191);
 
     $fields['type'] = BaseFieldDefinition::create('entity_reference')
       ->setLabel(t('Block type'))
diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php
index ff38ab3..2c659ad 100644
--- a/core/modules/file/src/Entity/File.php
+++ b/core/modules/file/src/Entity/File.php
@@ -249,7 +249,9 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields['uri'] = BaseFieldDefinition::create('uri')
       ->setLabel(t('URI'))
       ->setDescription(t('The URI to access the file (either local or remote).'))
-      ->setSetting('max_length', 255)
+      // We have a unique constraint on the URI field, which has the utf8mb4
+      // character set in MySQL so we can't have more than 191 characters.
+      ->setSetting('max_length', 191)
       ->setSetting('case_sensitive', TRUE);
 
     $fields['filemime'] = BaseFieldDefinition::create('string')
diff --git a/core/modules/node/src/Tests/NodeViewTest.php b/core/modules/node/src/Tests/NodeViewTest.php
index 2281dd8..c60d44a 100644
--- a/core/modules/node/src/Tests/NodeViewTest.php
+++ b/core/modules/node/src/Tests/NodeViewTest.php
@@ -33,4 +33,16 @@ public function testHtmlHeadLinks() {
     $this->assertEqual($result[0]['href'], $node->url());
   }
 
+  /**
+   * Tests that we store and retrieve multi-byte UTF-8 characters correctly.
+   */
+  public function testMultiByteUtf8() {
+    $title = '🐝';
+    $this->assertTrue(mb_strlen($title, 'utf-8') < strlen($title), 'Title has multi-byte characters.');
+    $node = $this->drupalCreateNode(array('title' => $title));
+    $this->drupalGet($node->urlInfo());
+    $result = $this->xpath('//span[contains(@class, "field-name-title")]');
+    $this->assertEqual((string) $result[0], $title, 'The passed title was returned.');
+  }
+
 }
diff --git a/core/modules/system/src/Tests/Database/SchemaTest.php b/core/modules/system/src/Tests/Database/SchemaTest.php
index 46b591c..1b75be6 100644
--- a/core/modules/system/src/Tests/Database/SchemaTest.php
+++ b/core/modules/system/src/Tests/Database/SchemaTest.php
@@ -68,17 +68,19 @@ function testSchema() {
     $this->checkSchemaComment($table_specification['fields']['test_field']['description'], 'test_table', 'test_field');
 
     // Make sure that varchar fields have the correct collation.
-    $columns = db_query('SHOW FULL COLUMNS FROM {test_table}');
-    foreach ($columns as $column) {
-      if ($column->Field == 'test_field_string') {
-        $string_check = ($column->Collation == 'utf8_general_ci');
-      }
-      if ($column->Field == 'test_field_string_ascii') {
-        $string_ascii_check = ($column->Collation == 'ascii_general_ci');
+    if (Database::getConnection()->databaseType() == 'mysql') {
+      $columns = db_query('SHOW FULL COLUMNS FROM {test_table}');
+      foreach ($columns as $column) {
+        if ($column->Field == 'test_field_string') {
+          $string_check = ($column->Collation == 'utf8mb4_general_ci');
+        }
+        if ($column->Field == 'test_field_string_ascii') {
+          $string_ascii_check = ($column->Collation == 'ascii_general_ci');
+        }
       }
+      $this->assertTrue(!empty($string_check), 'string field has the right collation.');
+      $this->assertTrue(!empty($string_ascii_check), 'ASCII string field has the right collation.');
     }
-    $this->assertTrue(!empty($string_check), 'string field has the right collation.');
-    $this->assertTrue(!empty($string_ascii_check), 'ASCII string field has the right collation.');
 
     // An insert without a value for the column 'test_table' should fail.
     $this->assertFalse($this->tryInsert(), 'Insert without a default failed.');
diff --git a/core/modules/user/src/UserStorageSchema.php b/core/modules/user/src/UserStorageSchema.php
index 447469d..6247b10 100644
--- a/core/modules/user/src/UserStorageSchema.php
+++ b/core/modules/user/src/UserStorageSchema.php
@@ -52,6 +52,9 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st
           // Improves the performance of the user__name index defined
           // in getEntitySchema().
           $schema['fields'][$field_name]['not null'] = TRUE;
+          // Make sure the field is no longer than 191 characters so we can
+          // add a unique constraint in MySQL.
+          $schema['fields'][$field_name]['length'] = USERNAME_MAX_LENGTH;
           break;
 
         case 'mail':
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index f35f547..a9797f9 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -25,6 +25,8 @@
 
 /**
  * Maximum length of username text field.
+ *
+ * Keep this under 191 characters so we can use a unique constraint in MySQL.
  */
 const USERNAME_MAX_LENGTH = 60;
 
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 3783d0a..f9a5a1b 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -75,7 +75,7 @@
  *   'host' => 'localhost',
  *   'port' => 3306,
  *   'prefix' => 'myprefix_',
- *   'collation' => 'utf8_general_ci',
+ *   'collation' => 'utf8mb4_general_ci',
  * );
  * @endcode
  *
@@ -127,7 +127,7 @@
  *   'password' => 'password',
  *   'host' => 'localhost',
  *   'prefix' => 'main_',
- *   'collation' => 'utf8_general_ci',
+ *   'collation' => 'utf8mb4_general_ci',
  * );
  * @endcode
  *
