diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
index 8c2a34a..4611a94 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
@@ -101,6 +101,22 @@ public static function open(array &$connection_options = array()) {
     return $pdo;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function startTransaction($name = '') {
+    // Pop off and/or commit any transactions that are on the stack before
+    // attempting to create and return a new Transaction object. Menu router
+    // rebuild is the only case in core that creates a new transaction
+    // explicitly.
+    if (!empty($this->transactionLayers)) {
+      foreach ($this->transactionLayers as $savepoint_name) {
+        $this->popTransaction($savepoint_name);
+      }
+    }
+
+    return parent::startTransaction($name);
+  }
 
   public function query($query, array $args = array(), $options = array()) {
 
@@ -274,6 +290,39 @@ public function nextId($existing = 0) {
 
     return $id;
   }
+
+  /**
+   * Add a new savepoint with an unique name.
+   *
+   * The main use for this method is to mimic InnoDB functionality, which
+   * provides an inherent savepoint before any query in a transaction.
+   *
+   * @param $savepoint_name
+   *   A string representing the savepoint name. By default, "mimic_innodb" is
+   *   used.
+   *
+   * @see Drupal\Core\Database\Connection::pushTransaction().
+   */
+  public function addSavepoint($savepoint_name = 'mimic_innodb') {
+    if ($this->inTransaction()) {
+      $this->pushTransaction($savepoint_name);
+    }
+  }
+
+  /**
+   * Release a savepoint by name.
+   *
+   * @param $savepoint_name
+   *   A string representing the savepoint name. By default, "mimic_innodb" is
+   *   used.
+   *
+   * @see Drupal\Core\Database\Connection::popTransaction().
+   */
+  public function releaseSavepoint($savepoint_name = 'mimic_innodb') {
+    if ($this->inTransaction()) {
+      $this->popTransaction($savepoint_name);
+    }
+  }
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Delete.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Delete.php
index e9914ca..1e3ef51 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Delete.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Delete.php
@@ -9,4 +9,17 @@
 
 use Drupal\Core\Database\Query\Delete as QueryDelete;
 
-class Delete extends QueryDelete { }
+class Delete extends QueryDelete {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    $this->connection->addSavepoint();
+    $result = parent::execute();
+    $this->connection->releaseSavepoint();
+
+    return $result;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
index 8b4f913..3d510a2 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
@@ -60,11 +60,16 @@ public function queryTableInformation($table) {
         'sequences' => array(),
       );
       // Don't use {} around information_schema.columns table.
+      $this->connection->addSavepoint();
+
       $result = $this->connection->query("SELECT column_name, data_type, column_default FROM information_schema.columns WHERE table_schema = :schema AND table_name = :table AND (data_type = 'bytea' OR (numeric_precision IS NOT NULL AND column_default LIKE :default))", array(
         ':schema' => $schema,
         ':table' => $table_name,
         ':default' => '%nextval%',
       ));
+
+      $this->connection->releaseSavepoint();
+
       foreach ($result as $column) {
         if ($column->data_type == 'bytea') {
           $table_information->blob_fields[$column->column_name] = TRUE;
@@ -102,11 +107,16 @@ public function queryFieldInformation($table, $field) {
     $schema = $prefixInfo['schema'];
     $table_name = $prefixInfo['table'];
 
+    $this->connection->addSavepoint();
+
     $checks = $this->connection->query("SELECT conname FROM pg_class cl INNER JOIN pg_constraint co ON co.conrelid = cl.oid INNER JOIN pg_attribute attr ON attr.attrelid = cl.oid AND attr.attnum = ANY (co.conkey) INNER JOIN pg_namespace ns ON cl.relnamespace = ns.oid WHERE co.contype = 'c' AND ns.nspname = :schema AND cl.relname = :table AND attr.attname = :column", array(
       ':schema' => $schema,
       ':table' => $table_name,
       ':column' => $field,
     ));
+
+    $this->connection->releaseSavepoint();
+
     $field_information = $checks->fetchCol();
 
     return $field_information;
diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Select.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Select.php
index bf9f23a..185cef9 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Select.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Select.php
@@ -104,6 +104,17 @@ public function orderBy($field, $direction = 'ASC') {
     $this->addField(NULL, $field);
     return $return;
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    $this->connection->addSavepoint();
+    $result = parent::execute();
+    $this->connection->releaseSavepoint();
+
+    return $result;
+  }
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Truncate.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Truncate.php
index e2fa83d..c6d39cf 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Truncate.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Truncate.php
@@ -9,4 +9,16 @@
 
 use Drupal\Core\Database\Query\Truncate as QueryTruncate;
 
-class Truncate extends QueryTruncate { }
+class Truncate extends QueryTruncate {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    $this->connection->addSavepoint();
+    $result = parent::execute();
+    $this->connection->releaseSavepoint();
+
+    return $result;
+  }
+}
