20#include <xrpld/app/ledger/TransactionMaster.h> 
   21#include <xrpld/app/misc/NetworkOPs.h> 
   22#include <xrpld/app/misc/SHAMapStoreImp.h> 
   23#include <xrpld/app/rdb/State.h> 
   24#include <xrpld/app/rdb/backend/SQLiteDatabase.h> 
   25#include <xrpld/core/ConfigSections.h> 
   27#include <xrpl/beast/core/CurrentThreadName.h> 
   28#include <xrpl/nodestore/Scheduler.h> 
   29#include <xrpl/nodestore/detail/DatabaseRotatingImp.h> 
   30#include <xrpl/shamap/SHAMapMissingNode.h> 
   32#include <boost/algorithm/string/predicate.hpp> 
   99        Throw<std::runtime_error>(
 
  101            "] entry in configuration file");
 
  105    if (boost::iequals(
get(section, 
"type"), 
"RocksDB"))
 
  107        if (!section.exists(
"cache_mb"))
 
  114        if (!section.exists(
"filter_bits") && (config.NODE_SIZE >= 2))
 
  115            section.set(
"filter_bits", 
"10");
 
  138        auto const minInterval = config.standalone()
 
  143            Throw<std::runtime_error>(
 
  144                "online_delete must be at least " +
 
  150            Throw<std::runtime_error>(
 
  151                "online_delete must not be less than ledger_history " 
 
  167    if (!nscfg.exists(
"cache_size"))
 
  173    if (!nscfg.exists(
"cache_age"))
 
  188            state.
writableDb = writableBackend->getName();
 
  189            state.
archiveDb = archiveBackend->getName();
 
  198            std::move(writableBackend),
 
  199            std::move(archiveBackend),
 
 
  300        LedgerIndex const validatedSeq = validatedLedger->info().seq;
 
  303            lastRotated = validatedSeq;
 
  307        bool const readyToRotate =
 
  315                << 
"rotating  validatedSeq " << validatedSeq << 
" lastRotated " 
  330                validatedLedger->stateMap().snapShot(
false)->visitNodes(
 
  335                        std::placeholders::_1));
 
  340                    << 
"Missing node while copying ledger before rotate: " 
  349                                   << 
" nodecount " << nodeCount;
 
  356            JLOG(
journal_.
debug()) << validatedSeq << 
" freshened caches";
 
  361                << validatedSeq << 
" new backend " << newBackend->getName();
 
  367            lastRotated = validatedSeq;
 
  370                std::move(newBackend),
 
  382            JLOG(
journal_.
warn()) << 
"finished rotation " << validatedSeq;
 
 
  391    boost::filesystem::path dbPath = 
get(section, 
"path");
 
  393    if (boost::filesystem::exists(dbPath))
 
  395        if (!boost::filesystem::is_directory(dbPath))
 
  398                << 
"node db path must be a directory. " << dbPath.string();
 
  399            Throw<std::runtime_error>(
"node db path must be a directory.");
 
  404        boost::filesystem::create_directories(dbPath);
 
  415            using namespace boost::filesystem;
 
  416            auto const stored{path(sPath)};
 
  417            if (stored.parent_path() == dbPath)
 
  420            sPath = (dbPath / stored.filename()).
string();
 
  431    bool writableDbExists = 
false;
 
  432    bool archiveDbExists = 
false;
 
  435    for (boost::filesystem::directory_iterator it(dbPath);
 
  436         it != boost::filesystem::directory_iterator();
 
  440            writableDbExists = 
true;
 
  442            archiveDbExists = 
true;
 
  449        (writableDbExists != archiveDbExists) ||
 
  452        boost::filesystem::path stateDbPathName =
 
  455        stateDbPathName += 
"*";
 
  458            << 
"state db error:\n" 
  459            << 
"  writableDbExists " << writableDbExists << 
" archiveDbExists " 
  460            << archiveDbExists << 
'\n' 
  461            << 
"  writableDb '" << state.
writableDb << 
"' archiveDb '" 
  463            << 
"The existing data is in a corrupted state.\n" 
  464            << 
"To resume operation, remove the files matching " 
  465            << stateDbPathName.
string() << 
" and contents of the directory " 
  466            << 
get(section, 
"path") << 
'\n' 
  467            << 
"Optionally, you can move those files to another\n" 
  468            << 
"location if you wish to analyze or back up the data.\n" 
  469            << 
"However, there is no guarantee that the data in its\n" 
  470            << 
"existing form is usable.";
 
  472        Throw<std::runtime_error>(
"state db error");
 
  476    for (boost::filesystem::path& p : pathsToDelete)
 
  477        boost::filesystem::remove_all(p);
 
 
  484    boost::filesystem::path newPath;
 
  492        boost::filesystem::path p = 
get(section, 
"path");
 
  495        newPath = boost::filesystem::unique_path(p);
 
  497    section.set(
"path", newPath.string());
 
 
  518        "ripple::SHAMapStoreImp::clearSql : nonzero delete interval");
 
  523            << 
"Begin: Look up lowest value of: " << TableName;
 
  524        auto m = getMinSeq();
 
  525        JLOG(
journal_.
trace()) << 
"End: Look up lowest value of: " << TableName;
 
  533    if (min == lastRotated)
 
  536        JLOG(
journal_.
trace()) << 
"Nothing to delete from " << TableName;
 
  540    JLOG(
journal_.
debug()) << 
"start deleting in: " << TableName << 
" from " 
  541                           << min << 
" to " << lastRotated;
 
  542    while (min < lastRotated)
 
  547            << 
" rows with LedgerSeq < " << min << 
" from: " << TableName;
 
  548        deleteBeforeSeq(min);
 
  550            << 
"End: Delete up to " << 
deleteBatch_ << 
" rows with LedgerSeq < " 
  551            << min << 
" from: " << TableName;
 
  554        if (min < lastRotated)
 
  559    JLOG(
journal_.
debug()) << 
"finished deleting from: " << TableName;
 
 
  584    JLOG(
journal_.
trace()) << 
"Begin: Clear internal ledgers up to " 
  587    JLOG(
journal_.
trace()) << 
"End: Clear internal ledgers up to " 
  596        Throw<std::runtime_error>(
"Failed to get relational database");
 
  623        "AccountTransactions",
 
 
  644                              << 
"s for node to stabilize. state: " 
  646                              << 
". age " << age.count() << 
's';
 
 
A generic endpoint for log messages.
 
Stream trace() const
Severity stream access functions.
 
virtual Config & config()=0
 
virtual NetworkOPs & getOPs()=0
 
virtual Family & getNodeFamily()=0
 
virtual LedgerMaster & getLedgerMaster()=0
 
virtual RelationalDatabase & getRelationalDatabase()=0
 
virtual TransactionMaster & getMasterTransaction()=0
 
Holds unparsed configuration information.
 
Section & section(std::string const &name)
Returns the section with the given name.
 
void legacy(std::string const §ion, std::string value)
Set a value that is not a key/value pair.
 
int getValueFor(SizedItem item, std::optional< std::size_t > node=std::nullopt) const
Retrieve the default value for the item at the specified node size.
 
virtual std::shared_ptr< FullBelowCache > getFullBelowCache()=0
Return a pointer to the Family Full Below Cache.
 
virtual std::shared_ptr< TreeNodeCache > getTreeNodeCache()=0
Return a pointer to the Family Tree Node Cache.
 
void clearLedgerCachePrior(LedgerIndex seq)
 
void clearPriorLedgers(LedgerIndex seq)
 
std::optional< LedgerIndex > minSqlSeq()
 
std::chrono::seconds getValidatedLedgerAge()
 
beast::Journal journal(std::string const &name)
 
virtual OperatingMode getOperatingMode() const =0
 
virtual std::string strOperatingMode(OperatingMode const mode, bool const admin=false) const =0
 
virtual void rotate(std::unique_ptr< NodeStore::Backend > &&newBackend, std::function< void(std::string const &writableName, std::string const &archiveName)> const &f)=0
Rotates the backends.
 
Persistency layer for NodeObject.
 
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous, bool duplicate=false)
Fetch a node object.
 
