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  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  bool
156  storeLedger(std::shared_ptr<Ledger const> const& srcLedger) override;
157 
158  void
159  sweep() override;
160 
161 private:
162  enum class PathDesignation : uint8_t {
163  none, // No path specified
164  historical // Needs a historical path
165  };
166 
170  bool init_{false};
171 
172  // The context shared with all shard backend databases
174 
175  // Queue of background tasks to be performed
177 
178  // Shards held by this server
180 
181  // Shard indexes being imported
183 
184  // Shard index being acquired from the peer network
186 
187  // The shard store root directory
188  boost::filesystem::path dir_;
189 
190  // If new shards can be stored
191  bool canAdd_{true};
192 
193  // Complete shard indexes
195 
196  // The name associated with the backend used with the shard store
198 
199  // Maximum number of historical shards to store.
201 
202  // Contains historical shard paths
204 
205  // Storage space utilized by the shard store (in bytes)
207 
208  // Each shard stores 16384 ledgers. The earliest shard may store
209  // less if the earliest ledger sequence truncates its beginning.
210  // The value should only be altered for unit tests.
212 
213  // The earliest shard index
215 
216  // Average storage space required by a shard (in bytes)
218 
219  // The limit of final shards with open databases at any time
221 
222  // File name used to mark shards being imported from node store
223  static constexpr auto importMarker_ = "import";
224 
225  // latestShardIndex_ and secondLatestShardIndex hold the indexes
226  // of the shards most recently confirmed by the network. These
227  // values are not updated in real time and are modified only
228  // when adding shards to the database, in order to determine where
229  // pending shards will be stored on the filesystem. A value of
230  // boost::none indicates that the corresponding shard is not held
231  // by the database.
232  boost::optional<std::uint32_t> latestShardIndex_;
233  boost::optional<std::uint32_t> secondLatestShardIndex_;
234 
235  // Initialize settings from the configuration file
236  // Lock must be held
237  bool
239 
242  uint256 const& hash,
243  std::uint32_t ledgerSeq,
244  FetchReport& fetchReport) override;
245 
246  void
248  {
249  Throw<std::runtime_error>("Shard store import not supported");
250  }
251 
252  // Randomly select a shard index not stored
253  // Lock must be held
254  boost::optional<std::uint32_t>
256  std::uint32_t validLedgerSeq,
258 
259  // Queue a task to finalize a shard by verifying its databases
260  // Lock must be held
261  void
263  std::shared_ptr<Shard>& shard,
264  bool writeSQLite,
265  boost::optional<uint256> const& expectedHash);
266 
267  // Set storage and file descriptor usage stats
268  void
269  setFileStats();
270 
271  // Update status string
272  // Lock must be held
273  void
275 
276  // Returns true if the filesystem has enough storage
277  // available to hold the specified number of shards.
278  // The value of pathDesignation determines whether
279  // the shard(s) in question are historical and thus
280  // meant to be stored at a path designated for historical
281  // shards.
282  bool
284  std::uint32_t numShards,
285  PathDesignation pathDesignation,
286  std::lock_guard<std::mutex> const&) const;
287 
288  bool
290  std::shared_ptr<Shard>& shard,
291  std::shared_ptr<Ledger const> const& ledger);
292 
293  void
295 
296  // Returns the index that represents the logical
297  // partition between historical and recent shards
299  shardBoundaryIndex() const;
300 
303 
304  // Shifts the recent and second most recent (by index)
305  // shards as new shards become available on the network.
306  // Older shards are moved to a historical shard path.
307  void
309 
310  // Checks whether the shard can be stored. If
311  // the new shard can't be stored, returns
312  // boost::none. Otherwise returns an enum
313  // indicating whether the new shard should be
314  // placed in a separate directory for historical
315  // shards.
316  boost::optional<PathDesignation>
318  std::uint32_t shardIndex,
320  std::lock_guard<std::mutex> const& lock);
321 
322  boost::filesystem::path
324 
325  bool
326  checkHistoricalPaths() const;
327 };
328 
329 } // namespace NodeStore
330 } // namespace ripple
331 
332 #endif
ripple::Application
Definition: Application.h:97
ripple::NodeStore::DatabaseShardImp::earliestShardIndex_
std::uint32_t earliestShardIndex_
Definition: DatabaseShardImp.h:214
ripple::NodeStore::DatabaseShardImp::ledgersPerShard_
std::uint32_t ledgersPerShard_
Definition: DatabaseShardImp.h:211
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:247
ripple::NodeStore::DatabaseShardImp::earliestShardIndex
std::uint32_t earliestShardIndex() const override
Definition: DatabaseShardImp.h:86
ripple::NodeStore::DatabaseShardImp::mutex_
std::mutex mutex_
Definition: DatabaseShardImp.h:169
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:167
ripple::NodeStore::DatabaseShardImp::storeLedger
bool storeLedger(std::shared_ptr< Ledger const > const &srcLedger) override
Store a ledger from a different database.
Definition: DatabaseShardImp.cpp:1021
ripple::NodeStore::Database
Persistency layer for NodeObject.
Definition: Database.h:52
std::string
STL class.
std::shared_ptr< Ledger >
ripple::NodeStore::DatabaseShardImp::PathDesignation
PathDesignation
Definition: DatabaseShardImp.h:162
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:206
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:176
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:1432
ripple::NodeStore::DatabaseShardImp::secondLatestShardIndex_
boost::optional< std::uint32_t > secondLatestShardIndex_
Definition: DatabaseShardImp.h:233
std::lock_guard
STL class.
ripple::NodeStore::FetchReport
Contains information about a fetch operation.
Definition: ripple/nodestore/Scheduler.h:32
ripple::NodeStore::DatabaseShardImp::finalizeShard
void finalizeShard(std::shared_ptr< Shard > &shard, bool writeSQLite, boost::optional< uint256 > const &expectedHash)
Definition: DatabaseShardImp.cpp:1283
std::function
ripple::NodeStore::DatabaseShardImp::operator=
DatabaseShardImp & operator=(DatabaseShardImp const &)=delete
ripple::NodeStore::DatabaseShardImp::openFinalLimit_
const std::uint32_t openFinalLimit_
Definition: DatabaseShardImp.h:220
ripple::NodeStore::DatabaseShardImp::sweep
void sweep() override
Remove expired entries from the positive and negative caches.
Definition: DatabaseShardImp.cpp:1056
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:1198
ripple::NodeStore::DatabaseShardImp::avgShardFileSz_
std::uint64_t avgShardFileSz_
Definition: DatabaseShardImp.h:217
ripple::base_uint< 256 >
ripple::NodeStore::DatabaseShardImp::status_
std::string status_
Definition: DatabaseShardImp.h:194
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:1776
ripple::NodeStore::DatabaseShardImp::sufficientStorage
bool sufficientStorage(std::uint32_t numShards, PathDesignation pathDesignation, std::lock_guard< std::mutex > const &) const
Definition: DatabaseShardImp.cpp:1447
ripple::NodeStore::DatabaseShardImp::init_
bool init_
Definition: DatabaseShardImp.h:170
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::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:188
ripple::NodeStore::DatabaseShardImp::removeFailedShard
void removeFailedShard(std::shared_ptr< Shard > &shard)
Definition: DatabaseShardImp.cpp:1535
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:1809
ripple::NodeStore::DatabaseShardImp::initConfig
bool initConfig(std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1110
ripple::NodeStore::DatabaseShardImp::latestShardIndex_
boost::optional< std::uint32_t > latestShardIndex_
Definition: DatabaseShardImp.h:232
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:228
ripple::NodeStore::DatabaseShardImp::setFileStats
void setFileStats()
Definition: DatabaseShardImp.cpp:1371
ripple::NodeStore::DatabaseShardImp::acquireIndex_
std::uint32_t acquireIndex_
Definition: DatabaseShardImp.h:185
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:182
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:203
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:168
ripple::NodeStore::DatabaseShardImp::findAcquireIndex
boost::optional< std::uint32_t > findAcquireIndex(std::uint32_t validLedgerSeq, std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1217
ripple::NodeStore::DatabaseShardImp::importMarker_
static constexpr auto importMarker_
Definition: DatabaseShardImp.h:223
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:200
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:1581
ripple::NodeStore::DatabaseShardImp::relocateOutdatedShards
void relocateOutdatedShards(std::lock_guard< std::mutex > const &lock)
Definition: DatabaseShardImp.cpp:1592
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:1565
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:1502
ripple::NodeStore::DatabaseShardImp::canAdd_
bool canAdd_
Definition: DatabaseShardImp.h:191
ripple::NodeStore::DatabaseShardImp::shards_
std::unordered_map< std::uint32_t, std::shared_ptr< Shard > > shards_
Definition: DatabaseShardImp.h:179
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:1745
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:173
ripple::NodeStore::DatabaseShardImp::backendName_
std::string backendName_
Definition: DatabaseShardImp.h:197