diff --git a/includes/database/database.inc b/includes/database/database.inc
index 4cc1a33..de7943f 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -211,6 +211,13 @@ abstract class DatabaseConnection extends PDO {
   protected $logger = NULL;
 
   /**
+   * The current database change logging object for this connection.
+   *
+   * @var DatabaseChangeLog
+   */
+  protected $changeLogger = NULL;
+
+  /**
    * Tracks the number of "layers" of transactions currently active.
    *
    * On many databases transactions cannot nest.  Instead, we track
@@ -511,6 +518,10 @@ abstract class DatabaseConnection extends PDO {
     $this->logger = $logger;
   }
 
+  public function setChangeLogger(DatabaseChangeLog $logger) {
+    $this->changeLogger = $logger;
+  }
+
   /**
    * Gets the current logging object for this connection.
    *
@@ -523,6 +534,17 @@ abstract class DatabaseConnection extends PDO {
   }
 
   /**
+   * Gets the current change logging object for this connection.
+   *
+   * @return DatabaseChangeLog
+   *   The current change logging object for this connection. If there isn't
+   *   one, NULL is returned.
+   */
+  public function getChangeLogger() {
+    return $this->changeLogger;
+  }
+
+  /**
    * Creates the appropriate sequence name for a given table and serial field.
    *
    * This information is exposed to all database drivers, although it is only
@@ -1328,6 +1350,20 @@ abstract class Database {
   static protected $logs = array();
 
   /**
+   * An array of active query change log objects.
+   *
+   * Every connection has one and only one change logger object for all
+   * targets and logging keys.
+   *
+   * array(
+   *   '$db_key' => DatabaseChangeLog object.
+   * );
+   *
+   * @var array
+   */
+  static protected $changeLogs = array();
+
+  /**
    * Starts logging a given logging key on the specified connection.
    *
    * @param $logging_key
@@ -1360,6 +1396,38 @@ abstract class Database {
   }
 
   /**
+   * Starts logging changes a given logging key on the specified connection.
+   *
+   * @param $logging_key
+   *   The logging key to log changes.
+   * @param $key
+   *   The database connection key for which we want to log change.
+   *
+   * @return DatabaseChangeLog
+   *   The query change log object. Note that the log object does support
+   *   richer methods than the few exposed through the Database class, so in
+   *   some cases it may be desirable to access it directly.
+   *
+   * @see DatabaseChangeLog
+   */
+  final public static function startChangeLog($logging_key, $key = 'default') {
+    if (empty(self::$changeLogs[$key])) {
+      self::$changeLogs[$key] = new DatabaseChangeLog($key);
+
+      // Every target already active for this connection key needs to have the
+      // logging object associated with it.  
+      if (!empty(self::$connections[$key])) {
+        foreach (self::$connections[$key] as $connection) {
+          $connection->setChangeLogger(self::$changeLogs[$key]);
+        }
+      }  
+    }  
+
+    self::$changeLogs[$key]->start($logging_key);
+    return self::$changeLogs[$key];
+  }
+
+  /**
    * Retrieves the queries logged on for given logging key.
    *
    * This method also ends logging for the specified key. To get the query log
@@ -1387,6 +1455,33 @@ abstract class Database {
   }
 
   /**
+   * Retrieves the queries logged on for given logging key.
+   *
+   * This method also ends logging for the specified key. To get the query log
+   * to date without ending the logger request the logging object by starting
+   * it again (which does nothing to an open log key) and call methods on it as
+   * desired.
+   *
+   * @param $logging_key
+   *   The logging key to log.
+   * @param $key
+   *   The database connection key for which we want to log.
+   *
+   * @return array
+   *   The query log for the specified logging key and connection.
+   *
+   * @see DatabaseLog
+   */
+  final public static function getChangeLog($logging_key, $key = 'default') {
+    if (empty(self::$changeLogs[$key])) {
+      return NULL;
+    }
+    $queries = self::$changeLogs[$key]->get($logging_key);
+    self::$changeLogs[$key]->end($logging_key);
+    return $queries;
+  }
+
+  /**
    * Gets the connection object for the specified database key and target.
    *
    * Note: do not use the setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE) on the
@@ -1615,6 +1710,7 @@ abstract class Database {
     // If the requested database does not exist then it is an unrecoverable
     // error.
     if (!isset(self::$databaseInfo[$key])) {
+var_dump(debug_backtrace());
       throw new DatabaseConnectionNotDefinedException('The specified database connection is not defined: ' . $key);
     }
 
diff --git a/includes/database/log.inc b/includes/database/log.inc
index ec27ef8..a39173e 100644
--- a/includes/database/log.inc
+++ b/includes/database/log.inc
@@ -157,3 +157,45 @@ class DatabaseLog {
     }
   }
 }
+
+/**
+ * Database change query logger.
+ *
+ * We log change queries in a separate object rather than in the connection
+ * object because we want to be able to see all queries sent to a given
+ * database, not database target. If we logged the queries in each connection
+ * object we would not be able to track what queries went to which target.
+ *
+ * Every connection has one and only one change logging object on it for all
+ * targets and logging keys.
+ */
+class DatabaseChangeLog extends DatabaseLog {
+
+  /**
+   * Log a change query to all active logging keys.
+   *
+   * @param $table
+   *   The table being changed.
+   * @param $query
+   *   The SQL query string or DatabaseStatementInterface passed to
+   *   DatabaseConnection::query().
+   * @param $args
+   *   The arguments passed to DatabaseConnection::query().
+   * @param $options
+   *   The options passed to DatabaseConnection::query().
+   * @param $time
+   *   The time in milliseconds the query took to execute.
+   */
+  public function log($table, $query, $args, $options, $time) {
+    foreach (array_keys($this->queryLog) as $key) {
+      $this->queryLog[$key][] = array(
+        'query' => $query,
+        'table' => $table,
+        'args' => $args,
+        'options' => $options,
+#        'caller' => $this->findCaller(),
+        'time' => $time,
+      );
+    }
+  }
+}
diff --git a/includes/database/mysql/query.inc b/includes/database/mysql/query.inc
index 888b6a5..6a06fdf 100644
--- a/includes/database/mysql/query.inc
+++ b/includes/database/mysql/query.inc
@@ -32,8 +32,16 @@ class InsertQuery_mysql extends InsertQuery {
     else {
       $values = $this->fromQuery->getArguments();
     }
-
-    $last_insert_id = $this->connection->query((string) $this, $values, $this->queryOptions);
+    $change_logger = $this->connection->getChangeLogger();
+    if (!empty($change_logger)) {
+      $query_start = microtime(TRUE);
+    }
+    $sql = (string) $this;
+    $last_insert_id = $this->connection->query($sql, $values, $this->queryOptions);
+    if (!empty($change_logger)) {
+      $query_end = microtime(TRUE);
+      $change_logger->log($this->table, $sql, $insert_values, $this->queryOptions, $query_end - $query_start);
+    }
 
     // Re-initialize the values array so that we can re-use this query.
     $this->insertValues = array();
diff --git a/includes/database/query.inc b/includes/database/query.inc
index 23b652f..1aafb55 100644
--- a/includes/database/query.inc
+++ b/includes/database/query.inc
@@ -77,7 +77,7 @@ interface QueryConditionInterface {
 
   /**
    * Sets a condition that the specified subquery returns values.
-   * 
+   *
    * @param SelectQueryInterface $select
    *   The subquery that must contain results.
    *
@@ -85,10 +85,10 @@ interface QueryConditionInterface {
    *   The called object.
    */
   public function exists(SelectQueryInterface $select);
-  
+
   /**
    * Sets a condition that the specified subquery returns no values.
-   * 
+   *
    * @param SelectQueryInterface $select
    *   The subquery that must not contain results.
    *
@@ -96,7 +96,7 @@ interface QueryConditionInterface {
    *   The called object.
    */
   public function notExists(SelectQueryInterface $select);
-  
+
   /**
    * Gets a complete list of all conditions in this conditional clause.
    *
@@ -264,14 +264,14 @@ abstract class Query implements QueryPlaceholderInterface {
 
   /**
    * The target of the connection object.
-   * 
+   *
    * @var string
    */
   protected $connectionTarget;
 
   /**
    * The key of the connection object.
-   * 
+   *
    * @var string
    */
   protected $connectionKey;
@@ -597,11 +597,19 @@ class InsertQuery extends Query {
     // we wrap it in a transaction so that it is atomic where possible. On many
     // databases, such as SQLite, this is also a notable performance boost.
     $transaction = $this->connection->startTransaction();
+    $change_logger = $this->connection->getChangeLogger();
 
     try {
       $sql = (string) $this;
       foreach ($this->insertValues as $insert_values) {
+        if (!empty($change_logger)) {
+          $query_start = microtime(TRUE);
+        }
         $last_insert_id = $this->connection->query($sql, $insert_values, $this->queryOptions);
+        if (!empty($change_logger)) {
+          $query_end = microtime(TRUE);
+          $change_logger->log($this->table, $sql, $insert_values, $this->queryOptions, $query_end - $query_start);
+        }
       }
     }
     catch (Exception $e) {
@@ -764,7 +772,7 @@ class DeleteQuery extends Query implements QueryConditionInterface {
     $this->condition->notExists($select);
     return $this;
   }
-  
+
   /**
    * Implements QueryConditionInterface::conditions().
    */
@@ -807,7 +815,17 @@ class DeleteQuery extends Query implements QueryConditionInterface {
       $values = $this->condition->arguments();
     }
 
-    return $this->connection->query((string) $this, $values, $this->queryOptions);
+    $change_logger = $this->connection->getChangeLogger();
+    if (!empty($change_logger)) {
+      $query_start = microtime(TRUE);
+    }
+    $sql = (string) $this;
+    $return = $this->connection->query($sql, $values, $this->queryOptions);
+    if (!empty($change_logger)) {
+      $query_end = microtime(TRUE);
+      $change_logger->log($this->table, $sql, $values, $this->queryOptions, $query_end - $query_start);
+    }
+    return $return;
   }
 
   /**
@@ -875,7 +893,17 @@ class TruncateQuery extends Query {
    *   Return value is dependent on the database type.
    */
   public function execute() {
-    return $this->connection->query((string) $this, array(), $this->queryOptions);
+    $change_logger = $this->connection->getChangeLogger();
+    if (!empty($change_logger)) {
+      $query_start = microtime(TRUE);
+    }
+    $sql = (string) $this;
+    $return = $this->connection->query($sql, array(), $this->queryOptions);
+    if (!empty($change_logger)) {
+      $query_end = microtime(TRUE);
+      $change_logger->log($this->table, $sql, array(), $this->queryOptions, $query_end - $query_start);
+    }
+    return $return;
   }
 
   /**
@@ -999,7 +1027,7 @@ class UpdateQuery extends Query implements QueryConditionInterface {
     $this->condition->notExists($select);
     return $this;
   }
-  
+
   /**
    * Implements QueryConditionInterface::conditions().
    */
@@ -1102,7 +1130,17 @@ class UpdateQuery extends Query implements QueryConditionInterface {
       $update_values = array_merge($update_values, $this->condition->arguments());
     }
 
-    return $this->connection->query((string) $this, $update_values, $this->queryOptions);
+    $change_logger = $this->connection->getChangeLogger();
+    if (!empty($change_logger)) {
+      $query_start = microtime(TRUE);
+    }
+    $sql = (string) $this;
+    $return = $this->connection->query($sql, $update_values, $this->queryOptions);
+    if (!empty($change_logger)) {
+      $query_end = microtime(TRUE);
+      $change_logger->log($this->table, $sql, $update_values, $this->queryOptions, $query_end - $query_start);
+    }
+    return $return;
   }
 
   /**
@@ -1484,7 +1522,7 @@ class MergeQuery extends Query implements QueryConditionInterface {
     $this->condition->notExists($select);
     return $this;
   }
-  
+
   /**
    * Implements QueryConditionInterface::conditions().
    */
@@ -1689,14 +1727,14 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
   public function exists(SelectQueryInterface $select) {
     return $this->condition('', $select, 'EXISTS');
   }
-  
+
   /**
    * Implements QueryConditionInterface::notExists().
    */
   public function notExists(SelectQueryInterface $select) {
     return $this->condition('', $select, 'NOT EXISTS');
   }
-  
+
   /**
    * Implements QueryConditionInterface::conditions().
    */
diff --git a/includes/database/sqlite/query.inc b/includes/database/sqlite/query.inc
index 6b8a72f..3a9a1f9 100644
--- a/includes/database/sqlite/query.inc
+++ b/includes/database/sqlite/query.inc
@@ -27,7 +27,16 @@ class InsertQuery_sqlite extends InsertQuery {
       return parent::execute();
     }
     else {
-      return $this->connection->query('INSERT INTO {' . $this->table . '} DEFAULT VALUES', array(), $this->queryOptions);
+      $change_logger = $this->connection->getChangeLogger();
+      $sql = 'INSERT INTO {' . $this->table . '} DEFAULT VALUES';
+      if (!empty($change_logger)) {
+        $query_start = microtime(TRUE);
+      }
+      $return = $this->connection->query($sql, array(), $this->queryOptions);
+      if (!empty($change_logger)) {
+        $query_end = microtime(TRUE);
+        $change_logger->log($this->table, $sql, array(), $this->queryOptions, $query_end - $query_start);
+      }
     }
   }
 
diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index b60c682..0c54e10 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -1232,11 +1232,16 @@ class DrupalWebTestCase extends DrupalTestCase {
     global $user, $language, $conf;
 
     // Generate a temporary prefixed database to ensure that tests have a clean starting point.
-    $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000);
-    db_update('simpletest_test_id')
-      ->fields(array('last_prefix' => $this->databasePrefix))
-      ->condition('test_id', $this->testId)
-      ->execute();
+    $changelog_key = 'DrupalWebTestCase::setup';
+    $queries = Database::getChangeLog($changelog_key);
+    if (!$queries) {
+      $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000);
+      db_update('simpletest_test_id')
+        ->fields(array('last_prefix' => $this->databasePrefix))
+        ->condition('test_id', $this->testId)
+        ->execute();
+      Database::startChangeLog($changelog_key);
+    }
 
     // Clone the current connection and replace the current prefix.
     $connection_info = Database::getConnectionInfo('default');
@@ -1289,23 +1294,36 @@ class DrupalWebTestCase extends DrupalTestCase {
     $test_info['test_run_id'] = $this->databasePrefix;
     $test_info['in_child_site'] = FALSE;
 
-    include_once DRUPAL_ROOT . '/includes/install.inc';
-    drupal_install_system();
-
-    $this->preloadRegistry();
+    if ($queries) {
+      $empty = array();
+      $connection = Database::getConnection();
+      foreach ($queries as $query) {
+        if (!isset($empty[$query['table']])) {
+          db_truncate($query['table'])->execute();
+          $empty[$query['table']] = TRUE;
+        }
+        $connection->query($query['query'], $query['args'], $query['options']);
+      }
+    }
+    else {
+      include_once DRUPAL_ROOT . '/includes/install.inc';
+      drupal_install_system();
 
-    // Set path variables.
-    variable_set('file_public_path', $public_files_directory);
-    variable_set('file_private_path', $private_files_directory);
-    variable_set('file_temporary_path', $temp_files_directory);
+      // Set path variables.
+      variable_set('file_public_path', $public_files_directory);
+      variable_set('file_private_path', $private_files_directory);
+      variable_set('file_temporary_path', $temp_files_directory);
 
-    // Include the testing profile.
-    variable_set('install_profile', $this->profile);
-    $profile_details = install_profile_info($this->profile, 'en');
+      // Include the testing profile.
+      variable_set('install_profile', $this->profile);
+      $profile_details = install_profile_info($this->profile, 'en');
 
-    // Install the modules specified by the testing profile.
-    module_enable($profile_details['dependencies'], FALSE);
+      // Install the modules specified by the testing profile.
+      module_enable($profile_details['dependencies'], FALSE);
+      Database::getChangeLog($changelog_key);
+    }
 
+    Database::startChangeLog('simpletest');
     // Install modules needed for this test. This could have been passed in as
     // either a single array argument or a variable number of string arguments.
     // @todo Remove this compatibility layer in Drupal 8, and only accept
@@ -1354,42 +1372,6 @@ class DrupalWebTestCase extends DrupalTestCase {
   }
 
   /**
-   * Preload the registry from the testing site.
-   *
-   * This method is called by DrupalWebTestCase::setUp(), and preloads the
-   * registry from the testing site to cut down on the time it takes to
-   * set up a clean environment for the current test run.
-   */
-  protected function preloadRegistry() {
-    // Use two separate queries, each with their own connections: copy the
-    // {registry} and {registry_file} tables over from the parent installation
-    // to the child installation.
-    $original_connection = Database::getConnection('default', 'simpletest_original_default');
-    $test_connection = Database::getConnection();
-
-    foreach (array('registry', 'registry_file') as $table) {
-      // Find the records from the parent database.
-      $source_query = $original_connection
-        ->select($table, array(), array('fetch' => PDO::FETCH_ASSOC))
-        ->fields($table);
-
-      $dest_query = $test_connection->insert($table);
-
-      $first = TRUE;
-      foreach ($source_query->execute() as $row) {
-        if ($first) {
-          $dest_query->fields(array_keys($row));
-          $first = FALSE;
-        }
-        // Insert the records into the child database.
-        $dest_query->values($row);
-      }
-
-      $dest_query->execute();
-    }
-  }
-
-  /**
    * Reset all data structures after having enabled new modules.
    *
    * This method is called by DrupalWebTestCase::setUp() after enabling
@@ -1453,10 +1435,24 @@ class DrupalWebTestCase extends DrupalTestCase {
     // Delete temporary files directory.
     file_unmanaged_delete_recursive($this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10));
 
-    // Remove all prefixed tables (all the tables in the schema).
-    $schema = drupal_get_schema(NULL, TRUE);
-    foreach ($schema as $name => $table) {
-      db_drop_table($name);
+    $queries = Database::getChangeLog('simpletest');
+    file_put_contents('/tmp/log', var_export($queries, TRUE));
+    if ($queries) {
+      $dropped = array();
+      foreach ($queries as $query) {
+        $table = $query['table'];
+        if ($table != 'simpletest' && $table != 'simpletest_test_id' && !isset($dropped[$table])) {
+          db_drop_table($query['table'])->execute();
+          $dropped[$query['table']] = TRUE;
+        }
+      }
+    }
+    else {
+      // Remove all prefixed tables (all the tables in the schema).
+      $schema = drupal_get_schema(NULL, TRUE);
+      foreach ($schema as $name => $table) {
+        db_drop_table($name);
+      }
     }
 
     // Get back to the original connection.
