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  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  Backend&
165  getBackend() override;
166 
167 private:
168  enum class PathDesignation : uint8_t {
169  none, // No path specified
170  historical // Needs a historical path
171  };
172 
176  bool init_{false};
177 
178  // The context shared with all shard backend databases
180 
181  // Queue of background tasks to be performed
183 
184  // Shards held by this server
186 
187  // Shard indexes being imported
189 
190  // Shard index being acquired from the peer network
192 
193  // The shard store root directory
194  boost::filesystem::path dir_;
195 
196  // If new shards can be stored
197  bool canAdd_{true};
198 
199  // Complete shard indexes
201 
202  // The name associated with the backend used with the shard store
204 
205  // Maximum number of historical shards to store.
207 
208  // Contains historical shard paths
210 
211  // Storage space utilized by the shard store (in bytes)
213 
214  // Each shard stores 16384 ledgers. The earliest shard may store
215  // less if the earliest ledger sequence truncates its beginning.
216  // The value should only be altered for unit tests.
218 
219  // The earliest shard index
221 
222  // Average storage space required by a shard (in bytes)
224 
225  // The limit of final shards with open databases at any time
227 
228  // File name used to mark shards being imported from node store
229  static constexpr auto importMarker_ = "import";
230 
231  // latestShardIndex_ and secondLatestShardIndex hold the indexes
232  // of the shards most recently confirmed by the network. These
233  // values are not updated in real time and are modified only
234  // when adding shards to the database, in order to determine where
235  // pending shards will be stored on the filesystem. A value of
236  // boost::none indicates that the corresponding shard is not held
237  // by the database.
238  boost::optional<std::uint32_t> latestShardIndex_;
239  boost::optional<std::uint32_t> secondLatestShardIndex_;
240 
241  // Initialize settings from the configuration file
242  // Lock must be held
243  bool
245 
248  uint256 const& hash,
249  std::uint32_t ledgerSeq,
250  FetchReport& fetchReport) override;
251 
252  void
254  {
255  Throw<std::runtime_error>("Shard store import not supported");
256  }
257 
258  // Randomly select a shard index not stored
259  // Lock must be held
260  boost::optional<std::uint32_t>
262  std::uint32_t validLedgerSeq,
264 
265  // Queue a task to finalize a shard by verifying its databases
266  // Lock must be held
267  void
269  std::shared_ptr<Shard>& shard,
270  bool writeSQLite,
271  boost::optional<uint256> const& expectedHash);
272 
273  // Set storage and file descriptor usage stats
274  void
275  setFileStats();
276 
277  // Update status string
278  // Lock must be held
279  void
281 
282  // Returns true if the filesystem has enough storage
283  // available to hold the specified number of shards.
284  // The value of pathDesignation determines whether
285  // the shard(s) in question are historical and thus
286  // meant to be stored at a path designated for historical
287  // shards.
288  bool
290  std::uint32_t numShards,
291  PathDesignation pathDesignation,
292  std::lock_guard<std::mutex> const&) const;
293 
294  bool
296  std::shared_ptr<Shard>& shard,
297  std::shared_ptr<Ledger const> const& ledger);
298 
299  void
301 
302  // Returns the index that represents the logical
303  // partition between historical and recent shards
305  shardBoundaryIndex() const;
306 
309 
310  // Shifts the recent and second most recent (by index)
311  // shards as new shards become available on the network.
312  // Older shards are moved to a historical shard path.
313  void
315 
316  // Checks whether the shard can be stored. If
317  // the new shard can't be stored, returns
318  // boost::none. Otherwise returns an enum
319  // indicating whether the new shard should be
320  // placed in a separate directory for historical
321  // shards.
322  boost::optional<PathDesignation>
324  std::uint32_t shardIndex,
326  std::lock_guard<std::mutex> const& lock);
327 
328  boost::filesystem::path
330 
331  bool
332  checkHistoricalPaths() const;
333 };
334 
335 } // namespace NodeStore
336 } // namespace ripple
337 
338 #endif
ripple::Application
Definition: Application.h:102
ripple::NodeStore::DatabaseShardImp::earliestShardIndex_
std::uint32_t earliestShardIndex_
Definition: DatabaseShardImp.h:220
ripple::NodeStore::DatabaseShardImp::ledgersPerShard_
std::uint32_t ledgersPerShard_
Definition: DatabaseShardImp.h:217
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:253
ripple::NodeStore::DatabaseShardImp::earliestShardIndex
std::uint32_t earliestShardIndex() const override
Definition: DatabaseShardImp.h:86
ripple::NodeStore::DatabaseShardImp::mutex_
std::mutex mutex_
Definition: DatabaseShardImp.h:175
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:234
ripple::NodeStore::DatabaseShardImp::app_
Application & app_
Definition: DatabaseShardImp.h:173
ripple::NodeStore::DatabaseShardImp::storeLedger
bool storeLedger(std::shared_ptr< Ledger const > const &srcLedger) override
Store a ledger from a different database.
Definition: DatabaseShardImp.cpp:1028
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:168
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:212
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:182
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:628
ripple::NodeStore::DatabaseShardImp::updateStatus
void updateStatus(std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1439
ripple::NodeStore::DatabaseShardImp::secondLatestShardIndex_
boost::optional< std::uint32_t > secondLatestShardIndex_
Definition: DatabaseShardImp.h:239
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:1290
std::function
ripple::NodeStore::DatabaseShardImp::operator=
DatabaseShardImp & operator=(DatabaseShardImp const &)=delete
ripple::NodeStore::DatabaseShardImp::openFinalLimit_
const std::uint32_t openFinalLimit_
Definition: DatabaseShardImp.h:226
ripple::NodeStore::DatabaseShardImp::sweep
void sweep() override
Remove expired entries from the positive and negative caches.
Definition: DatabaseShardImp.cpp:1063
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:1205
ripple::NodeStore::DatabaseShardImp::avgShardFileSz_
std::uint64_t avgShardFileSz_
Definition: DatabaseShardImp.h:223
ripple::base_uint< 256 >
ripple::NodeStore::DatabaseShardImp::status_
std::string status_
Definition: DatabaseShardImp.h:200
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:977
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:1783
ripple::NodeStore::DatabaseShardImp::sufficientStorage
bool sufficientStorage(std::uint32_t numShards, PathDesignation pathDesignation, std::lock_guard< std::mutex > const &) const
Definition: DatabaseShardImp.cpp:1454
ripple::NodeStore::DatabaseShardImp::init_
bool init_
Definition: DatabaseShardImp.h:176
ripple::NodeStore::DatabaseShardImp::getCompleteShards
std::string getCompleteShards() override
Query which complete shards are stored.
Definition: DatabaseShardImp.cpp:690
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:194
ripple::NodeStore::DatabaseShardImp::removeFailedShard
void removeFailedShard(std::shared_ptr< Shard > &shard)
Definition: DatabaseShardImp.cpp:1542
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: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:994
ripple::NodeStore::DatabaseShardImp::PathDesignation::none
@ none
ripple::NodeStore::DatabaseShardImp::checkHistoricalPaths
bool checkHistoricalPaths() const
Definition: DatabaseShardImp.cpp:1816
ripple::NodeStore::DatabaseShardImp::initConfig
bool initConfig(std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1117
ripple::NodeStore::DatabaseShardImp::latestShardIndex_
boost::optional< std::uint32_t > latestShardIndex_
Definition: DatabaseShardImp.h:238
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:237
ripple::NodeStore::DatabaseShardImp::setFileStats
void setFileStats()
Definition: DatabaseShardImp.cpp:1378
ripple::NodeStore::DatabaseShardImp::acquireIndex_
std::uint32_t acquireIndex_
Definition: DatabaseShardImp.h:191
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:188
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:209
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:174
ripple::NodeStore::DatabaseShardImp::findAcquireIndex
boost::optional< std::uint32_t > findAcquireIndex(std::uint32_t validLedgerSeq, std::lock_guard< std::mutex > const &)
Definition: DatabaseShardImp.cpp:1224
ripple::NodeStore::DatabaseShardImp::importMarker_
static constexpr auto importMarker_
Definition: DatabaseShardImp.h:229
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:206
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:550
ripple::NodeStore::DatabaseShardImp::numHistoricalShards
std::uint32_t numHistoricalShards(std::lock_guard< std::mutex > const &lock) const
Definition: DatabaseShardImp.cpp:1588
ripple::NodeStore::DatabaseShardImp::relocateOutdatedShards
void relocateOutdatedShards(std::lock_guard< std::mutex > const &lock)
Definition: DatabaseShardImp.cpp:1599
ripple::NodeStore::DatabaseShardImp::onChildrenStopped
void onChildrenStopped() override
Override called when all children have stopped.
Definition: DatabaseShardImp.cpp:712
ripple::NodeStore::DatabaseShardImp::shardBoundaryIndex
std::uint32_t shardBoundaryIndex() const
Definition: DatabaseShardImp.cpp:1572
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::mutex
STL class.
ripple::NodeStore::DatabaseShardImp::setStoredInShard
bool setStoredInShard(std::shared_ptr< Shard > &shard, std::shared_ptr< Ledger const > const &ledger)
Definition: DatabaseShardImp.cpp:1509
ripple::NodeStore::DatabaseShardImp::canAdd_
bool canAdd_
Definition: DatabaseShardImp.h:197
ripple::NodeStore::DatabaseShardImp::shards_
std::unordered_map< std::uint32_t, std::shared_ptr< Shard > > shards_
Definition: DatabaseShardImp.h:185
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.
ripple::NodeStore::DatabaseShardImp::getBackend
Backend & getBackend() override
Definition: DatabaseShardImp.cpp:544
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:1752
ripple::NodeStore::DatabaseShardImp::onStop
void onStop() override
Override called when the stop notification is issued.
Definition: DatabaseShardImp.cpp:699
ripple::NodeStore::DatabaseShardImp::ctx_
std::unique_ptr< nudb::context > ctx_
Definition: DatabaseShardImp.h:179
ripple::NodeStore::DatabaseShardImp::backendName_
std::string backendName_
Definition: DatabaseShardImp.h:203
ripple::NodeStore::Backend
A backend used for the NodeStore.
Definition: Backend.h:39