rippled
DatabaseShardImp.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2017 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_NODESTORE_DATABASESHARDIMP_H_INCLUDED
21 #define RIPPLE_NODESTORE_DATABASESHARDIMP_H_INCLUDED
22 
23 #include <ripple/nodestore/DatabaseShard.h>
24 #include <ripple/nodestore/impl/Shard.h>
25 #include <ripple/nodestore/impl/TaskQueue.h>
26 
27 #include <boost/asio/basic_waitable_timer.hpp>
28 
29 namespace ripple {
30 namespace NodeStore {
31 
33 {
34 public:
35  DatabaseShardImp() = delete;
36  DatabaseShardImp(DatabaseShardImp const&) = delete;
39  operator=(DatabaseShardImp const&) = delete;
41  operator=(DatabaseShardImp&&) = delete;
42 
44  Application& app,
45  Stoppable& parent,
46  std::string const& name,
47  Scheduler& scheduler,
48  int readThreads,
49  beast::Journal j);
50 
51  [[nodiscard]] bool
52  init() override;
53 
54  [[nodiscard]] std::optional<std::uint32_t>
55  prepareLedger(std::uint32_t validLedgerSeq) override;
56 
57  bool
58  prepareShards(std::vector<std::uint32_t> const& shardIndexes) override;
59 
60  void
61  removePreShard(std::uint32_t shardIndex) override;
62 
64  getPreShards() override;
65 
66  bool
67  importShard(std::uint32_t shardIndex, boost::filesystem::path const& srcDir)
68  override;
69 
71  fetchLedger(uint256 const& hash, std::uint32_t ledgerSeq) override;
72 
73  void
74  setStored(std::shared_ptr<Ledger const> const& ledger) override;
75 
77  getCompleteShards() override;
78 
80  ledgersPerShard() const override
81  {
82  return ledgersPerShard_;
83  }
84 
86  earliestShardIndex() const override
87  {
88  return earliestShardIndex_;
89  }
90 
92  seqToShardIndex(std::uint32_t ledgerSeq) const override
93  {
94  assert(ledgerSeq >= earliestLedgerSeq());
96  }
97 
99  firstLedgerSeq(std::uint32_t shardIndex) const override
100  {
101  assert(shardIndex >= earliestShardIndex_);
102  if (shardIndex <= earliestShardIndex_)
103  return earliestLedgerSeq();
104  return 1 + (shardIndex * ledgersPerShard_);
105  }
106 
108  lastLedgerSeq(std::uint32_t shardIndex) const override
109  {
110  assert(shardIndex >= earliestShardIndex_);
111  return (shardIndex + 1) * ledgersPerShard_;
112  }
113 
114  boost::filesystem::path const&
115  getRootDir() const override
116  {
117  return dir_;
118  }
119 
121  getName() const override
122  {
123  return backendName_;
124  }
125 
126  void
127  onStop() override;
128 
129  void
130  onChildrenStopped() override;
131 
136  void
137  import(Database& source) override;
138 
140  getWriteLoad() const override;
141 
142  bool
144  {
145  return seqToShardIndex(s1) == seqToShardIndex(s2);
146  }
147 
148  void
149  store(
150  NodeObjectType type,
151  Blob&& data,
152  uint256 const& hash,
153  std::uint32_t ledgerSeq) override;
154 
155  void
156  sync() override{};
157 
158  bool
159  storeLedger(std::shared_ptr<Ledger const> const& srcLedger) override;
160 
161  void
162  sweep() override;
163 
164 private:
165  enum class PathDesignation : uint8_t {
166  none, // No path specified
167  historical // Needs a historical path
168  };
169 
173  bool init_{false};
174 
175  // The context shared with all shard backend databases
177 
178  // Queue of background tasks to be performed
180 
181  // Shards held by this server
183 
184  // Shard indexes being imported
186 
187  // Shard index being acquired from the peer network
189 
190  // The shard store root directory
191  boost::filesystem::path dir_;
192 
193  // If new shards can be stored
194  bool canAdd_{true};
195 
196  // Complete shard indexes
198 
199  // The name associated with the backend used with the shard store
201 
202  // Maximum number of historical shards to store.
204 
205  // Contains historical shard paths
207 
208  // Storage space utilized by the shard store (in bytes)
210 
211  // Each shard stores 16384 ledgers. The earliest shard may store
212  // less if the earliest ledger sequence truncates its beginning.
213  // The value should only be altered for unit tests.
215 
216  // The earliest shard index
218 
219  // Average storage space required by a shard (in bytes)
221 
222  // The limit of final shards with open databases at any time
224 
225  // File name used to mark shards being imported from node store
226  static constexpr auto importMarker_ = "import";
227 
228  // latestShardIndex_ and secondLatestShardIndex hold the indexes
229  // of the shards most recently confirmed by the network. These
230  // values are not updated in real time and are modified only
231  // when adding shards to the database, in order to determine where
232  // pending shards will be stored on the filesystem. A value of
233  // std::nullopt indicates that the corresponding shard is not held
234  // by the database.
237 
238  // Initialize settings from the configuration file
239  // Lock must be held
240  bool
242 
245  uint256 const& hash,
246  std::uint32_t ledgerSeq,
247  FetchReport& fetchReport) override;
248 
249  void
251  {
252  Throw<std::runtime_error>("Shard store import not supported");
253  }
254 
255  // Randomly select a shard index not stored
256  // Lock must be held
259  std::uint32_t validLedgerSeq,
261 
262  // Queue a task to finalize a shard by verifying its databases
263  // Lock must be held
264  void
266  std::shared_ptr<Shard>& shard,
267  bool writeSQLite,
268  std::optional<uint256> const& expectedHash);
269 
270  // Set storage and file descriptor usage stats
271  void
272  setFileStats();
273 
274  // Update status string
275  // Lock must be held
276  void
278 
279  // Returns true if the filesystem has enough storage
280  // available to hold the specified number of shards.
281  // The value of pathDesignation determines whether
282  // the shard(s) in question are historical and thus
283  // meant to be stored at a path designated for historical
284  // shards.
285  bool
287  std::uint32_t numShards,
288  PathDesignation pathDesignation,
289  std::lock_guard<std::mutex> const&) const;
290 
291  bool
293  std::shared_ptr<Shard>& shard,
294  std::shared_ptr<Ledger const> const& ledger);
295 
296  void
298 
299  // Returns the index that represents the logical
300  // partition between historical and recent shards
302  shardBoundaryIndex() const;
303 
306 
307  // Shifts the recent and second most recent (by index)
308  // shards as new shards become available on the network.
309  // Older shards are moved to a historical shard path.
310  void
312 
313  // Checks whether the shard can be stored. If
314  // the new shard can't be stored, returns
315  // std::nullopt. Otherwise returns an enum
316  // indicating whether the new shard should be
317  // placed in a separate directory for historical
318  // shards.
321  std::uint32_t shardIndex,
323  std::lock_guard<std::mutex> const& lock);
324 
325  boost::filesystem::path
327 
328  bool
329  checkHistoricalPaths() const;
330 };
331 
332 } // namespace NodeStore
333 } // namespace ripple
334 
335 #endif
ripple::Application
Definition: Application.h:102
ripple::NodeStore::DatabaseShardImp::earliestShardIndex_
std::uint32_t earliestShardIndex_
Definition: DatabaseShardImp.h:217
ripple::NodeStore::DatabaseShardImp::ledgersPerShard_
std::uint32_t ledgersPerShard_
Definition: DatabaseShardImp.h:214
ripple::NodeStore::DatabaseShardImp::lastLedgerSeq
std::uint32_t lastLedgerSeq(std::uint32_t shardIndex) const override
Calculates the last ledger sequence for a given shard index.
Definition: DatabaseShardImp.h:108
ripple::NodeStore::DatabaseShardImp::for_each
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
Definition: DatabaseShardImp.h:250
ripple::NodeStore::DatabaseShardImp::earliestShardIndex
std::uint32_t earliestShardIndex() const override
Definition: DatabaseShardImp.h:86
ripple::NodeStore::DatabaseShardImp::mutex_
std::mutex mutex_
Definition: DatabaseShardImp.h:172
ripple::NodeStore::DatabaseShardImp::app_
Application & app_
Definition: DatabaseShardImp.h:170
ripple::NodeStore::DatabaseShardImp::storeLedger
bool storeLedger(std::shared_ptr< Ledger const > const &srcLedger) override
Store a ledger from a different database.
Definition: DatabaseShardImp.cpp:1022
ripple::NodeStore::Database
Persistency layer for NodeObject.
Definition: Database.h:50
std::string
STL class.
std::shared_ptr< Ledger >
ripple::NodeStore::DatabaseShardImp::PathDesignation
PathDesignation
Definition: DatabaseShardImp.h:165
ripple::NodeStore::DatabaseShardImp::getName
std::string getName() const override
Retrieve the name associated with this backend.
Definition: DatabaseShardImp.h:121
ripple::NodeStore::DatabaseShardImp::removePreShard
void removePreShard(std::uint32_t shardIndex) override
Remove a previously prepared shard index for import.
Definition: DatabaseShardImp.cpp:411
ripple::NodeStore::DatabaseShardImp::fileSz_
std::uint64_t fileSz_
Definition: DatabaseShardImp.h:209
std::vector
STL class.
ripple::NodeObjectType
NodeObjectType
The types of node objects.
Definition: NodeObject.h:32
ripple::NodeStore::DatabaseShardImp
Definition: DatabaseShardImp.h:32
ripple::NodeStore::DatabaseShardImp::taskQueue_
std::unique_ptr< TaskQueue > taskQueue_
Definition: DatabaseShardImp.h:179
ripple::NodeStore::DatabaseShardImp::setStored
void setStored(std::shared_ptr< Ledger const > const &ledger) override
Notifies the database that the given ledger has been fully acquired and stored.
Definition: DatabaseShardImp.cpp:622
ripple::NodeStore::DatabaseShardImp::updateStatus
void updateStatus(std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1433
std::lock_guard
STL class.
ripple::NodeStore::FetchReport
Contains information about a fetch operation.
Definition: ripple/nodestore/Scheduler.h:32
std::function
ripple::NodeStore::DatabaseShardImp::operator=
DatabaseShardImp & operator=(DatabaseShardImp const &)=delete
ripple::NodeStore::DatabaseShardImp::openFinalLimit_
const std::uint32_t openFinalLimit_
Definition: DatabaseShardImp.h:223
ripple::NodeStore::DatabaseShardImp::sweep
void sweep() override
Remove expired entries from the positive and negative caches.
Definition: DatabaseShardImp.cpp:1057
ripple::NodeStore::DatabaseShardImp::PathDesignation::historical
@ historical
ripple::NodeStore::DatabaseShardImp::firstLedgerSeq
std::uint32_t firstLedgerSeq(std::uint32_t shardIndex) const override
Calculates the first ledger sequence for a given shard index.
Definition: DatabaseShardImp.h:99
ripple::NodeStore::DatabaseShardImp::fetchNodeObject
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq, FetchReport &fetchReport) override
Definition: DatabaseShardImp.cpp:1199
ripple::NodeStore::DatabaseShardImp::secondLatestShardIndex_
std::optional< std::uint32_t > secondLatestShardIndex_
Definition: DatabaseShardImp.h:236
ripple::NodeStore::DatabaseShardImp::avgShardFileSz_
std::uint64_t avgShardFileSz_
Definition: DatabaseShardImp.h:220
ripple::base_uint< 256 >
ripple::NodeStore::DatabaseShardImp::status_
std::string status_
Definition: DatabaseShardImp.h:197
ripple::NodeStore::DatabaseShardImp::getPreShards
std::string getPreShards() override
Get shard indexes being imported.
Definition: DatabaseShardImp.cpp:420
ripple::NodeStore::DatabaseShardImp::getWriteLoad
std::int32_t getWriteLoad() const override
Retrieve the estimated number of pending write operations.
Definition: DatabaseShardImp.cpp:971
ripple::NodeStore::DatabaseShardImp::findAcquireIndex
std::optional< std::uint32_t > findAcquireIndex(std::uint32_t validLedgerSeq, std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1218
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:201
ripple::NodeStore::DatabaseShardImp::chooseHistoricalPath
boost::filesystem::path chooseHistoricalPath(std::lock_guard< std::mutex > const &) const
Definition: DatabaseShardImp.cpp:1777
ripple::NodeStore::DatabaseShardImp::sufficientStorage
bool sufficientStorage(std::uint32_t numShards, PathDesignation pathDesignation, std::lock_guard< std::mutex > const &) const
Definition: DatabaseShardImp.cpp:1448
ripple::NodeStore::DatabaseShardImp::init_
bool init_
Definition: DatabaseShardImp.h:173
ripple::NodeStore::DatabaseShardImp::getCompleteShards
std::string getCompleteShards() override
Query which complete shards are stored.
Definition: DatabaseShardImp.cpp:684
ripple::NodeStore::DatabaseShardImp::seqToShardIndex
std::uint32_t seqToShardIndex(std::uint32_t ledgerSeq) const override
Calculates the shard index for a given ledger sequence.
Definition: DatabaseShardImp.h:92
ripple::NodeStore::DatabaseShardImp::isSameDB
bool isSameDB(std::uint32_t s1, std::uint32_t s2) override
Definition: DatabaseShardImp.h:143
ripple::NodeStore::DatabaseShardImp::ledgersPerShard
std::uint32_t ledgersPerShard() const override
Definition: DatabaseShardImp.h:80
ripple::NodeStore::DatabaseShardImp::dir_
boost::filesystem::path dir_
Definition: DatabaseShardImp.h:191
ripple::NodeStore::DatabaseShardImp::removeFailedShard
void removeFailedShard(std::shared_ptr< Shard > &shard)
Definition: DatabaseShardImp.cpp:1536
ripple::NodeStore::DatabaseShard
A collection of historical shards.
Definition: DatabaseShard.h:36
ripple::NodeStore::DatabaseShardImp::importShard
bool importShard(std::uint32_t shardIndex, boost::filesystem::path const &srcDir) override
Import a shard into the shard database.
Definition: DatabaseShardImp.cpp:438
ripple::NodeStore::DatabaseShardImp::store
void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t ledgerSeq) override
Store the object.
Definition: DatabaseShardImp.cpp:988
ripple::NodeStore::DatabaseShardImp::PathDesignation::none
@ none
ripple::NodeStore::DatabaseShardImp::checkHistoricalPaths
bool checkHistoricalPaths() const
Definition: DatabaseShardImp.cpp:1810
ripple::NodeStore::DatabaseShardImp::initConfig
bool initConfig(std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1111
ripple::NodeStore::DatabaseShardImp::latestShardIndex_
std::optional< std::uint32_t > latestShardIndex_
Definition: DatabaseShardImp.h:235
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::NodeStore::seqToShardIndex
constexpr std::uint32_t seqToShardIndex(std::uint32_t ledgerSeq, std::uint32_t ledgersPerShard=DatabaseShard::ledgersPerShardDefault)
Definition: DatabaseShard.h:183
std::uint32_t
ripple::NodeStore::Database::earliestLedgerSeq
std::uint32_t earliestLedgerSeq() const
Definition: Database.h:232
ripple::NodeStore::DatabaseShardImp::setFileStats
void setFileStats()
Definition: DatabaseShardImp.cpp:1372
ripple::NodeStore::DatabaseShardImp::acquireIndex_
std::uint32_t acquireIndex_
Definition: DatabaseShardImp.h:188
ripple::NodeStore::Scheduler
Scheduling for asynchronous backend activity.
Definition: ripple/nodestore/Scheduler.h:60
ripple::NodeStore::DatabaseShardImp::preparedIndexes_
std::set< std::uint32_t > preparedIndexes_
Definition: DatabaseShardImp.h:185
ripple::NodeStore::DatabaseShardImp::init
bool init() override
Initialize the database.
Definition: DatabaseShardImp.cpp:73
ripple::NodeStore::DatabaseShardImp::historicalPaths_
std::vector< boost::filesystem::path > historicalPaths_
Definition: DatabaseShardImp.h:206
ripple::NodeStore::DatabaseShardImp::getRootDir
boost::filesystem::path const & getRootDir() const override
Returns the root database directory.
Definition: DatabaseShardImp.h:115
ripple::NodeStore::DatabaseShardImp::parent_
Stoppable & parent_
Definition: DatabaseShardImp.h:171
ripple::NodeStore::DatabaseShardImp::importMarker_
static constexpr auto importMarker_
Definition: DatabaseShardImp.h:226
ripple::NodeStore::DatabaseShard::ledgersPerShardDefault
static constexpr std::uint32_t ledgersPerShardDefault
The number of ledgers in a shard.
Definition: DatabaseShard.h:179
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::NodeStore::DatabaseShardImp::maxHistoricalShards_
std::uint32_t maxHistoricalShards_
Definition: DatabaseShardImp.h:203
ripple::NodeStore::DatabaseShardImp::prepareForNewShard
std::optional< PathDesignation > prepareForNewShard(std::uint32_t shardIndex, std::uint32_t numHistoricalShards, std::lock_guard< std::mutex > const &lock)
Definition: DatabaseShardImp.cpp:1746
ripple::NodeStore::DatabaseShardImp::fetchLedger
std::shared_ptr< Ledger > fetchLedger(uint256 const &hash, std::uint32_t ledgerSeq) override
Fetch a ledger from the shard store.
Definition: DatabaseShardImp.cpp:544
ripple::NodeStore::DatabaseShardImp::numHistoricalShards
std::uint32_t numHistoricalShards(std::lock_guard< std::mutex > const &lock) const
Definition: DatabaseShardImp.cpp:1582
ripple::NodeStore::DatabaseShardImp::relocateOutdatedShards
void relocateOutdatedShards(std::lock_guard< std::mutex > const &lock)
Definition: DatabaseShardImp.cpp:1593
ripple::NodeStore::DatabaseShardImp::onChildrenStopped
void onChildrenStopped() override
Override called when all children have stopped.
Definition: DatabaseShardImp.cpp:706
ripple::NodeStore::DatabaseShardImp::shardBoundaryIndex
std::uint32_t shardBoundaryIndex() const
Definition: DatabaseShardImp.cpp:1566
ripple::NodeStore::DatabaseShardImp::prepareShards
bool prepareShards(std::vector< std::uint32_t > const &shardIndexes) override
Prepare one or more shard indexes to be imported into the database.
Definition: DatabaseShardImp.cpp:302
std::optional< std::uint32_t >
std::mutex
STL class.
ripple::NodeStore::DatabaseShardImp::setStoredInShard
bool setStoredInShard(std::shared_ptr< Shard > &shard, std::shared_ptr< Ledger const > const &ledger)
Definition: DatabaseShardImp.cpp:1503
ripple::NodeStore::DatabaseShardImp::canAdd_
bool canAdd_
Definition: DatabaseShardImp.h:194
ripple::NodeStore::DatabaseShardImp::finalizeShard
void finalizeShard(std::shared_ptr< Shard > &shard, bool writeSQLite, std::optional< uint256 > const &expectedHash)
Definition: DatabaseShardImp.cpp:1284
ripple::NodeStore::DatabaseShardImp::shards_
std::unordered_map< std::uint32_t, std::shared_ptr< Shard > > shards_
Definition: DatabaseShardImp.h:182
ripple::NodeStore::DatabaseShardImp::sync
void sync() override
Definition: DatabaseShardImp.h:156
ripple::NodeStore::DatabaseShardImp::DatabaseShardImp
DatabaseShardImp()=delete
std::unique_ptr< nudb::context >
std::unordered_map
STL class.
std::set< std::uint32_t >
ripple::NodeStore::DatabaseShardImp::prepareLedger
std::optional< std::uint32_t > prepareLedger(std::uint32_t validLedgerSeq) override
Prepare to store a new ledger in the shard being acquired.
Definition: DatabaseShardImp.cpp:234
ripple::NodeStore::DatabaseShardImp::onStop
void onStop() override
Override called when the stop notification is issued.
Definition: DatabaseShardImp.cpp:693
ripple::NodeStore::DatabaseShardImp::ctx_
std::unique_ptr< nudb::context > ctx_
Definition: DatabaseShardImp.h:176
ripple::NodeStore::DatabaseShardImp::backendName_
std::string backendName_
Definition: DatabaseShardImp.h:200