mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-23 10:54:33 +00:00
Bug 581606 - Avoid sqlite fragmentation via SQLITE_FCNTL_CHUNK_SIZE r=asuth sr=shaver a=b6
This commit is contained in:
parent
ca8bdb6f3c
commit
96bd2a13d9
@ -735,6 +735,9 @@ nsCookieService::TryInitDB(PRBool aDeleteExistingDB)
|
||||
rv = mStorageService->OpenDatabase(cookieFile, getter_AddRefs(mDBState->dbConn));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Grow cookie db in 512KB increments
|
||||
mDBState->dbConn->SetGrowthIncrement(512 * 1024, EmptyCString());
|
||||
|
||||
PRBool tableExists = PR_FALSE;
|
||||
mDBState->dbConn->TableExists(NS_LITERAL_CSTRING("moz_cookies"), &tableExists);
|
||||
if (!tableExists) {
|
||||
|
@ -61,7 +61,7 @@ interface nsIFile;
|
||||
*
|
||||
* @threadsafe
|
||||
*/
|
||||
[scriptable, uuid(7b5ed315-58b3-41fd-8257-d5768943021d)]
|
||||
[scriptable, uuid(ad035628-4ffb-42ff-a256-0ed9e410b859)]
|
||||
interface mozIStorageConnection : nsISupports {
|
||||
/**
|
||||
* Closes a database connection. Callers must finalize all statements created
|
||||
@ -350,4 +350,16 @@ interface mozIStorageConnection : nsISupports {
|
||||
* @return previous registered handler.
|
||||
*/
|
||||
mozIStorageProgressHandler removeProgressHandler();
|
||||
|
||||
/**
|
||||
* Controls SQLITE_FCNTL_CHUNK_SIZE setting in sqlite. This helps avoid fragmentation
|
||||
* by growing/shrinking the database file in SQLITE_FCNTL_CHUNK_SIZE increments.
|
||||
*
|
||||
* @param aIncrement
|
||||
* The database file will grow in multiples of chunkSize.
|
||||
* @param aDatabaseName
|
||||
* Sqlite database name. "" means pass NULL for zDbName to sqlite3_file_control.
|
||||
* See http://sqlite.org/c3ref/file_control.html for more details.
|
||||
*/
|
||||
void setGrowthIncrement(in PRInt32 aIncrement, in AUTF8String aDatabaseName);
|
||||
};
|
||||
|
@ -1105,5 +1105,15 @@ Connection::RemoveProgressHandler(mozIStorageProgressHandler **_oldHandler)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Connection::SetGrowthIncrement(PRInt32 aChunkSize, const nsACString &aDatabaseName)
|
||||
{
|
||||
(void)::sqlite3_file_control(mDBConn,
|
||||
aDatabaseName.Length() ? nsPromiseFlatCString(aDatabaseName).get() : NULL,
|
||||
SQLITE_FCNTL_CHUNK_SIZE,
|
||||
&aChunkSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace storage
|
||||
} // namespace mozilla
|
||||
|
50
storage/test/unit/test_chunk_growth.js
Normal file
50
storage/test/unit/test_chunk_growth.js
Normal file
@ -0,0 +1,50 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// This file tests SQLITE_FCNTL_CHUNK_SIZE behaves as expected
|
||||
|
||||
function run_sql(d, sql) {
|
||||
var stmt = d.createStatement(sql)
|
||||
stmt.execute()
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
function new_file(name)
|
||||
{
|
||||
var file = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
file.append(name);
|
||||
return file;
|
||||
}
|
||||
|
||||
function get_size(name) {
|
||||
return new_file(name).fileSize
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
const filename = "chunked.sqlite";
|
||||
const CHUNK_SIZE = 512 * 1024;
|
||||
var d = getDatabase(new_file(filename));
|
||||
d.setGrowthIncrement(CHUNK_SIZE, "");
|
||||
run_sql(d, "CREATE TABLE bloat(data varchar)");
|
||||
|
||||
var orig_size = get_size(filename);
|
||||
/* Dump in at least 32K worth of data.
|
||||
* While writing ensure that the file size growth in chunksize set above.
|
||||
*/
|
||||
const str1024 = new Array(1024).join("T");
|
||||
for(var i = 0; i < 32; i++) {
|
||||
run_sql(d, "INSERT INTO bloat VALUES('" + str1024 + "')");
|
||||
var size = get_size(filename)
|
||||
// Must not grow in small increments.
|
||||
do_check_true(size == orig_size || size >= CHUNK_SIZE);
|
||||
}
|
||||
/* In addition to growing in chunk-size increments, the db
|
||||
* should shrink in chunk-size increments too.
|
||||
*/
|
||||
run_sql(d, "DELETE FROM bloat")
|
||||
run_sql(d, "VACUUM")
|
||||
do_check_true(get_size(filename) >= CHUNK_SIZE)
|
||||
}
|
||||
|
@ -709,6 +709,9 @@ nsNavHistory::InitDB()
|
||||
// a transaction for performances.
|
||||
mozStorageTransaction transaction(mDBConn, PR_FALSE);
|
||||
|
||||
// Grow places in 10MB increments
|
||||
mDBConn->SetGrowthIncrement(10 * 1024 * 1024, EmptyCString());
|
||||
|
||||
// Initialize the other Places services' database tables before creating our
|
||||
// statements. Some of our statements depend on these external tables, such as
|
||||
// the bookmarks or favicon tables.
|
||||
|
@ -3418,6 +3418,7 @@ nsUrlClassifierDBServiceWorker::OpenDb()
|
||||
}
|
||||
}
|
||||
|
||||
connection->SetGrowthIncrement(5 * 1024 * 1024, EmptyCString());
|
||||
rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA synchronous=OFF"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user