Skip to content

Commit

Permalink
sql: Add support for measuring per-database memory usage.
Browse files Browse the repository at this point in the history
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}
  • Loading branch information
pwnall authored and Commit Bot committed Oct 14, 2020
1 parent 5a42971 commit d6e7325
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
27 changes: 27 additions & 0 deletions sql/database.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions sql/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
23 changes: 23 additions & 0 deletions sql/database_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit d6e7325

Please sign in to comment.