Index: sql/connection.cc |
diff --git a/sql/connection.cc b/sql/connection.cc |
index 825d3192f0d147790fd294620489ff685531c6b7..1213a77fa78a0912b726e2d02a508c52a9f23b3d 100644 |
--- a/sql/connection.cc |
+++ b/sql/connection.cc |
@@ -24,6 +24,7 @@ |
#include "base/synchronization/lock.h" |
#include "base/trace_event/memory_dump_manager.h" |
#include "base/trace_event/process_memory_dump.h" |
+#include "sql/meta_table.h" |
#include "sql/statement.h" |
#include "third_party/sqlite/sqlite3.h" |
@@ -458,6 +459,7 @@ bool Connection::Open(const base::FilePath& path) { |
base::HistogramBase::kUmaTargetedHistogramFlag); |
if (histogram) |
histogram->Add(sample); |
+ UMA_HISTOGRAM_COUNTS("Sqlite.SizeKB", sample); |
Scott Hess - ex-Googler
2015/12/16 23:09:08
This is sneaking in because when I went to verify
|
} |
} |
@@ -883,54 +885,43 @@ std::string Connection::CollectCorruptionInfo() { |
size_t Connection::GetAppropriateMmapSize() { |
AssertIOAllowed(); |
- // TODO(shess): Using sql::MetaTable seems indicated, but mixing |
- // sql::MetaTable and direct access seems error-prone. It might make sense to |
- // simply integrate sql::MetaTable functionality into sql::Connection. |
- |
#if defined(OS_IOS) |
// iOS SQLite does not support memory mapping. |
return 0; |
#endif |
- // If the database doesn't have a place to track progress, assume the worst. |
- // This will happen when new databases are created. |
- if (!DoesTableExist("meta")) { |
+ // How much to map if no errors are found. 50MB encompasses the 99th |
+ // percentile of Chrome databases in the wild, so this should be good. |
+ const size_t kMmapEverything = 256 * 1024 * 1024; |
+ |
+ // If the database doesn't have a place to track progress, assume the best. |
+ // This will happen when new databases are created, or if a database doesn't |
+ // use a meta table. sql::MetaTable::Init() will preload kMmapSuccess. |
+ // TODO(shess): Databases not using meta include: |
+ // DOMStorageDatabase (localstorage) |
+ // ActivityDatabase (extensions activity log) |
+ // PredictorDatabase (prefetch and autocomplete predictor data) |
+ // SyncDirectory (sync metadata storage) |
+ // For now, these all have mmap disabled to allow other databases to get the |
+ // default-enable path. sqlite-diag could be an alternative for all but |
+ // DOMStorageDatabase, which creates many small databases. |
+ // http://crbug.com/537742 |
+ if (!MetaTable::DoesTableExist(this)) { |
RecordOneEvent(EVENT_MMAP_META_MISSING); |
- return 0; |
+ return kMmapEverything; |
} |
- // Key into meta table to get status from a previous run. The value |
- // represents how much data in bytes has successfully been read from the |
- // database. |kMmapFailure| indicates that there was a read error and the |
- // database should not be memory-mapped, while |kMmapSuccess| indicates that |
- // the entire file was read at some point and can be memory-mapped without |
- // constraint. |
- const char* kMmapStatusKey = "mmap_status"; |
- static const sqlite3_int64 kMmapFailure = -2; |
- static const sqlite3_int64 kMmapSuccess = -1; |
- |
- // Start reading from 0 unless status is found in meta table. |
- sqlite3_int64 mmap_ofs = 0; |
- |
- // Retrieve the current status. It is fine for the status to be missing |
- // entirely, but any error prevents memory-mapping. |
- { |
- const char* kMmapStatusSql = "SELECT value FROM meta WHERE key = ?"; |
- Statement s(GetUniqueStatement(kMmapStatusSql)); |
- s.BindString(0, kMmapStatusKey); |
- if (s.Step()) { |
- mmap_ofs = s.ColumnInt64(0); |
- } else if (!s.Succeeded()) { |
- RecordOneEvent(EVENT_MMAP_META_FAILURE_READ); |
- return 0; |
- } |
+ int64_t mmap_ofs = 0; |
+ if (!MetaTable::GetMmapStatus(this, &mmap_ofs)) { |
+ RecordOneEvent(EVENT_MMAP_META_FAILURE_READ); |
+ return 0; |
} |
// Database read failed in the past, don't memory map. |
- if (mmap_ofs == kMmapFailure) { |
+ if (mmap_ofs == MetaTable::kMmapFailure) { |
RecordOneEvent(EVENT_MMAP_FAILED); |
return 0; |
- } else if (mmap_ofs != kMmapSuccess) { |
+ } else if (mmap_ofs != MetaTable::kMmapSuccess) { |
// Continue reading from previous offset. |
DCHECK_GE(mmap_ofs, 0); |
@@ -981,7 +972,7 @@ size_t Connection::GetAppropriateMmapSize() { |
break; |
} else { |
// TODO(shess): Consider calling OnSqliteError(). |
- mmap_ofs = kMmapFailure; |
+ mmap_ofs = MetaTable::kMmapFailure; |
break; |
} |
} |
@@ -989,20 +980,16 @@ size_t Connection::GetAppropriateMmapSize() { |
// Log these events after update to distinguish meta update failure. |
Events event; |
if (mmap_ofs >= db_size) { |
- mmap_ofs = kMmapSuccess; |
+ mmap_ofs = MetaTable::kMmapSuccess; |
event = EVENT_MMAP_SUCCESS_NEW; |
} else if (mmap_ofs > 0) { |
event = EVENT_MMAP_SUCCESS_PARTIAL; |
} else { |
- DCHECK_EQ(kMmapFailure, mmap_ofs); |
+ DCHECK_EQ(MetaTable::kMmapFailure, mmap_ofs); |
event = EVENT_MMAP_FAILED_NEW; |
} |
- const char* kMmapUpdateStatusSql = "REPLACE INTO meta VALUES (?, ?)"; |
- Statement s(GetUniqueStatement(kMmapUpdateStatusSql)); |
- s.BindString(0, kMmapStatusKey); |
- s.BindInt64(1, mmap_ofs); |
- if (!s.Run()) { |
+ if (!MetaTable::SetMmapStatus(this, mmap_ofs)) { |
RecordOneEvent(EVENT_MMAP_META_FAILURE_UPDATE); |
return 0; |
} |
@@ -1011,10 +998,10 @@ size_t Connection::GetAppropriateMmapSize() { |
} |
} |
- if (mmap_ofs == kMmapFailure) |
+ if (mmap_ofs == MetaTable::kMmapFailure) |
return 0; |
- if (mmap_ofs == kMmapSuccess) |
- return 256 * 1024 * 1024; |
+ if (mmap_ofs == MetaTable::kMmapSuccess) |
+ return kMmapEverything; |
return mmap_ofs; |
} |