зеркало из https://github.com/mozilla/pjs.git
Merge backout
This commit is contained in:
Коммит
b958ffa13d
|
@ -82,9 +82,6 @@ EXTRA_DSO_LDOPTS += \
|
|||
|
||||
LOCAL_INCLUDES += -I$(srcdir)/../../build
|
||||
|
||||
# This is the default value. Must be in sync with the one defined in SQLite.
|
||||
DEFINES += -DSQLITE_DEFAULT_PAGE_SIZE=32768
|
||||
|
||||
EXTRA_COMPONENTS = \
|
||||
toolkitplaces.manifest \
|
||||
nsLivemarkService.js \
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "mozIStorageAsyncStatement.h"
|
||||
|
||||
#include "nsNavBookmarks.h"
|
||||
#include "nsAnnotationService.h"
|
||||
|
@ -142,6 +141,10 @@ using namespace mozilla::places;
|
|||
// Filename used to backup corrupt databases.
|
||||
#define DATABASE_CORRUPT_FILENAME NS_LITERAL_STRING("places.sqlite.corrupt")
|
||||
|
||||
// We use the TRUNCATE journal mode to reduce the number of fsyncs. Without
|
||||
// this setting we had a Ts hit on Linux. See bug 460315 for details.
|
||||
#define DATABASE_JOURNAL_MODE "TRUNCATE"
|
||||
|
||||
// Fraction of free pages in the database to force a vacuum between
|
||||
// DATABASE_MAX_TIME_BEFORE_VACUUM and DATABASE_MIN_TIME_BEFORE_VACUUM.
|
||||
#define DATABASE_VACUUM_FREEPAGES_THRESHOLD 0.1
|
||||
|
@ -374,8 +377,6 @@ PLACES_FACTORY_SINGLETON_IMPLEMENTATION(nsNavHistory, gHistoryService)
|
|||
nsNavHistory::nsNavHistory()
|
||||
: mBatchLevel(0)
|
||||
, mBatchDBTransaction(nsnull)
|
||||
, mDBPageSize(0)
|
||||
, mCurrentJournalMode(JOURNAL_DELETE)
|
||||
, mCachedNow(0)
|
||||
, mExpireNowTimer(nsnull)
|
||||
, mLastSessionID(0)
|
||||
|
@ -619,83 +620,26 @@ nsNavHistory::InitDBFile(PRBool aForceInit)
|
|||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsNavHistory::SetJournalMode(enum JournalMode aJournalMode) {
|
||||
nsCAutoString journalMode;
|
||||
switch (aJournalMode) {
|
||||
case JOURNAL_DELETE:
|
||||
journalMode.AssignLiteral("delete");
|
||||
break;
|
||||
case JOURNAL_TRUNCATE:
|
||||
journalMode.AssignLiteral("truncate");
|
||||
break;
|
||||
case JOURNAL_MEMORY:
|
||||
journalMode.AssignLiteral("memory");
|
||||
break;
|
||||
case JOURNAL_WAL:
|
||||
journalMode.AssignLiteral("wal");
|
||||
break;
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(false, "Trying to set an unknown journal mode.");
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"PRAGMA journal_mode = ") + journalMode,
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mozStorageStatementScoper scoper(statement);
|
||||
PRBool hasResult;
|
||||
rv = statement->ExecuteStep(&hasResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(hasResult, NS_ERROR_FAILURE);
|
||||
|
||||
nsCAutoString currentJournalMode;
|
||||
rv = statement->GetUTF8String(0, currentJournalMode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
bool succeeded = currentJournalMode.Equals(journalMode);
|
||||
NS_WARN_IF_FALSE(succeeded,
|
||||
nsPrintfCString(128, "Setting journal mode failed: %s",
|
||||
PromiseFlatCString(journalMode).get()).get());
|
||||
if (succeeded) {
|
||||
mCurrentJournalMode = aJournalMode;
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsNavHistory::InitDB()
|
||||
{
|
||||
// WARNING:
|
||||
// Any unfinalized statement will cause failure on setting WAL journal mode.
|
||||
// Be sure to avoid them till journal mode has been set.
|
||||
|
||||
// Get the database schema version.
|
||||
PRInt32 currentSchemaVersion = 0;
|
||||
nsresult rv = mDBConn->GetSchemaVersion(¤tSchemaVersion);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
{
|
||||
// Get the page size. This may be different than the default if the
|
||||
// database file already existed with a different page size.
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("PRAGMA page_size"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool hasResult;
|
||||
mozStorageStatementScoper scoper(statement);
|
||||
rv = statement->ExecuteStep(&hasResult);
|
||||
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && hasResult, NS_ERROR_FAILURE);
|
||||
rv = statement->GetInt32(0, &mDBPageSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(mDBPageSize > 0, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
// Get the page size. This may be different than the default if the
|
||||
// database file already existed with a different page size.
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("PRAGMA page_size"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool hasResult;
|
||||
mozStorageStatementScoper scoper(statement);
|
||||
rv = statement->ExecuteStep(&hasResult);
|
||||
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && hasResult, NS_ERROR_FAILURE);
|
||||
PRInt32 pageSize = statement->AsInt32(0);
|
||||
|
||||
// Ensure that temp tables are held in memory, not on disk. We use temp
|
||||
// tables mainly for fsync and I/O reduction.
|
||||
|
@ -727,10 +671,10 @@ nsNavHistory::InitDB()
|
|||
PRInt64 cacheSize = physMem * cachePercentage / 100;
|
||||
|
||||
// Compute number of cached pages, this will be our cache size.
|
||||
PRInt64 cachePages = cacheSize / mDBPageSize;
|
||||
nsCAutoString cacheSizePragma("PRAGMA cache_size = ");
|
||||
cacheSizePragma.AppendInt(cachePages);
|
||||
rv = mDBConn->ExecuteSimpleSQL(cacheSizePragma);
|
||||
PRInt64 cachePages = cacheSize / pageSize;
|
||||
nsCAutoString pageSizePragma("PRAGMA cache_size = ");
|
||||
pageSizePragma.AppendInt(cachePages);
|
||||
rv = mDBConn->ExecuteSimpleSQL(pageSizePragma);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Lock the database file. This is done partly to avoid third party
|
||||
|
@ -739,14 +683,9 @@ nsNavHistory::InitDB()
|
|||
"PRAGMA locking_mode = EXCLUSIVE"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Be sure to set journal mode after page_size, WAL would prevent the change
|
||||
// otherwise.
|
||||
if (NS_FAILED(SetJournalMode(JOURNAL_WAL))) {
|
||||
// Ignore errors, if we fail here the database could be considered corrupt
|
||||
// and we won't be able to go on, even if it's just matter of a bogus
|
||||
// filesystem. The default mode (DELETE) will be fine in such a case.
|
||||
(void)SetJournalMode(JOURNAL_TRUNCATE);
|
||||
}
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"PRAGMA journal_mode = " DATABASE_JOURNAL_MODE));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We are going to initialize tables, so everything from now on should be in
|
||||
// a transaction for performances.
|
||||
|
@ -1841,7 +1780,9 @@ nsNavHistory::MigrateV9Up(mozIStorageConnection *aDBConn)
|
|||
// reducing write times by a half, but will temporary consume more memory
|
||||
// and increase risks of corruption if we should crash in the middle of this
|
||||
// update.
|
||||
(void)SetJournalMode(JOURNAL_MEMORY);
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"PRAGMA journal_mode = MEMORY"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"UPDATE moz_places SET last_visit_date = "
|
||||
|
@ -1851,9 +1792,9 @@ nsNavHistory::MigrateV9Up(mozIStorageConnection *aDBConn)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Restore the default journal mode.
|
||||
if (NS_FAILED(SetJournalMode(JOURNAL_WAL))) {
|
||||
(void)SetJournalMode(JOURNAL_TRUNCATE);
|
||||
}
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"PRAGMA journal_mode = " DATABASE_JOURNAL_MODE));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return transaction.Commit();
|
||||
|
@ -5931,25 +5872,38 @@ nsNavHistory::VacuumDatabase()
|
|||
nsnull);
|
||||
}
|
||||
|
||||
// If journal mode is WAL, a VACUUM cannot upgrade page_size value.
|
||||
// If current page_size is not the expected one, journal mode must be
|
||||
// changed to a rollback one. Once done we won't be able to go back to WAL
|
||||
// mode though, since unfinalized statements exist. Just keep using
|
||||
// compatible mode till next restart.
|
||||
// See http://www.sqlite.org/wal.html
|
||||
if (mCurrentJournalMode == JOURNAL_WAL &&
|
||||
mDBPageSize != SQLITE_DEFAULT_PAGE_SIZE) {
|
||||
(void)SetJournalMode(JOURNAL_TRUNCATE);
|
||||
}
|
||||
// Actually vacuuming a database is a slow operation, since it could take
|
||||
// seconds. Part of the time is spent in updating the journal file on disk
|
||||
// and this is particularly bad on devices with slow I/O. Temporary
|
||||
// moving the journal to memory could increase a bit the possibility of
|
||||
// corruption if we crash during this time, but makes the process really
|
||||
// faster.
|
||||
nsCOMPtr<mozIStorageStatement> journalToMemory;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"PRAGMA journal_mode = MEMORY"),
|
||||
getter_AddRefs(journalToMemory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<mozIStorageAsyncStatement> vacuum;
|
||||
rv = mDBConn->CreateAsyncStatement(NS_LITERAL_CSTRING("VACUUM"),
|
||||
getter_AddRefs(vacuum));
|
||||
nsCOMPtr<mozIStorageStatement> vacuum;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("VACUUM"),
|
||||
getter_AddRefs(vacuum));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> journalToDefault;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"PRAGMA journal_mode = " DATABASE_JOURNAL_MODE),
|
||||
getter_AddRefs(journalToDefault));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mozIStorageBaseStatement *stmts[] = {
|
||||
journalToMemory,
|
||||
vacuum,
|
||||
journalToDefault
|
||||
};
|
||||
nsCOMPtr<mozIStoragePendingStatement> ps;
|
||||
rv = vacuum->ExecuteAsync(nsnull, getter_AddRefs(ps));
|
||||
rv = mDBConn->ExecuteAsync(stmts, NS_ARRAY_LENGTH(stmts), nsnull,
|
||||
getter_AddRefs(ps));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
vacuum->Finalize();
|
||||
|
||||
if (mPrefBranch) {
|
||||
(void)mPrefBranch->SetIntPref(PREF_LAST_VACUUM,
|
||||
|
|
|
@ -122,18 +122,6 @@ namespace places {
|
|||
, DB_SET_PLACE_TITLE = 9
|
||||
};
|
||||
|
||||
enum JournalMode {
|
||||
// Default SQLite jousrnal mode.
|
||||
JOURNAL_DELETE = 0
|
||||
// Can reduce fsyncs on Linux when journal is deleted (See bug 460315).
|
||||
// We fallback to this mode when WAL is unavailable.
|
||||
, JOURNAL_TRUNCATE
|
||||
// Unsafe in case of crashes on database swap or low memory.
|
||||
, JOURNAL_MEMORY
|
||||
// Can reduce number of fsyncs. We try to use this mode by default.
|
||||
, JOURNAL_WAL
|
||||
};
|
||||
|
||||
} // namespace places
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -481,7 +469,6 @@ protected:
|
|||
nsCOMPtr<mozIStorageService> mDBService;
|
||||
nsCOMPtr<mozIStorageConnection> mDBConn;
|
||||
nsCOMPtr<nsIFile> mDBFile;
|
||||
PRInt32 mDBPageSize;
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetURLPageInfo; // kGetInfoIndex_* results
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetIdPageInfo; // kGetInfoIndex_* results
|
||||
|
@ -549,12 +536,6 @@ protected:
|
|||
*/
|
||||
nsresult InitDBFile(PRBool aForceInit);
|
||||
|
||||
/**
|
||||
* Set journal mode on the database.
|
||||
*/
|
||||
nsresult SetJournalMode(enum mozilla::places::JournalMode aJournalMode);
|
||||
enum mozilla::places::JournalMode mCurrentJournalMode;
|
||||
|
||||
/**
|
||||
* Initializes the database. This performs any necessary migrations for the
|
||||
* database. All migration is done inside a transaction that is rolled back
|
||||
|
|
|
@ -138,18 +138,6 @@ nsPlacesDBFlush.prototype = {
|
|||
// Close the database connection, this was the last sync and we can't
|
||||
// ensure database coherence from now on.
|
||||
this._self._finalizeInternalStatements();
|
||||
|
||||
// Before closing the connection we have to set back journal mode to
|
||||
// a backwards compatible value. Newer journal modes like WAL make
|
||||
// the database incompatible with old versions of the browser, setting
|
||||
// an old mode restores database version.
|
||||
// See http://www.sqlite.org/draft/wal.html
|
||||
let journalStmt = this._self._db.createAsyncStatement(
|
||||
"PRAGMA journal_mode = truncate"
|
||||
);
|
||||
journalStmt.executeAsync();
|
||||
journalStmt.finalize();
|
||||
|
||||
this._self._db.asyncClose();
|
||||
}
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
|
|
Загрузка…
Ссылка в новой задаче