diff --git a/includes/database/mysql/database.inc b/includes/database/mysql/database.inc
index 356e039f7..77a83eab4 100644
--- a/includes/database/mysql/database.inc
+++ b/includes/database/mysql/database.inc
@@ -19,6 +19,12 @@ class DatabaseConnection_mysql extends DatabaseConnection {
    */
   protected $needsCleanup = FALSE;
 
+  /**
+   * Whether we're running MySQL 8.x. Required to determine if we should quote
+   * table names.
+   */
+  protected $isMySQL8;
+
   public function __construct(array $connection_options = array()) {
     // This driver defaults to transaction support, except if explicitly passed FALSE.
     $this->transactionSupport = !isset($connection_options['transactions']) || ($connection_options['transactions'] !== FALSE);
@@ -86,8 +92,19 @@ class DatabaseConnection_mysql extends DatabaseConnection {
     $connection_options += array(
       'init_commands' => array(),
     );
+
+    $sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO';
+    // NO_AUTO_CREATE_USER is removed in MySQL 8.0.11
+    // https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-11.html#mysqld-8-0-11-deprecation-removal
+    $version_server = $this->getAttribute(PDO::ATTR_SERVER_VERSION);
+    if (version_compare($version_server, '8.0.11', '<')) {
+      $sql_mode .= ',NO_AUTO_CREATE_USER';
+    }
+
+    $this->isMySQL8 = version_compare($version_server, '8.0.0', '>=');
+
     $connection_options['init_commands'] += array(
-      'sql_mode' => "SET sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER'",
+      'sql_mode' => "SET sql_mode = '$sql_mode'",
     );
     // Execute initial commands.
     foreach ($connection_options['init_commands'] as $sql) {
@@ -101,6 +118,35 @@ class DatabaseConnection_mysql extends DatabaseConnection {
     }
   }
 
+  /**
+   * Overridden to quote table and database names with backticks for MySQL 8.
+   */
+  public function query($query, array $args = array(), $options = array()) {
+    if ($this->isMySQL8) {
+      // Match {table} as well as {db.table} and quote both DB and table with
+      // backticks.
+      $query = preg_replace_callback('/{((.*?)\.)?(.*?)}/', function($matches) {
+        $quoted = '';
+
+        // If there is an explicit database, quote it, too.
+        if ($matches[2] !== '') {
+          $quoted .= '`' . $matches[2] . '`.';
+        }
+
+        // Quote the table name.
+        $quoted .= '`' . $matches[3] . '`';
+
+        return $quoted;
+      }, $query);
+
+      // Make Drush work.
+      $query = str_replace(' system.', ' `system`.', $query);
+      $query = str_replace('`system` system', '`system` `system`', $query);
+    }
+
+    return parent::query($query, $args, $options);
+  }
+
   public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
     return $this->query($query . ' LIMIT ' . (int) $from . ', ' . (int) $count, $args, $options);
   }
