Bug 1411538 - Try to recover tables from a corrupt places.sqlite. r=standard8
authorMarco Bonardo <mbonardo@mozilla.com>
Thu, 07 Dec 2017 14:05:29 +0100
changeset 450327 ec94d6e3e253b752d1b2f6468ea911d8cd66e053
parent 450326 2652447b0840146bba50bcd0428771b9b1cd72b3
child 450328 da8ba47df0fc7b1de810ab0a0d82a703e0729e89
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstandard8
bugs1411538
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1411538 - Try to recover tables from a corrupt places.sqlite. r=standard8 MozReview-Commit-ID: FvuKwIqSt7b
toolkit/components/places/Database.cpp
toolkit/components/places/Database.h
toolkit/components/places/tests/head_common.js
toolkit/components/places/tests/unit/default.sqlite
toolkit/components/places/tests/unit/test_database_replaceOnStartup.js
toolkit/components/places/tests/unit/xpcshell.ini
--- a/toolkit/components/places/Database.cpp
+++ b/toolkit/components/places/Database.cpp
@@ -39,22 +39,26 @@
 
 // Time between corrupt database backups.
 #define RECENT_BACKUP_TIME_MICROSEC (int64_t)86400 * PR_USEC_PER_SEC // 24H
 
 // Filename of the database.
 #define DATABASE_FILENAME NS_LITERAL_STRING("places.sqlite")
 // Filename used to backup corrupt databases.
 #define DATABASE_CORRUPT_FILENAME NS_LITERAL_STRING("places.sqlite.corrupt")
+#define DATABASE_RECOVER_FILENAME NS_LITERAL_STRING("places.sqlite.recover")
 // Filename of the icons database.
 #define DATABASE_FAVICONS_FILENAME NS_LITERAL_STRING("favicons.sqlite")
 
 // Set when the database file was found corrupt by a previous maintenance.
 #define PREF_FORCE_DATABASE_REPLACEMENT "places.database.replaceOnStartup"
 
+// Whether on corruption we should try to fix the database by cloning it.
+#define PREF_DATABASE_CLONEONCORRUPTION "places.database.cloneOnCorruption"
+
 // Set to specify the size of the places database growth increments in kibibytes
 #define PREF_GROWTH_INCREMENT_KIB "places.database.growthIncrementKiB"
 
 // Set to disable the default robust storage and use volatile, in-memory
 // storage without robust transaction flushing guarantees. This makes
 // SQLite use much less I/O at the cost of losing data when things crash.
 // The pref is only honored if an environment variable is set. The env
 // variable is intentionally named something scary to help prevent someone
@@ -570,33 +574,37 @@ Database::EnsureConnection()
     bool databaseCreated = false;
     nsresult rv = InitDatabaseFile(storage, &databaseCreated);
     if (NS_SUCCEEDED(rv) && databaseCreated) {
       mDatabaseStatus = nsINavHistoryService::DATABASE_STATUS_CREATE;
     }
     else if (rv == NS_ERROR_FILE_CORRUPTED) {
       // The database is corrupt, backup and replace it with a new one.
       mDatabaseStatus = nsINavHistoryService::DATABASE_STATUS_CORRUPT;
-      rv = BackupAndReplaceDatabaseFile(storage);
+      rv = BackupAndReplaceDatabaseFile(storage, true);
       // Fallback to catch-all handler.
     }
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Ensure the icons database exists.
     rv = EnsureFaviconsDatabaseFile(storage);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Initialize the database schema.  In case of failure the existing schema is
     // is corrupt or incoherent, thus the database should be replaced.
     bool databaseMigrated = false;
     rv = SetupDatabaseConnection(storage);
