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]] boost::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  void
143  store(
144  NodeObjectType type,
145  Blob&& data,
146  uint256 const& hash,
147  std::uint32_t ledgerSeq) override;
148 
149  bool
150  asyncFetch(
151  uint256 const& hash,
152  std::uint32_t ledgerSeq,
153  std::shared_ptr<NodeObject>& nodeObject) override;
154 
155  bool
156  storeLedger(std::shared_ptr<Ledger const> const& srcLedger) override;
157 
158  int
159  getDesiredAsyncReadCount(std::uint32_t ledgerSeq) override;
160 
161  float
162  getCacheHitRate() override;
163 
164  void
165  tune(int size, std::chrono::seconds age) override{};
166 
167  void
168  sweep() override;
169 
170 private:
171  enum class PathDesignation : uint8_t {
172  none, // No path specified
173  historical // Needs a historical path
174  };
175 
179  bool init_{false};
180 
181  // The context shared with all shard backend databases
183 
184  // Queue of background tasks to be performed
186 
187  // Shards held by this server
189 
190  // Shard indexes being imported
192 
193  // Shard index being acquired from the peer network
195 
196  // The shard store root directory
197  boost::filesystem::path dir_;
198 
199  // If new shards can be stored
200  bool canAdd_{true};
201 
202  // Complete shard indexes
204 
205  // The name associated with the backend used with the shard store
207 
208  // Maximum number of historical shards to store.
210 
211  // Contains historical shard paths
213 
214  // Storage space utilized by the shard store (in bytes)
216 
217  // Each shard stores 16384 ledgers. The earliest shard may store
218  // less if the earliest ledger sequence truncates its beginning.
219  // The value should only be altered for unit tests.
221 
222  // The earliest shard index
224 
225  // Average storage space required by a shard (in bytes)
227 
228  // The limit of final shards with open databases at any time
230 
231  // File name used to mark shards being imported from node store
232  static constexpr auto importMarker_ = "import";
233 
234  // latestShardIndex_ and secondLatestShardIndex hold the indexes
235  // of the shards most recently confirmed by the network. These
236  // values are not updated in real time and are modified only
237  // when adding shards to the database, in order to determine where
238  // pending shards will be stored on the filesystem. A value of
239  // boost::none indicates that the corresponding shard is not held
240  // by the database.
241  boost::optional<std::uint32_t> latestShardIndex_;
242  boost::optional<std::uint32_t> secondLatestShardIndex_;
243 
244  // Initialize settings from the configuration file
245  // Lock must be held
246  bool
248 
251  uint256 const& hash,
252  std::uint32_t ledgerSeq,
253  FetchReport& fetchReport) override;
254 
255  void
257  {
258  Throw<std::runtime_error>("Shard store import not supported");
259  }
260 
261  // Randomly select a shard index not stored
262  // Lock must be held
263  boost::optional<std::uint32_t>
265  std::uint32_t validLedgerSeq,
267 
268  // Queue a task to finalize a shard by verifying its databases
269  // Lock must be held
270  void
272  std::shared_ptr<Shard>& shard,
273  bool writeSQLite,
274  boost::optional<uint256> const& expectedHash);
275 
276  // Set storage and file descriptor usage stats
277  void
278  setFileStats();
279 
280  // Update status string
281  // Lock must be held
282  void
284 
285  // Returns true if the filesystem has enough storage
286  // available to hold the specified number of shards.
287  // The value of pathDesignation determines whether
288  // the shard(s) in question are historical and thus
289  // meant to be stored at a path designated for historical
290  // shards.
291  bool
293  std::uint32_t numShards,
294  PathDesignation pathDesignation,
295  std::lock_guard<std::mutex> const&) const;
296 
297  bool
299  std::shared_ptr<Shard>& shard,
300  std::shared_ptr<Ledger const> const& ledger);
301 
302  void
304 
305  // Returns the index that represents the logical
306  // partition between historical and recent shards
308  shardBoundaryIndex() const;
309 
312 
313  // Shifts the recent and second most recent (by index)
314  // shards as new shards become available on the network.
315  // Older shards are moved to a historical shard path.
316  void
318 
319  // Checks whether the shard can be stored. If
320  // the new shard can't be stored, returns
321  // boost::none. Otherwise returns an enum
322  // indicating whether the new shard should be
323  // placed in a separate directory for historical
324  // shards.
325  boost::optional<PathDesignation>
327  std::uint32_t shardIndex,
329  std::lock_guard<std::mutex> const& lock);
330 
331  boost::filesystem::path
333 
334  bool
335  checkHistoricalPaths() const;
336 };
337 
338 } // namespace NodeStore
339 } // namespace ripple
340 
341 #endif
ripple::Application
Definition: Application.h:97
ripple::NodeStore::DatabaseShardImp::earliestShardIndex_
std::uint32_t earliestShardIndex_
Definition: DatabaseShardImp.h:223
ripple::NodeStore::DatabaseShardImp::ledgersPerShard_
std::uint32_t ledgersPerShard_
Definition: DatabaseShardImp.h:220
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:256
ripple::NodeStore::DatabaseShardImp::earliestShardIndex
std::uint32_t earliestShardIndex() const override
Definition: DatabaseShardImp.h:86
ripple::NodeStore::DatabaseShardImp::mutex_
std::mutex mutex_
Definition: DatabaseShardImp.h:178
ripple::NodeStore::DatabaseShardImp::prepareLedger
boost::optional< std::uint32_t > prepareLedger(std::uint32_t validLedgerSeq) override
Prepare to store a new ledger in the shard being acquired.
Definition: DatabaseShardImp.cpp:228
ripple::NodeStore::DatabaseShardImp::app_
Application & app_
Definition: DatabaseShardImp.h:176
ripple::NodeStore::DatabaseShardImp::storeLedger
bool storeLedger(std::shared_ptr< Ledger const > const &srcLedger) override
Store a ledger from a different database.
Definition: DatabaseShardImp.cpp:1046
ripple::NodeStore::Database
Persistency layer for NodeObject.
Definition: Database.h:53
std::string
STL class.
std::shared_ptr< Ledger >
ripple::NodeStore::DatabaseShardImp::getDesiredAsyncReadCount
int getDesiredAsyncReadCount(std::uint32_t ledgerSeq) override
Get the maximum number of async reads the node store prefers.
Definition: DatabaseShardImp.cpp:1081
ripple::NodeStore::DatabaseShardImp::PathDesignation
PathDesignation
Definition: DatabaseShardImp.h:171
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:405
ripple::NodeStore::DatabaseShardImp::fileSz_
std::uint64_t fileSz_
Definition: DatabaseShardImp.h:215
std::vector
STL class.
ripple::NodeObjectType
NodeObjectType
The types of node objects.
Definition: NodeObject.h:32
ripple::NodeStore::DatabaseShardImp
Definition: DatabaseShardImp.h:32
std::chrono::seconds
ripple::NodeStore::DatabaseShardImp::taskQueue_
std::unique_ptr< TaskQueue > taskQueue_
Definition: DatabaseShardImp.h:185
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:616
ripple::NodeStore::DatabaseShardImp::updateStatus
void updateStatus(std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1492
ripple::NodeStore::DatabaseShardImp::secondLatestShardIndex_
boost::optional< std::uint32_t > secondLatestShardIndex_
Definition: DatabaseShardImp.h:242
std::lock_guard
STL class.
ripple::NodeStore::FetchReport
Contains information about a fetch operation.
Definition: ripple/nodestore/Scheduler.h:32
ripple::NodeStore::DatabaseShardImp::asyncFetch
bool asyncFetch(uint256 const &hash, std::uint32_t ledgerSeq, std::shared_ptr< NodeObject > &nodeObject) override
Fetch an object without waiting.
Definition: DatabaseShardImp.cpp:1021
ripple::NodeStore::DatabaseShardImp::finalizeShard
void finalizeShard(std::shared_ptr< Shard > &shard, bool writeSQLite, boost::optional< uint256 > const &expectedHash)
Definition: DatabaseShardImp.cpp:1343
ripple::NodeStore::DatabaseShardImp::tune
void tune(int size, std::chrono::seconds age) override
Set the maximum number of entries and maximum cache age for both caches.
Definition: DatabaseShardImp.h:165
std::function
ripple::NodeStore::DatabaseShardImp::operator=
DatabaseShardImp & operator=(DatabaseShardImp const &)=delete
ripple::NodeStore::DatabaseShardImp::openFinalLimit_
const std::uint32_t openFinalLimit_
Definition: DatabaseShardImp.h:229
ripple::NodeStore::DatabaseShardImp::sweep
void sweep() override
Remove expired entries from the positive and negative caches.
Definition: DatabaseShardImp.cpp:1116
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:1258
ripple::NodeStore::DatabaseShardImp::getCacheHitRate
float getCacheHitRate() override
Get the positive cache hits to total attempts ratio.
Definition: DatabaseShardImp.cpp:1099
ripple::NodeStore::DatabaseShardImp::avgShardFileSz_
std::uint64_t avgShardFileSz_
Definition: DatabaseShardImp.h:226
ripple::base_uint< 256 >
ripple::NodeStore::DatabaseShardImp::status_
std::string status_
Definition: DatabaseShardImp.h:203
ripple::NodeStore::DatabaseShardImp::getPreShards
std::string getPreShards() override
Get shard indexes being imported.
Definition: DatabaseShardImp.cpp:414
ripple::NodeStore::DatabaseShardImp::getWriteLoad
std::int32_t getWriteLoad() const override
Retrieve the estimated number of pending write operations.
Definition: DatabaseShardImp.cpp:970
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:1836
ripple::NodeStore::DatabaseShardImp::sufficientStorage
bool sufficientStorage(std::uint32_t numShards, PathDesignation pathDesignation, std::lock_guard< std::mutex > const &) const
Definition: DatabaseShardImp.cpp:1507
ripple::NodeStore::DatabaseShardImp::init_
bool init_
Definition: DatabaseShardImp.h:179
ripple::NodeStore::DatabaseShardImp::getCompleteShards
std::string getCompleteShards() override
Query which complete shards are stored.
Definition: DatabaseShardImp.cpp:678
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::ledgersPerShard
std::uint32_t ledgersPerShard() const override
Definition: DatabaseShardImp.h:80
ripple::NodeStore::DatabaseShardImp::dir_
boost::filesystem::path dir_
Definition: DatabaseShardImp.h:197
ripple::NodeStore::DatabaseShardImp::removeFailedShard
void removeFailedShard(std::shared_ptr< Shard > &shard)
Definition: DatabaseShardImp.cpp:1595
ripple::NodeStore::DatabaseShard
A collection of historical shards.
Definition: DatabaseShard.h:37
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:432
ripple::NodeStore::DatabaseShardImp::store
void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t ledgerSeq) override
Store the object.
Definition: DatabaseShardImp.cpp:987
ripple::NodeStore::DatabaseShardImp::PathDesignation::none
@ none
ripple::NodeStore::DatabaseShardImp::checkHistoricalPaths
bool checkHistoricalPaths() const
Definition: DatabaseShardImp.cpp:1869
ripple::NodeStore::DatabaseShardImp::initConfig
bool initConfig(std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1170
ripple::NodeStore::DatabaseShardImp::latestShardIndex_
boost::optional< std::uint32_t > latestShardIndex_
Definition: DatabaseShardImp.h:241
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:241
ripple::NodeStore::DatabaseShardImp::setFileStats
void setFileStats()
Definition: DatabaseShardImp.cpp:1431
ripple::NodeStore::DatabaseShardImp::acquireIndex_
std::uint32_t acquireIndex_
Definition: DatabaseShardImp.h:194
ripple::NodeStore::Scheduler
Scheduling for asynchronous backend activity.
Definition: ripple/nodestore/Scheduler.h:61
ripple::NodeStore::DatabaseShardImp::preparedIndexes_
std::set< std::uint32_t > preparedIndexes_
Definition: DatabaseShardImp.h:191
ripple::NodeStore::DatabaseShardImp::init
bool init() override
Initialize the database.
Definition: DatabaseShardImp.cpp:67
ripple::NodeStore::DatabaseShardImp::historicalPaths_
std::vector< boost::filesystem::path > historicalPaths_
Definition: DatabaseShardImp.h:212
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:177
ripple::NodeStore::DatabaseShardImp::findAcquireIndex
boost::optional< std::uint32_t > findAcquireIndex(std::uint32_t validLedgerSeq, std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1277
ripple::NodeStore::DatabaseShardImp::importMarker_
static constexpr auto importMarker_
Definition: DatabaseShardImp.h:232
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:209
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:538
ripple::NodeStore::DatabaseShardImp::numHistoricalShards
std::uint32_t numHistoricalShards(std::lock_guard< std::mutex > const &lock) const
Definition: DatabaseShardImp.cpp:1641
ripple::NodeStore::DatabaseShardImp::relocateOutdatedShards
void relocateOutdatedShards(std::lock_guard< std::mutex > const &lock)
Definition: DatabaseShardImp.cpp:1652
ripple::NodeStore::DatabaseShardImp::onChildrenStopped
void onChildrenStopped() override
Override called when all children have stopped.
Definition: DatabaseShardImp.cpp:700
ripple::NodeStore::DatabaseShardImp::shardBoundaryIndex
std::uint32_t shardBoundaryIndex() const
Definition: DatabaseShardImp.cpp:1625
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:296
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:1562
ripple::NodeStore::DatabaseShardImp::canAdd_
bool canAdd_
Definition: DatabaseShardImp.h:200
ripple::NodeStore::DatabaseShardImp::shards_
std::unordered_map< std::uint32_t, std::shared_ptr< Shard > > shards_
Definition: DatabaseShardImp.h:188
ripple::NodeStore::DatabaseShardImp::DatabaseShardImp
DatabaseShardImp()=delete
std::unique_ptr< nudb::context >
std::unordered_map
STL class.
std::set< std::uint32_t >
ripple::NodeStore::DatabaseShardImp::prepareForNewShard
boost::optional< PathDesignation > prepareForNewShard(std::uint32_t shardIndex, std::uint32_t numHistoricalShards, std::lock_guard< std::mutex > const &lock)
Definition: DatabaseShardImp.cpp:1805
ripple::NodeStore::DatabaseShardImp::onStop
void onStop() override
Override called when the stop notification is issued.
Definition: DatabaseShardImp.cpp:687
ripple::NodeStore::DatabaseShardImp::ctx_
std::unique_ptr< nudb::context > ctx_
Definition: DatabaseShardImp.h:182
ripple::NodeStore::DatabaseShardImp::backendName_
std::string backendName_
Definition: DatabaseShardImp.h:206