sql: Use a much more aggressive preread limit in Database::Preload().
Bug: 1010273, 1001838
Change-Id: Ic7a490640f44fe3d449462c974737f71d20c76a7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1853847
Auto-Submit: Victor Costan <[email protected]>
Commit-Queue: Staphany Park <[email protected]>
Reviewed-by: Staphany Park <[email protected]>
Cr-Commit-Position: refs/heads/master@{#705288}
diff --git a/sql/database.cc b/sql/database.cc
index 964fd61..7f7bcd2a 100644
--- a/sql/database.cc
+++ b/sql/database.cc
@@ -355,17 +355,20 @@
base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(&scoped_blocking_call);
- // The constructor and set_page_size() ensure that page_size_ is never zero.
- const int page_size = page_size_;
- DCHECK(page_size);
-
- // Use local settings if provided, otherwise use documented defaults. The
- // actual results could be fetching via PRAGMA calls.
- sqlite3_int64 preload_size = page_size * (cache_size_ ? cache_size_ : 2000);
- if (preload_size < 1)
- return;
-
- base::PreReadFile(DbPath(), /*is_executable=*/false, preload_size);
+ // Maximum number of bytes that will be prefetched from the database.
+ //
+ // This limit is very aggressive. Here are the trade-offs involved.
+ // 1) Accessing bytes that weren't preread is very expensive on
+ // performance-critical databases, so the limit must exceed the expected
+ // sizes of feature databases.
+ // 2) On some platforms (Windows 7 and, currently, macOS), base::PreReadFile()
+ // falls back to a synchronous read, and blocks until the entire file is
+ // read into memory. So, there's a tangible cost to reading data that would
+ // get evicted before base::PreReadFile() completes. This cost needs to be
+ // balanced with the benefit reading the entire database at once, and
+ // avoiding seeks on spinning disks.
+ constexpr int kPreReadSize = 128 * 1024 * 1024; // 128 MB
+ base::PreReadFile(DbPath(), /*is_executable=*/false, kPreReadSize);
}
// SQLite keeps unused pages associated with a database in a cache. It asks