virtual std::unique_ptr< Backend > make_Backend(Section const ¶meters, std::size_t burstSize, Scheduler &scheduler, beast::Journal journal)=0
Create a backend.
 
virtual std::unique_ptr< Database > make_Database(std::size_t burstSize, Scheduler &scheduler, int readThreads, Section const &backendParameters, beast::Journal journal)=0
Construct a NodeStore database.
 
static Manager & instance()
Returns the instance of the manager singleton.
 
Scheduling for asynchronous backend activity.
 
virtual std::optional< LedgerIndex > getMinLedgerSeq()=0
getMinLedgerSeq Returns the minimum ledger sequence in the Ledgers table.
 
uint256 const & as_uint256() const
 
LedgerIndex setCanDelete(LedgerIndex canDelete)
 
void setState(SavedState const &state)
 
void setLastRotated(LedgerIndex seq)
 
LedgerIndex getCanDelete()
 
void init(BasicConfig const &config, std::string const &dbName)
 
std::condition_variable rendezvous_
 
std::condition_variable cond_
 
bool freshenCache(CacheInstance &cache)
 
void rendezvous() const override
 
NodeStore::DatabaseRotating * dbRotating_
 
std::chrono::milliseconds backOff_
 
void clearSql(LedgerIndex lastRotated, std::string const &TableName, std::function< std::optional< LedgerIndex >()> const &getMinSeq, std::function< void(LedgerIndex)> const &deleteBeforeSeq)
delete from sqlite table in batches to not lock the db excessively.
 
