Skip to content

Commit

Permalink
Disable "housekeeping" tasks for db opened with openAgain() (#2223)
Browse files Browse the repository at this point in the history
Adds a flag `C4DB_NoHousekeeping` that suppresses database
"housekeeping" tasks, and makes C4Database::openAgain() set this
flag in the database it opens.

Housekeeping tasks like expiring documents and SQLite vacuuming
only need to be done by one database connection (C4Database), but we
do them in all connections. This means CBL wastes some time and also
opens twice as many SQLite connections as it needs to (that
_backgroundDB that DatabaseImpl opens.)

It also enables a nasty deadlock condition when the replicator closes
its database(s) -- the close call happens on an actor thread, and
ends up calling Housekeeper::stop, which sends an Actor message to
the Housekeeper and blocks until it's processed. But if all actor
threads are doing this, there are no threads left to actually
run the Housekeeper. [CBSE-19205]
  • Loading branch information
snej authored Feb 6, 2025
1 parent 2140bfb commit 75a36e4
Show file tree
Hide file tree
Showing 6 changed files with 11 additions and 2 deletions.
2 changes: 1 addition & 1 deletion C/Cpp_include/c4Database.hh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct C4Database

static void shutdownLiteCore();

Retained<C4Database> openAgain() const { return openNamed(getName(), getConfiguration()); }
Retained<C4Database> openAgain() const;

virtual void close() = 0;
virtual void closeAndDeleteFile() = 0;
Expand Down
6 changes: 6 additions & 0 deletions C/c4Database.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ static C4DatabaseConfig newToOldConfig(const C4DatabaseConfig2& config2) {

/*static*/ void C4Database::shutdownLiteCore() { SQLiteDataFile::shutdown(); }

Retained<C4Database> C4Database::openAgain() const {
auto config = _config;
config.flags |= kC4DB_NoHousekeeping;
return openNamed(getName(), config);
}

C4Collection* C4Database::getDefaultCollection() const {
// Make a distinction: If the DB is open and the default collection is deleted
// then simply return null. If the DB is closed, an error should occur.
Expand Down
1 change: 1 addition & 0 deletions C/include/c4DatabaseTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef C4_OPTIONS(uint32_t, C4DatabaseFlags){
kC4DB_NonObservable = 0x40, ///< Disable database/collection observers, for slightly faster writes
kC4DB_DiskSyncFull = 0x80, ///< Flush to disk after each transaction
kC4DB_FakeVectorClock = 0x0100, ///< Use counters instead of timestamps in version vectors (TESTS ONLY)
kC4DB_NoHousekeeping = 0x0200, ///< Disable normal tasks like expiring docs and compaction
};


Expand Down
1 change: 1 addition & 0 deletions LiteCore/Database/DatabaseImpl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ namespace litecore {
options.upgradeable = (_config.flags & kC4DB_NoUpgrade) == 0;
options.diskSyncFull = (_config.flags & kC4DB_DiskSyncFull) != 0;
options.mmapDisabled = (_config.flags & kC4DB_MmapDisabled) != 0;
options.noHousekeeping = (_config.flags & kC4DB_NoHousekeeping) != 0;
options.useDocumentKeys = true;
options.encryptionAlgorithm = (EncryptionAlgorithm)_config.encryptionKey.algorithm;
if ( options.encryptionAlgorithm != kNoEncryption ) {
Expand Down
1 change: 1 addition & 0 deletions LiteCore/Storage/DataFile.hh
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ namespace litecore {
bool upgradeable : 1; ///< DB schema can be upgraded
bool diskSyncFull : 1; ///< SQLite PRAGMA synchronous
bool mmapDisabled : 1; ///< Disable MMAP in SQLite
bool noHousekeeping : 1; ///< Disable automatic maintenance
EncryptionAlgorithm encryptionAlgorithm; ///< What encryption (if any)
alloc_slice encryptionKey; ///< Encryption key, if encrypting
DatabaseTag dbTag;
Expand Down
2 changes: 1 addition & 1 deletion LiteCore/Storage/SQLiteDataFile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ namespace litecore {
_getPurgeCntStmt.reset();
_setPurgeCntStmt.reset();
if ( _sqlDb ) {
if ( options().writeable ) {
if ( options().writeable && !options().noHousekeeping ) {
withFileLock([this]() {
optimize();
vacuum(false);
Expand Down

0 comments on commit 75a36e4

Please sign in to comment.