Skip to content

SQLite: Allow configurable sqlite database pragma variables. #5135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Sep 20, 2024
10 changes: 10 additions & 0 deletions cfg/rippled-example.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,16 @@
# This setting may not be combined with the
# "safety_level" setting.
#
# page_size Valid values: integer (typically 512, 1024, 2048, 4096)
# The default is 4096 bytes. This setting determines
# the size of a page in the database file.
#
# journal_size_limit Valid values: integer
# The default is 1582080. This setting limits
# the size of the journal file. When the limit is
# reached, older entries will be deleted.
#
#
#-------------------------------------------------------------------------------
#
# 7. Diagnostics
Expand Down
32 changes: 32 additions & 0 deletions src/test/nodestore/Database_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,38 @@ class Database_test : public TestBase
BEAST_EXPECT(found);
}
}
{
Env env(*this);
auto const s = setup_DatabaseCon(env.app().config());
if (BEAST_EXPECT(s.txPragma.size() == 4))
{
BEAST_EXPECT(s.txPragma.at(0) == "PRAGMA page_size=4096;");
BEAST_EXPECT(
s.txPragma.at(1) == "PRAGMA journal_size_limit=1582080;");
BEAST_EXPECT(
s.txPragma.at(2) == "PRAGMA max_page_count=4294967294;");
}
}
{
Env env = [&]() {
auto p = test::jtx::envconfig();
{
auto& section = p->section("sqlite");
section.set("page_size", "512");
section.set("journal_size_limit", "2582080");
}
return Env(*this, std::move(p));
}();
auto const s = setup_DatabaseCon(env.app().config());
if (BEAST_EXPECT(s.txPragma.size() == 4))
{
BEAST_EXPECT(s.txPragma.at(0) == "PRAGMA page_size=512;");
BEAST_EXPECT(
s.txPragma.at(1) == "PRAGMA journal_size_limit=2582080;");
BEAST_EXPECT(
s.txPragma.at(2) == "PRAGMA max_page_count=4294967294;");
}
}
}

//--------------------------------------------------------------------------
Expand Down
22 changes: 0 additions & 22 deletions src/xrpld/app/main/DBInit.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ inline constexpr std::uint32_t SQLITE_TUNING_CUTOFF = 10'000'000;
// Ledger database holds ledgers and ledger confirmations
inline constexpr auto LgrDBName{"ledger.db"};

inline constexpr std::array<char const*, 1> LgrDBPragma{
{"PRAGMA journal_size_limit=1582080;"}};

