0

sql: Add support for measuring per-database memory usage.

Change-Id: I836b9412f915cdebeff46883c535b83026ed6472
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2463873
Reviewed-by: Mark Pearson <mpearson@chromium.org>
Commit-Queue: Victor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817189}
This commit is contained in:
Victor Costan
2020-10-14 21:11:25 +00:00
committed by Commit Bot
parent 5a429714cd
commit d6e7325a8e
3 changed files with 59 additions and 0 deletions

@ -1401,6 +1401,33 @@ int Database::GetLastChangeCount() const {
return sqlite3_changes(db_);
}
int Database::GetMemoryUsage() {
if (!db_) {
DCHECK(poisoned_) << "Illegal use of Database without a db";
return 0;
}
int highwater_should_always_be_zero;
int cache_memory = 0, schema_memory = 0, statement_memory = 0;
int error =
sqlite3_db_status(db_, SQLITE_DBSTATUS_CACHE_USED, &cache_memory,
&highwater_should_always_be_zero, /*resetFlg=*/false);
DCHECK_EQ(error, SQLITE_OK);
error =
sqlite3_db_status(db_, SQLITE_DBSTATUS_SCHEMA_USED, &schema_memory,
&highwater_should_always_be_zero, /*resetFlg=*/false);
DCHECK_EQ(error, SQLITE_OK);
error =
sqlite3_db_status(db_, SQLITE_DBSTATUS_STMT_USED, &statement_memory,
&highwater_should_always_be_zero, /*resetFlg=*/false);
DCHECK_EQ(error, SQLITE_OK);
return cache_memory + schema_memory + statement_memory;
}
int Database::GetErrorCode() const {
if (!db_)
return SQLITE_ERROR;

@ -463,6 +463,15 @@ class COMPONENT_EXPORT(SQL) Database {
// is closed.
int GetLastChangeCount() const;
// Approximates the amount of memory used by SQLite for this database.
//
// This measures the memory used for the page cache (most likely the biggest
// consumer), database schema, and prepared statements.
//
// The memory used by the page cache can be recovered by calling TrimMemory(),
// which will cause SQLite to drop the page cache.
int GetMemoryUsage();
// Errors --------------------------------------------------------------------
// Returns the error code associated with the last sqlite operation.

@ -1251,6 +1251,29 @@ TEST_F(SQLDatabaseTest, GetAppropriateMmapSizeAltStatus) {
ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
}
TEST_F(SQLDatabaseTest, GetMemoryUsage) {
// Databases with mmap enabled may not follow the assumptions below.
db().Close();
db().set_mmap_disabled();
ASSERT_TRUE(db().Open(db_path()));
int initial_memory = db().GetMemoryUsage();
EXPECT_GT(initial_memory, 0)
<< "SQLite should always use some memory for a database";
ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
int post_query_memory = db().GetMemoryUsage();
EXPECT_GT(post_query_memory, initial_memory)
<< "Page cache usage should go up after executing queries";
db().TrimMemory();
int post_trim_memory = db().GetMemoryUsage();
EXPECT_GT(post_query_memory, post_trim_memory)
<< "Page cache usage should go down after calling TrimMemory()";
}
TEST_F(SQLDatabaseTest, LockingModeExclusive) {
db().Close();
db().set_exclusive_locking();