+    bool shouldTryToCloneDb = true;
     if (NS_SUCCEEDED(rv)) {
       // Failing to initialize the schema may indicate a corruption.
       rv = InitSchema(&databaseMigrated);
       if (NS_FAILED(rv)) {
+        // Cloning the db on a schema migration may not be a good idea, since we
+        // may end up cloning the schema problems.
+        shouldTryToCloneDb = false;
         if (rv == NS_ERROR_STORAGE_BUSY ||
             rv == NS_ERROR_FILE_IS_LOCKED ||
             rv == NS_ERROR_FILE_NO_DEVICE_SPACE ||
             rv == NS_ERROR_OUT_OF_MEMORY) {
           // The database is not corrupt, though some migration step failed.
           // This may be caused by concurrent use of sync and async Storage APIs
           // or by a system issue.
           // The best we can do is trying again. If it should still fail, Places
@@ -612,17 +620,17 @@ Database::EnsureConnection()
     }
     if (NS_WARN_IF(NS_FAILED(rv))) {
       if (rv != NS_ERROR_FILE_IS_LOCKED) {
         mDatabaseStatus = nsINavHistoryService::DATABASE_STATUS_CORRUPT;
       }
       // Some errors may not indicate a database corruption, for those cases we
       // just bail out without throwing away a possibly valid places.sqlite.
       if (rv == NS_ERROR_FILE_CORRUPTED) {
-        rv = BackupAndReplaceDatabaseFile(storage);
+        rv = BackupAndReplaceDatabaseFile(storage, shouldTryToCloneDb);
         NS_ENSURE_SUCCESS(rv, rv);
         // Try to initialize the new database again.
         rv = SetupDatabaseConnection(storage);
         NS_ENSURE_SUCCESS(rv, rv);
         rv = InitSchema(&databaseMigrated);
       }
       // Bail out if we couldn't fix the database.
       NS_ENSURE_SUCCESS(rv, rv);
@@ -764,17 +772,18 @@ Database::InitDatabaseFile(nsCOMPtr<mozI
   rv = aStorage->OpenUnsharedDatabase(databaseFile, getter_AddRefs(mMainConn));
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aNewDatabaseCreated = !databaseFileExists;
   return NS_OK;
 }
 
 nsresult
-Database::BackupAndReplaceDatabaseFile(nsCOMPtr<mozIStorageService>& aStorage)
+Database::BackupAndReplaceDatabaseFile(nsCOMPtr<mozIStorageService>& aStorage,
+                                       bool aTryToClone)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsCOMPtr<nsIFile> profDir;
   nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
                                        getter_AddRefs(profDir));
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIFile> databaseFile;
   rv = profDir->Clone(getter_AddRefs(databaseFile));
@@ -797,17 +806,19 @@ Database::BackupAndReplaceDatabaseFile(n
   // database file, and there's not much more we can do.
   // The only thing we can try to do is to replace the database on the next
   // startup, and report the problem through telemetry.
   {
     enum eCorruptDBReplaceStage : int8_t {
       stage_closing = 0,
       stage_removing,
       stage_reopening,
-      stage_replaced
+      stage_replaced,
+      stage_cloning,
+      stage_cloned
     };
     eCorruptDBReplaceStage stage = stage_closing;
     auto guard = MakeScopeExit([&]() {
       if (stage != stage_replaced) {
         // Reaching this point means the database is corrupt and we failed to
         // replace it.  For this session part of the application related to
         // bookmarks and history will misbehave.  The frontend may show a
         // "locked" notification to the user though.
@@ -827,26 +838,150 @@ Database::BackupAndReplaceDatabaseFile(n
 
     // Remove the broken database.
     stage = stage_removing;
     rv = databaseFile->Remove(false);
     if (NS_FAILED(rv) && rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
       return rv;
     }
 
-    // Create a new database file.
+    // Create a new database file and try to clone tables from the corrupt one.
+    bool cloned = false;
+    if (aTryToClone && Preferences::GetBool(PREF_DATABASE_CLONEONCORRUPTION, true)) {
+      stage = stage_cloning;
+      rv = TryToCloneTablesFromCorruptDatabase(aStorage);
+      if (NS_SUCCEEDED(rv)) {
+        mDatabaseStatus = nsINavHistoryService::DATABASE_STATUS_OK;
+        cloned = true;
+      }
+    }
+
     // Use an unshared connection, it will consume more memory but avoid shared
     // cache contentions across threads.
     stage = stage_reopening;
     rv = aStorage->OpenUnsharedDatabase(databaseFile, getter_AddRefs(mMainConn));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    stage = stage_replaced;
+    stage = cloned ? stage_cloned : stage_replaced;
+  }
+
+  return NS_OK;
+}
+
+nsresult
+Database::TryToCloneTablesFromCorruptDatabase(nsCOMPtr<mozIStorageService>& aStorage)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  nsCOMPtr<nsIFile> profDir;
+  nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+                                       getter_AddRefs(profDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIFile> corruptFile;
+  rv = profDir->Clone(getter_AddRefs(corruptFile));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = corruptFile->Append(DATABASE_CORRUPT_FILENAME);
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsAutoString path;
+  rv = corruptFile->GetPath(path);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIFile> recoverFile;
+  rv = profDir->Clone(getter_AddRefs(recoverFile));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = recoverFile->Append(DATABASE_RECOVER_FILENAME);
+  NS_ENSURE_SUCCESS(rv, rv);
+  // Ensure there's no previous recover file.
+  rv = recoverFile->Remove(false);
+  if (NS_FAILED(rv) && rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST &&
+                       rv != NS_ERROR_FILE_NOT_FOUND) {
+    return rv;
   }
 
+  nsCOMPtr<mozIStorageConnection> conn;
+  auto guard = MakeScopeExit([&]() {
+    if (conn) {
+      Unused << conn->Close();
+    }
+    Unused << recoverFile->Remove(false);
+  });
+
+  rv = aStorage->OpenUnsharedDatabase(recoverFile, getter_AddRefs(conn));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = AttachDatabase(conn, NS_ConvertUTF16toUTF8(path),
+                      NS_LITERAL_CSTRING("corrupt"));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mozStorageTransaction transaction(conn, false);
+
+  // Copy the schema version.
+  nsCOMPtr<mozIStorageStatement> stmt;
+  (void)conn->CreateStatement(NS_LITERAL_CSTRING("PRAGMA corrupt.user_version"),
+                              getter_AddRefs(stmt));
+  NS_ENSURE_TRUE(stmt, NS_ERROR_OUT_OF_MEMORY);
+  bool hasResult;
+  rv = stmt->ExecuteStep(&hasResult);
+  NS_ENSURE_SUCCESS(rv, rv);
+  int32_t schemaVersion = stmt->AsInt32(0);
+  rv = conn->SetSchemaVersion(schemaVersion);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Recreate the tables.
+  rv = conn->CreateStatement(NS_LITERAL_CSTRING(
+    "SELECT name, sql FROM corrupt.sqlite_master "
+    "WHERE type = 'table' AND name BETWEEN 'moz_' AND 'moza'"
+  ), getter_AddRefs(stmt));
+  NS_ENSURE_SUCCESS(rv, rv);
+  while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
+    nsAutoCString name;
+    rv = stmt->GetUTF8String(0, name);
+    NS_ENSURE_SUCCESS(rv, rv);
+    nsAutoCString query;
+    rv = stmt->GetUTF8String(1, query);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = conn->ExecuteSimpleSQL(query);
+    NS_ENSURE_SUCCESS(rv, rv);
+    // Copy the table contents.
+    rv = conn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("INSERT INTO main.") +
+     name + NS_LITERAL_CSTRING(" SELECT * FROM corrupt.") + name);
+    if (NS_FAILED(rv)) {
+      rv = conn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("INSERT INTO main.") +
+            name + NS_LITERAL_CSTRING(" SELECT * FROM corrupt.") + name +
+            NS_LITERAL_CSTRING(" ORDER BY rowid DESC"));
+    }
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  // Recreate the indices.  Doing this after data addition is faster.
+  rv = conn->CreateStatement(NS_LITERAL_CSTRING(
+    "SELECT sql FROM corrupt.sqlite_master "
+    "WHERE type <> 'table' AND name BETWEEN 'moz_' AND 'moza'"
+  ), getter_AddRefs(stmt));
+  NS_ENSURE_SUCCESS(rv, rv);
+  hasResult = false;
+  while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
+    nsAutoCString query;
+    rv = stmt->GetUTF8String(0, query);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = conn->ExecuteSimpleSQL(query);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+  rv = stmt->Finalize();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = transaction.Commit();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  Unused << conn->Close();
+  conn = nullptr;
+  rv = recoverFile->RenameTo(profDir, DATABASE_FILENAME);
+  NS_ENSURE_SUCCESS(rv, rv);
+  Unused << corruptFile->Remove(false);
+
+  guard.release();
   return NS_OK;
 }
 
 nsresult
 Database::SetupDatabaseConnection(nsCOMPtr<mozIStorageService>& aStorage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
--- a/toolkit/components/places/Database.h
+++ b/toolkit/components/places/Database.h
@@ -236,18 +236,29 @@ protected:
   nsresult EnsureFaviconsDatabaseFile(nsCOMPtr<mozIStorageService>& aStorage);
 
   /**
    * Creates a database backup and replaces the original file with a new
    * one.
    *
    * @param aStorage
    *        mozStorage service instance.
+   * @param aTryToClone
+   *        whether we should try to clone a corrupt database.
    */
-  nsresult BackupAndReplaceDatabaseFile(nsCOMPtr<mozIStorageService>& aStorage);
+  nsresult BackupAndReplaceDatabaseFile(nsCOMPtr<mozIStorageService>& aStorage,
+                                        bool aTryToClone);
+
+  /**
+   * Tries to recover tables and their contents from a corrupt database.
+   *
+   * @param aStorage
+   *        mozStorage service instance.
+   */
+  nsresult TryToCloneTablesFromCorruptDatabase(nsCOMPtr<mozIStorageService>& aStorage);
 
   /**
    * Set up the connection environment through PRAGMAs.
    * Will return NS_ERROR_FILE_CORRUPTED if any critical setting fails.
    *
    * @param aStorage
    *        mozStorage service instance.
    */
--- a/toolkit/components/places/tests/head_common.js
+++ b/toolkit/components/places/tests/head_common.js
@@ -23,43 +23,32 @@ const TRANSITION_REDIRECT_TEMPORARY = Ci
 const TRANSITION_DOWNLOAD = Ci.nsINavHistoryService.TRANSITION_DOWNLOAD;
 const TRANSITION_RELOAD = Ci.nsINavHistoryService.TRANSITION_RELOAD;
 
 const TITLE_LENGTH_MAX = 4096;
 
 Cu.importGlobalProperties(["URL"]);
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
-                                  "resource://gre/modules/FileUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
-                                  "resource://gre/modules/NetUtil.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
-                                  "resource://gre/modules/PromiseUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Services",
-                                  "resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "BookmarkJSONUtils",
-                                  "resource://gre/modules/BookmarkJSONUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils",
-                                  "resource://gre/modules/BookmarkHTMLUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups",
-                                  "resource://gre/modules/PlacesBackups.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesSyncUtils",
-                                  "resource://gre/modules/PlacesSyncUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
-                                  "resource://testing-common/PlacesTestUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesTransactions",
-                                  "resource://gre/modules/PlacesTransactions.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "OS",
-                                  "resource://gre/modules/osfile.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Sqlite",
-                                  "resource://gre/modules/Sqlite.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "TestUtils",
-                                  "resource://testing-common/TestUtils.jsm");
-
+XPCOMUtils.defineLazyModuleGetters(this, {
+  FileUtils: "resource://gre/modules/FileUtils.jsm",
+  NetUtil: "resource://gre/modules/NetUtil.jsm",
+  PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
+  Services: "resource://gre/modules/Services.jsm",
+  BookmarkJSONUtils: "resource://gre/modules/BookmarkJSONUtils.jsm",
+  BookmarkHTMLUtils: "resource://gre/modules/BookmarkHTMLUtils.jsm",
+  PlacesBackups: "resource://gre/modules/PlacesBackups.jsm",
+  PlacesSyncUtils: "resource://gre/modules/PlacesSyncUtils.jsm",
+  PlacesTestUtils: "resource://testing-common/PlacesTestUtils.jsm",
+  PlacesTransactions: "resource://gre/modules/PlacesTransactions.jsm",
+  OS: "resource://gre/modules/osfile.jsm",
+  Sqlite: "resource://gre/modules/Sqlite.jsm",
+  TestUtils: "resource://testing-common/TestUtils.jsm",
+  AppConstants: "resource://gre/modules/AppConstants.jsm",
+});
 // This imports various other objects in addition to PlacesUtils.
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "SMALLPNG_DATA_URI", function() {
   return NetUtil.newURI(
          "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAA" +
          "AAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==");
 });
deleted file mode 100644
index 8fbd3bc9acab0abff5305d493d9568a10b36d08b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/toolkit/components/places/tests/unit/test_database_replaceOnStartup.js
+++ b/toolkit/components/places/tests/unit/test_database_replaceOnStartup.js
@@ -1,46 +1,60 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that history initialization correctly handles a request to forcibly
 // replace the current database.
 
-function run_test() {
-  // Ensure that our database doesn't already exist.
-  let dbFile = gProfD.clone();
-  dbFile.append("places.sqlite");
-  Assert.ok(!dbFile.exists());
+add_task(async function() {
+  registerCleanupFunction(function() {
+    Services.prefs.clearUserPref("places.database.cloneOnCorruption");
+  });
+  test_replacement(true);
+  test_replacement(false);
+});
 
-  dbFile = gProfD.clone();
-  dbFile.append("places.sqlite.corrupt");
-  Assert.ok(!dbFile.exists());
+async function test_replacement(shouldClone) {
+  Services.prefs.setBoolPref("places.database.cloneOnCorruption", shouldClone);
+  // Ensure that our databases don't exist yet.
+  let sane = OS.Path.join(OS.Constants.Path.profileDir, "places.sqlite");
+  Assert.ok(!await OS.File.exists(sane), "The db should not exist initially");
+  let corrupt = OS.Path.join(OS.Constants.Path.profileDir, "places.sqlite.corrupt");
+  Assert.ok(!await OS.File.exists(corrupt), "The corrupt db should not exist initially");
 
-  let file = do_get_file("default.sqlite");
+  let file = do_get_file("../migration/places_v38.sqlite");
   file.copyToFollowingLinks(gProfD, "places.sqlite");
   file = gProfD.clone();
   file.append("places.sqlite");
 
   // Create some unique stuff to check later.
   let db = Services.storage.openUnsharedDatabase(file);
-  db.executeSimpleSQL("CREATE TABLE test (id INTEGER PRIMARY KEY)");
+  db.executeSimpleSQL("CREATE TABLE moz_cloned(id INTEGER PRIMARY KEY)");
+  db.executeSimpleSQL("CREATE TABLE not_cloned (id INTEGER PRIMARY KEY)");
+  db.executeSimpleSQL("DELETE FROM moz_cloned"); // Shouldn't throw.
   db.close();
 
+  // Open the database with Places.
   Services.prefs.setBoolPref("places.database.replaceOnStartup", true);
-  Assert.equal(PlacesUtils.history.databaseStatus,
-               PlacesUtils.history.DATABASE_STATUS_CORRUPT);
+  let expectedStatus = shouldClone ? PlacesUtils.history.DATABASE_STATUS_UPGRADED
+                                   : PlacesUtils.history.DATABASE_STATUS_CORRUPT;
+  Assert.equal(PlacesUtils.history.databaseStatus, expectedStatus);
 
-  dbFile = gProfD.clone();
-  dbFile.append("places.sqlite");
-  Assert.ok(dbFile.exists());
+  Assert.ok(await OS.File.exists(sane), "The database should exist");
+
+  // Check the new database still contains our special data.
+  db = Services.storage.openUnsharedDatabase(file);
+  if (shouldClone) {
+    db.executeSimpleSQL("DELETE FROM moz_cloned"); // Shouldn't throw.
+  }
 
   // Check the new database is really a new one.
-  db = Services.storage.openUnsharedDatabase(file);
-  try {
-    db.executeSimpleSQL("DELETE * FROM test");
-    do_throw("The new database should not have our unique content");
-  } catch (ex) {}
+  Assert.throws(() => {
+    db.executeSimpleSQL("DELETE FROM not_cloned");
+  }, "The database should have been replaced");
   db.close();
 
-  dbFile = gProfD.clone();
-  dbFile.append("places.sqlite.corrupt");
-  Assert.ok(dbFile.exists());
+  if (shouldClone) {
+    Assert.ok(!await OS.File.exists(corrupt), "The corrupt db should not exist");
+  } else {
+    Assert.ok(await OS.File.exists(corrupt), "The corrupt db should exist");
+  }
 }
--- a/toolkit/components/places/tests/unit/xpcshell.ini
+++ b/toolkit/components/places/tests/unit/xpcshell.ini
@@ -4,17 +4,16 @@ firefox-appdir = browser
 support-files =
   bookmarks.corrupt.html
   bookmarks.json
   bookmarks_corrupt.json
   bookmarks.preplaces.html
   bookmarks_html_singleframe.html
   bug476292.sqlite
   corruptDB.sqlite
-  default.sqlite
   livemark.xml
   mobile_bookmarks_folder_import.json
   mobile_bookmarks_folder_merge.json
   mobile_bookmarks_multiple_folders.json
   mobile_bookmarks_root_import.json
   mobile_bookmarks_root_merge.json
   nsDummyObserver.js
   nsDummyObserver.manifest