inline constexpr std::array<char const*, 5> LgrDBInit{
{"BEGIN TRANSACTION;",

Expand Down Expand Up @@ -72,25 +69,6 @@ inline constexpr std::array<char const*, 5> LgrDBInit{
// Transaction database holds transactions and public keys
inline constexpr auto TxDBName{"transaction.db"};

// In C++17 omitting the explicit template parameters caused
// a crash
inline constexpr std::array<char const*, 4> TxDBPragma
{
"PRAGMA page_size=4096;", "PRAGMA journal_size_limit=1582080;",
"PRAGMA max_page_count=4294967294;",

#if (ULONG_MAX > UINT_MAX) && !defined(NO_SQLITE_MMAP)
"PRAGMA mmap_size=17179869184;"
#else

// Provide an explicit `no-op` SQL statement
// in order to keep the size of the array
// constant regardless of the preprocessor
// condition evaluation
"PRAGMA sqlite_noop_statement;"
#endif
};

inline constexpr std::array<char const*, 8> TxDBInit{
{"BEGIN TRANSACTION;",

Expand Down
4 changes: 2 additions & 2 deletions src/xrpld/app/rdb/backend/detail/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ makeLedgerDBs(
{
// ledger database
auto lgr{std::make_unique<DatabaseCon>(
setup, LgrDBName, LgrDBPragma, LgrDBInit, checkpointerSetup, j)};
setup, LgrDBName, setup.lgrPragma, LgrDBInit, checkpointerSetup, j)};
lgr->getSession() << boost::str(
boost::format("PRAGMA cache_size=-%d;") %
kilobytes(config.getValueFor(SizedItem::lgrDBCache)));
Expand All @@ -81,7 +81,7 @@ makeLedgerDBs(
{
// transaction database
auto tx{std::make_unique<DatabaseCon>(
setup, TxDBName, TxDBPragma, TxDBInit, checkpointerSetup, j)};
setup, TxDBName, setup.txPragma, TxDBInit, checkpointerSetup, j)};
tx->getSession() << boost::str(
boost::format("PRAGMA cache_size=-%d;") %
kilobytes(config.getValueFor(SizedItem::txnDBCache)));
Expand Down
4 changes: 2 additions & 2 deletions src/xrpld/app/rdb/detail/Vacuum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ doVacuumDB(DatabaseCon::Setup const& setup, beast::Journal j)
return false;
}

auto txnDB =
std::make_unique<DatabaseCon>(setup, TxDBName, TxDBPragma, TxDBInit, j);
auto txnDB = std::make_unique<DatabaseCon>(
setup, TxDBName, setup.txPragma, TxDBInit, j);
auto& session = txnDB->getSession();
std::uint32_t pageSize;

Expand Down
4 changes: 2 additions & 2 deletions src/xrpld/app/rdb/detail/Wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ makeWalletDB(DatabaseCon::Setup const& setup, beast::Journal j)
{
// wallet database
return std::make_unique<DatabaseCon>(
setup, WalletDBName, std::array<char const*, 0>(), WalletDBInit, j);
setup, WalletDBName, std::array<std::string, 0>(), WalletDBInit, j);
}

std::unique_ptr<DatabaseCon>
Expand All @@ -38,7 +38,7 @@ makeTestWalletDB(
{
// wallet database
return std::make_unique<DatabaseCon>(
setup, dbname.data(), std::array<char const*, 0>(), WalletDBInit, j);
setup, dbname.data(), std::array<std::string, 0>(), WalletDBInit, j);
}

void
Expand Down
12 changes: 7 additions & 5 deletions src/xrpld/core/DatabaseCon.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ class DatabaseCon
}

static std::unique_ptr<std::vector<std::string> const> globalPragma;
std::array<std::string, 4> txPragma;
std::array<std::string, 1> lgrPragma;
};

struct CheckpointerSetup
Expand All @@ -114,7 +116,7 @@ class DatabaseCon
DatabaseCon(
Setup const& setup,
std::string const& dbName,
std::array<char const*, N> const& pragma,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
beast::Journal journal)
// Use temporary files or regular DB files?
Expand All @@ -136,7 +138,7 @@ class DatabaseCon
DatabaseCon(
Setup const& setup,
std::string const& dbName,
std::array<char const*, N> const& pragma,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
CheckpointerSetup const& checkpointerSetup,
beast::Journal journal)
Expand All @@ -149,7 +151,7 @@ class DatabaseCon
DatabaseCon(
boost::filesystem::path const& dataDir,
std::string const& dbName,
std::array<char const*, N> const& pragma,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
beast::Journal journal)
: DatabaseCon(dataDir / dbName, nullptr, pragma, initSQL, journal)
Expand All @@ -161,7 +163,7 @@ class DatabaseCon
DatabaseCon(
boost::filesystem::path const& dataDir,
std::string const& dbName,
std::array<char const*, N> const& pragma,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
CheckpointerSetup const& checkpointerSetup,
beast::Journal journal)
Expand Down Expand Up @@ -199,7 +201,7 @@ class DatabaseCon
DatabaseCon(
boost::filesystem::path const& pPath,
std::vector<std::string> const* commonPragma,
std::array<char const*, N> const& pragma,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
beast::Journal journal)
: session_(std::make_shared<soci::session>()), j_(journal)
Expand Down
36 changes: 35 additions & 1 deletion src/xrpld/core/detail/DatabaseCon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ setup_DatabaseCon(Config const& c, std::optional<beast::Journal> j)
}

{
//#synchronous Valid values : off, normal, full, extra
// #synchronous Valid values : off, normal, full, extra
if (set(synchronous, "synchronous", sqlite) &&
!safety_level.empty())
{
Expand Down Expand Up @@ -237,6 +237,40 @@ setup_DatabaseCon(Config const& c, std::optional<beast::Journal> j)
}
setup.useGlobalPragma = true;

auto setPragma =
[](std::string& pragma, std::string const& key, int64_t value) {
pragma = "PRAGMA " + key + "=" + std::to_string(value) + ";";
};

// Lgr Pragma
setPragma(setup.lgrPragma[0], "journal_size_limit", 1582080);

// TX Pragma
int64_t page_size = 4096;
int64_t journal_size_limit = 1582080;
int64_t max_page_count = 4294967294;

if (c.exists("sqlite"))
{
auto& s = c.section("sqlite");
set(page_size, "page_size", s);
set(journal_size_limit, "journal_size_limit", s);
}

setPragma(setup.txPragma[0], "page_size", page_size);
setPragma(setup.txPragma[1], "journal_size_limit", journal_size_limit);
setPragma(setup.txPragma[2], "max_page_count", max_page_count);

#if (ULONG_MAX > UINT_MAX) && !defined(NO_SQLITE_MMAP)
setup.txPragma[3] = "PRAGMA mmap_size=17179869184;";
#else
// Provide an explicit `no-op` SQL statement
// in order to keep the size of the array
// constant regardless of the preprocessor
// condition evaluation
setup.txPragma[3] = "PRAGMA sqlite_noop_statement;";
#endif

return setup;
}

Expand Down
Loading