diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
index 7dad008..631d693 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
@@ -14,6 +14,7 @@
 use Drupal\Core\Database\TransactionCommitFailedException;
 use Drupal\Core\Database\DatabaseException;
 use Drupal\Core\Database\Connection as DatabaseConnection;
+use Drupal\Component\Utility\Unicode;
 
 /**
  * @addtogroup database
@@ -35,6 +36,16 @@ class Connection extends DatabaseConnection {
   protected $needsCleanup = FALSE;
 
   /**
+   * The minimal possible value for the max_allowed_packet setting of MySQL.
+   *
+   * @link https://mariadb.com/kb/en/mariadb/server-system-variables/#max_allowed_packet
+   * @link https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_allowed_packet
+   *
+   * @var int
+   */
+  const MIN_MAX_ALLOWED_PACKET = 1024;
+
+  /**
    * Constructs a Connection object.
    */
   public function __construct(\PDO $connection, array $connection_options = array()) {
@@ -52,6 +63,24 @@ public function __construct(\PDO $connection, array $connection_options = array(
   /**
    * {@inheritdoc}
    */
+  public function query($query, array $args = array(), $options = array()) {
+    try {
+      return parent::query($query, $args, $options);
+    } catch (DatabaseException $e) {
+      if ($e->getPrevious()->errorInfo[1] == 1153) {
+        // If a max_allowed_packet error occurs the message length is truncated.
+        // This should prevent the error from reoccuring if the exception is
+        // logged to the database using dblog or the like.
+        $message = Unicode::truncateBytes($e->getMessage(), self::MIN_MAX_ALLOWED_PACKET);
+        $e = new DatabaseExceptionWrapper($message, $e->getCode(), $e->getPrevious());
+      }
+      throw $e;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public static function open(array &$connection_options = array()) {
     // The DSN should use either a socket or a host/port.
     if (isset($connection_options['unix_socket'])) {
@@ -278,6 +307,7 @@ protected function popCommittableTransactions() {
       }
     }
   }
+
 }
 
 
diff --git a/core/modules/dblog/src/Logger/DbLog.php b/core/modules/dblog/src/Logger/DbLog.php
index a841430..de64e25 100644
--- a/core/modules/dblog/src/Logger/DbLog.php
+++ b/core/modules/dblog/src/Logger/DbLog.php
@@ -9,7 +9,8 @@
 
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\Connection;
-use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Database\DatabaseException;
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 use Drupal\Core\Logger\LogMessageParserInterface;
 use Drupal\Core\Logger\RfcLoggerTrait;
@@ -23,11 +24,16 @@ class DbLog implements LoggerInterface {
   use DependencySerializationTrait;
 
   /**
+   * The dedicated database connection target to use for log entries.
+   */
+  const DEDICATED_DBLOG_CONNECTION_TARGET = 'dedicated_dblog';
+
+  /**
    * The database connection object.
    *
    * @var \Drupal\Core\Database\Connection
    */
-  protected $database;
+  protected $connection;
 
   /**
    * The message's placeholders parser.
@@ -44,8 +50,8 @@ class DbLog implements LoggerInterface {
    * @param \Drupal\Core\Logger\LogMessageParserInterface $parser
    *   The parser to use when extracting message variables.
    */
-  public function __construct(Connection $database, LogMessageParserInterface $parser) {
-    $this->database = $database;
+  public function __construct(Connection $connection, LogMessageParserInterface $parser) {
+    $this->connection = $connection;
     $this->parser = $parser;
   }
 
@@ -60,21 +66,41 @@ public function log($level, $message, array $context = array()) {
     // translated too in runtime.
     $message_placeholders = $this->parser->parseMessagePlaceholders($message, $context);
 
-    $this->database
-      ->insert('watchdog')
-      ->fields(array(
-        'uid' => $context['uid'],
-        'type' => Unicode::substr($context['channel'], 0, 64),
-        'message' => $message,
-        'variables' => serialize($message_placeholders),
-        'severity' => $level,
-        'link' => $context['link'],
-        'location' => $context['request_uri'],
-        'referer' => $context['referer'],
-        'hostname' => Unicode::substr($context['ip'], 0, 128),
-        'timestamp' => $context['timestamp'],
-      ))
-      ->execute();
+    try {
+      $this->connection
+        ->insert('watchdog')
+        ->fields(array(
+          'uid' => $context['uid'],
+          'type' => Unicode::substr($context['channel'], 0, 64),
+          'message' => $message,
+          'variables' => serialize($message_placeholders),
+          'severity' => $level,
+          'link' => $context['link'],
+          'location' => $context['request_uri'],
+          'referer' => $context['referer'],
+          'hostname' => Unicode::substr($context['ip'], 0, 128),
+          'timestamp' => $context['timestamp'],
+        ))
+        ->execute();
+    }
+    catch (\Exception $e) {
+      if (
+        ($e instanceof DatabaseException || $e instanceof \PDOException) &&
+        $this->connection->getTarget() != self::DEDICATED_DBLOG_CONNECTION_TARGET
+      ) {
+        // Open a dedicated connection for logging to ensure that errors that
+        // messed up the default connection are still logged.
+        $key = $this->connection->getKey();
+        $info = Database::getConnectionInfo($key);
+        Database::addConnectionInfo($key, self::DEDICATED_DBLOG_CONNECTION_TARGET, $info['default']);
+        $this->connection = Database::getConnection(self::DEDICATED_DBLOG_CONNECTION_TARGET, $key);
+        // Now try once to log the error again.
+        $this->log($level, $message, $context);
+      }
+      else {
+        throw $e;
+      }
+    }
   }
 
 }
diff --git a/core/modules/dblog/src/Tests/ConnectionFailureTest.php b/core/modules/dblog/src/Tests/ConnectionFailureTest.php
new file mode 100644
index 0000000..ff6de07
--- /dev/null
+++ b/core/modules/dblog/src/Tests/ConnectionFailureTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Definition of \Drupal\dblog\Tests\ConnectionFailureTest.
+ */
+
+namespace Drupal\dblog\Tests;
+
+use Drupal\Core\Database\Database;
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests loging of connection failures.
+ *
+ * @group dblog
+ */
+class ConnectionFailureTest extends WebTestBase {
+
+  public static $modules = array('dblog');
+
+  /**
+   * Tests loging of connection failures.
+   */
+  function testConnectionFailureLogging() {
+    $logger = \Drupal::service('logger.factory');
+
+    // MySQL erros like "1153 – Got a packet bigger than ‘max_allowed_packet’
+    // bytes" or "1100 - Table 'xyz' was not locked with LOCK TABLES" lead to a
+    // database connection unusable for further request. All further request
+    // will result in an "2006 - MySQL server had gone away" error. As a
+    // consequence it's impossible to use this connection to log the causing
+    // initial error itself. Using Database::closeConnection() we simulate such
+    // a corrupted connection. In this case dblog has to establish a different
+    // connection by itself to be able to write the log entry.
+    Database::closeConnection();
+
+    // Create a log entry.
+    $logger->get('php')->error('testConnectionFailureLogging');
+
+    // Re-establish the default database connection.
+    Database::getConnection();
+
+    $wid = db_query("SELECT MAX(wid) FROM {watchdog} WHERE message = 'testConnectionFailureLogging'")->fetchField();
+    $this->assertTrue($wid, 'Watchdog entry has been stored in database.');
+  }
+
+}
diff --git a/core/modules/system/src/Tests/Database/LargeQueryTest.php b/core/modules/system/src/Tests/Database/LargeQueryTest.php
new file mode 100644
index 0000000..790b72c
--- /dev/null
+++ b/core/modules/system/src/Tests/Database/LargeQueryTest.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Database\LargeQueryTest.
+ */
+
+namespace Drupal\system\Tests\Database;
+
+use Drupal\Component\Utility\Environment;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Database\DatabaseException;
+
+/**
+ * Tests handling of large queries.
+ *
+ * @group Database
+ */
+class LargeQueryTest extends DatabaseTestBase {
+
+  /**
+   * Tests truncation of messages when max_allowed_packet exception occurs.
+   */
+  function testMaxAllowedPacketQueryTruncating() {
+    // This test only makes sense if we are running on a MySQL database.
+    // Test if we are.
+    $database = Database::getConnectionInfo('default');
+    if ($database['default']['driver'] == 'mysql') {
+      // The max_allowed_packet value is configured per database instance.
+      // Retrieve the max_allowed_packet value from the current instance and
+      // check if PHP is configured with sufficient allowed memory to be able
+      // to generate a query larger than max_allowed_packet.
+      $max_allowed_packet = db_query('SELECT @@global.max_allowed_packet')->fetchField();
+      if (Environment::checkMemoryLimit($max_allowed_packet + (16 * 1024 * 1024))) {
+        $long_name = str_repeat('a', $max_allowed_packet + 1);
+        try {
+          db_query('SELECT name FROM {test} WHERE name = :name', array(':name' => $long_name));
+          $this->fail("An exception should be thrown for queries larger than 'max_allowed_packet'");
+        } catch (DatabaseException $e) {
+          // Close and re-open the connection. Otherwise we will run into error
+          // 2006 "MySQL server had gone away" afterwards.
+          Database::closeConnection();
+          Database::getConnection();
+          $this->assertEqual($e->getPrevious()->errorInfo[1], 1153, "Got a packet bigger than 'max_allowed_packet' bytes exception thrown.");
+          // Use strlen() to count the bytes exactly, not the unicode chars.
+          $this->assertTrue(strlen($e->getMessage()) <= $max_allowed_packet, "'max_allowed_packet' exception message truncated.");
+        }
+      }
+      else {
+        $this->verbose('The configured max_allowed_package exceeds the php memory limit. Therefore the test is skipped.');
+      }
+    }
+    else {
+      $this->verbose('The test requires MySQL. Therefore the test is skipped.');
+    }
+  }
+
+}