static constexpr auto nodeStoreName_
 
void clearPrior(LedgerIndex lastRotated)
 
std::atomic< LedgerIndex > canDelete_
 
std::unique_ptr< NodeStore::Backend > makeBackendRotating(std::string path=std::string())
 
TreeNodeCache * treeNodeCache_
 
std::uint32_t deleteInterval_
 
LedgerMaster * ledgerMaster_
 
void onLedgerClosed(std::shared_ptr< Ledger const > const &ledger) override
Called by LedgerMaster every time a ledger validates.
 
std::chrono::seconds recoveryWaitTime_
If the node is out of sync during an online_delete healthWait() call, sleep the thread for this time,...
 
std::string const dbPrefix_
 
std::uint32_t deleteBatch_
 
std::chrono::seconds ageThreshold_
 
std::atomic< LedgerIndex > minimumOnline_
 
std::uint64_t const checkHealthInterval_
 
std::unique_ptr< NodeStore::Database > makeNodeStore(int readThreads) override
 
std::string const dbName_
 
std::atomic< bool > working_
 
FullBelowCache * fullBelowCache_
 
std::optional< LedgerIndex > minimumOnline() const override
The minimum ledger to try and maintain in our database.
 
HealthResult
This is a health check for online deletion that waits until rippled is stable before returning.
 
beast::Journal const journal_
 
NodeStore::Scheduler & scheduler_
 
static std::uint32_t const minimumDeletionIntervalSA_
 
int fdRequired() const override
Returns the number of file descriptors that are needed.
 
bool copyNode(std::uint64_t &nodeCount, SHAMapTreeNode const &node)
 
std::shared_ptr< Ledger const  > newLedger_
 
HealthResult healthWait()
 
static std::uint32_t const minimumDeletionInterval_
 
void clearCaches(LedgerIndex validatedSeq)
 
SHAMapStoreImp(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
 
SHAMapHash const & getHash() const
Return the hash of this node.
 
virtual std::optional< LedgerIndex > getAccountTransactionsMinLedgerSeq()=0
getAccountTransactionsMinLedgerSeq Returns the minimum ledger sequence stored in the AccountTransacti...
 
virtual void deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)=0
deleteAccountTransactionsBeforeLedgerSeq Deletes all account transactions with a sequence number less...
 
virtual std::optional< LedgerIndex > getTransactionsMinLedgerSeq()=0
getTransactionsMinLedgerSeq Returns the minimum ledger sequence stored in the Transactions table.
 
virtual void deleteBeforeLedgerSeq(LedgerIndex ledgerSeq)=0
deleteBeforeLedgerSeq Deletes all ledgers with a sequence number less than or equal to the given ledg...
 
virtual void deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)=0
deleteTransactionsBeforeLedgerSeq Deletes all transactions with a sequence number less than or equal ...
 
Holds a collection of configuration values.
 
void set(std::string const &key, std::string const &value)
Set a key/value pair.
 
TaggedCache< uint256, Transaction > & getCache()
 
void setCurrentThreadName(std::string_view newThreadName)
Changes the name of the caller thread.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
LedgerIndex getCanDelete(soci::session &session)
getCanDelete Returns the ledger sequence which can be deleted.
 
constexpr auto megabytes(T value) noexcept
 
SavedState getSavedState(soci::session &session)
getSavedState Returns the saved state.
 
void setSavedState(soci::session &session, SavedState const &state)
setSavedState Saves the given state.
 
bool get_if_exists(Section const §ion, std::string const &name, T &v)
 
OperatingMode
Specifies the mode under which the server believes it's operating.
 
@ FULL
we have the ledger and can even validate
 
void initStateDB(soci::session &session, BasicConfig const &config, std::string const &dbName)
initStateDB Opens a session with the State database.
 
LedgerIndex setCanDelete(soci::session &session, LedgerIndex canDelete)
setCanDelete Updates the ledger sequence which can be deleted.
 
T get(Section const §ion, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
 
void setLastRotated(soci::session &session, LedgerIndex seq)
setLastRotated Updates the last rotated ledger sequence.
 
std::unique_ptr< SHAMapStore > make_SHAMapStore(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
 
static std::string nodeDatabase()