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 namespace ripple {
28 namespace NodeStore {
29 
31 {
32 public:
33  DatabaseShardImp() = delete;
34  DatabaseShardImp(DatabaseShardImp const&) = delete;
37  operator=(DatabaseShardImp const&) = delete;
39  operator=(DatabaseShardImp&&) = delete;
40 
42  Application& app,
43  Stoppable& parent,
44  std::string const& name,
45  Scheduler& scheduler,
46  int readThreads,
47  beast::Journal j);
48 
49  ~DatabaseShardImp() override;
50 
51  bool
52  init() override;
53 
54  boost::optional<std::uint32_t>
55  prepareLedger(std::uint32_t validLedgerSeq) override;
56 
57  bool
58  prepareShard(std::uint32_t shardIndex) 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 seq) override;
72 
73  void
74  setStored(std::shared_ptr<Ledger const> const& ledger) override;
75 
77  getCompleteShards() override;
78 
79  void
80  validate() override;
81 
83  ledgersPerShard() const override
84  {
85  return ledgersPerShard_;
86  }
87 
89  earliestShardIndex() const override
90  {
91  return earliestShardIndex_;
92  }
93 
95  seqToShardIndex(std::uint32_t seq) const override
96  {
97  assert(seq >= earliestLedgerSeq());
99  }
100 
102  firstLedgerSeq(std::uint32_t shardIndex) const override
103  {
104  assert(shardIndex >= earliestShardIndex_);
105  if (shardIndex <= earliestShardIndex_)
106  return earliestLedgerSeq();
107  return 1 + (shardIndex * ledgersPerShard_);
108  }
109 
111  lastLedgerSeq(std::uint32_t shardIndex) const override
112  {
113  assert(shardIndex >= earliestShardIndex_);
114  return (shardIndex + 1) * ledgersPerShard_;
115  }
116 
117  boost::filesystem::path const&
118  getRootDir() const override
119  {
120  return dir_;
121  }
122 
124  getName() const override
125  {
126  return backendName_;
127  }
128 
129  void
130  onStop() 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 seq) override;
148 
150  fetch(uint256 const& hash, std::uint32_t seq) override;
151 
152  bool
153  asyncFetch(
154  uint256 const& hash,
155  std::uint32_t seq,
156  std::shared_ptr<NodeObject>& object) override;
157 
158  bool
159  storeLedger(std::shared_ptr<Ledger const> const& srcLedger) override;
160 
161  int
163 
164  float
165  getCacheHitRate() override;
166 
167  void
168  tune(int size, std::chrono::seconds age) override{};
169 
170  void
171  sweep() override;
172 
173 private:
174  struct ShardInfo
175  {
176  enum class State {
177  none,
178  final, // Immutable, complete and validated
179  acquire, // Being acquired
180  import, // Being imported
181  finalize // Being finalized
182  };
183 
184  ShardInfo() = default;
186  : shard(std::move(shard_)), state(state_)
187  {
188  }
189 
192  };
193 
197  bool init_{false};
198 
199  // The context shared with all shard backend databases
201 
202  // Queue of background tasks to be performed
204 
205  // Shards held by this server
207 
208  // Shard index being acquired from the peer network
210 
211  // The shard store root directory
212  boost::filesystem::path dir_;
213 
214  // If new shards can be stored
215  bool canAdd_{true};
216 
217  // Complete shard indexes
219 
220  // The name associated with the backend used with the shard store
222 
223  // Maximum storage space the shard store can utilize (in bytes)
225 
226  // Storage space utilized by the shard store (in bytes)
228 
229  // Each shard stores 16384 ledgers. The earliest shard may store
230  // less if the earliest ledger sequence truncates its beginning.
231  // The value should only be altered for unit tests.
233 
234  // The earliest shard index
236 
237  // Average storage space required by a shard (in bytes)
239 
240  // File name used to mark shards being imported from node store
241  static constexpr auto importMarker_ = "import";
242 
243  // Initialize settings from the configuration file
244  // Lock must be held
245  bool
247 
249  fetchFrom(uint256 const& hash, std::uint32_t seq) override;
250 
251  void
253  {
254  Throw<std::runtime_error>("Shard store import not supported");
255  }
256 
257  // Randomly select a shard index not stored
258  // Lock must be held
259  boost::optional<std::uint32_t>
261  std::uint32_t validLedgerSeq,
263 
264  // Queue a task to finalize a shard by validating its databases
265  // Lock must be held
266  void
268  ShardInfo& shardInfo,
269  bool writeSQLite,
271 
272  // Set storage and file descriptor usage stats
273  // Lock must NOT be held
274  void
275  setFileStats();
276 
277  // Update status string
278  // Lock must be held
279  void
281 
283  getCache(std::uint32_t seq);
284 
285  // Returns available storage space
287  available() const;
288 
289  bool
291  std::shared_ptr<Shard>& shard,
292  std::shared_ptr<Ledger const> const& ledger);
293 };
294 
295 } // namespace NodeStore
296 } // namespace ripple
297 
298 #endif
ripple::NodeStore::DatabaseShardImp::ShardInfo::State
State
Definition: DatabaseShardImp.h:176
ripple::Application
Definition: Application.h:94
ripple::NodeStore::DatabaseShardImp::ledgersPerShard_
std::uint32_t ledgersPerShard_
Definition: DatabaseShardImp.h:232
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:111
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:252
ripple::NodeStore::DatabaseShardImp::earliestShardIndex
std::uint32_t earliestShardIndex() const override
Definition: DatabaseShardImp.h:89
ripple::NodeStore::DatabaseShardImp::ShardInfo::ShardInfo
ShardInfo(std::shared_ptr< Shard > shard_, State state_)
Definition: DatabaseShardImp.h:185
ripple::NodeStore::DatabaseShardImp::mutex_
std::mutex mutex_
Definition: DatabaseShardImp.h:196
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:193
ripple::NodeStore::DatabaseShardImp::app_
Application & app_
Definition: DatabaseShardImp.h:194
ripple::NodeStore::DatabaseShardImp::storeLedger
bool storeLedger(std::shared_ptr< Ledger const > const &srcLedger) override
Copies a ledger stored in a different database to this one.
Definition: DatabaseShardImp.cpp:908
ripple::NodeStore::Database
Persistency layer for NodeObject.
Definition: Database.h:53
std::string
STL class.
ripple::NodeStore::DatabaseShardImp::fetch
std::shared_ptr< NodeObject > fetch(uint256 const &hash, std::uint32_t seq) override
Fetch an object.
Definition: DatabaseShardImp.cpp:880
std::shared_ptr
STL class.
ripple::NodeStore::DatabaseShardImp::seqToShardIndex
std::uint32_t seqToShardIndex(std::uint32_t seq) const override
Calculates the shard index for a given ledger sequence.
Definition: DatabaseShardImp.h:95
ripple::NodeStore::DatabaseShardImp::ShardInfo::State::none
@ none
ripple::NodeStore::DatabaseShardImp::getName
std::string getName() const override
Retrieve the name associated with this backend.
Definition: DatabaseShardImp.h:124
std::pair
ripple::NodeStore::DatabaseShardImp::getCache
std::pair< std::shared_ptr< PCache >, std::shared_ptr< NCache > > getCache(std::uint32_t seq)
Definition: DatabaseShardImp.cpp:1310
ripple::NodeStore::DatabaseShardImp::removePreShard
void removePreShard(std::uint32_t shardIndex) override
Remove a previously prepared shard index for import.
Definition: DatabaseShardImp.cpp:306
ripple::NodeStore::DatabaseShardImp::fileSz_
std::uint64_t fileSz_
Definition: DatabaseShardImp.h:227
std::vector< unsigned char >
ripple::NodeObjectType
NodeObjectType
The types of node objects.
Definition: NodeObject.h:32
ripple::NodeStore::DatabaseShardImp
Definition: DatabaseShardImp.h:30
std::chrono::seconds
ripple::NodeStore::DatabaseShardImp::taskQueue_
std::unique_ptr< TaskQueue > taskQueue_
Definition: DatabaseShardImp.h:203
ripple::NodeStore::DatabaseShardImp::ShardInfo::state
State state
Definition: DatabaseShardImp.h:191
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:496
ripple::NodeStore::DatabaseShardImp::ShardInfo::State::acquire
@ acquire
ripple::NodeStore::DatabaseShardImp::prepareShard
bool prepareShard(std::uint32_t shardIndex) override
Prepare a shard index to be imported into the database.
Definition: DatabaseShardImp.cpp:255
std::lock_guard
STL class.
ripple::NodeStore::DatabaseShardImp::available
std::uint64_t available() const
Definition: DatabaseShardImp.cpp:1335
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:168
ripple::NodeStore::DatabaseShardImp::asyncFetch
bool asyncFetch(uint256 const &hash, std::uint32_t seq, std::shared_ptr< NodeObject > &object) override
Fetch an object without waiting.
Definition: DatabaseShardImp.cpp:889
std::function
ripple::NodeStore::DatabaseShardImp::operator=
DatabaseShardImp & operator=(DatabaseShardImp const &)=delete
ripple::NodeStore::DatabaseShardImp::sweep
void sweep() override
Remove expired entries from the positive and negative caches.
Definition: DatabaseShardImp.cpp:992
ripple::NodeStore::DatabaseShardImp::ShardInfo::State::finalize
@ finalize
ripple::NodeStore::DatabaseShardImp::getDesiredAsyncReadCount
int getDesiredAsyncReadCount(std::uint32_t seq) override
Get the maximum number of async reads the node store prefers.
Definition: DatabaseShardImp.cpp:953
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:102
ripple::NodeStore::DatabaseShardImp::getCacheHitRate
float getCacheHitRate() override
Get the positive cache hits to total attempts ratio.
Definition: DatabaseShardImp.cpp:975
ripple::NodeStore::DatabaseShardImp::avgShardFileSz_
std::uint64_t avgShardFileSz_
Definition: DatabaseShardImp.h:238
ripple::base_uint< 256 >
ripple::NodeStore::DatabaseShardImp::status_
std::string status_
Definition: DatabaseShardImp.h:218
ripple::NodeStore::DatabaseShardImp::fetchFrom
std::shared_ptr< NodeObject > fetchFrom(uint256 const &hash, std::uint32_t seq) override
Definition: DatabaseShardImp.cpp:1091
ripple::NodeStore::DatabaseShardImp::getPreShards
std::string getPreShards() override
Get shard indexes being imported.
Definition: DatabaseShardImp.cpp:319
ripple::NodeStore::DatabaseShardImp::getWriteLoad
std::int32_t getWriteLoad() const override
Retrieve the estimated number of pending write operations.
Definition: DatabaseShardImp.cpp:823
ripple::NodeStore::DatabaseShardImp::maxFileSz_
std::uint64_t maxFileSz_
Definition: DatabaseShardImp.h:224
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:200
ripple::NodeStore::DatabaseShardImp::ShardInfo::shard
std::shared_ptr< Shard > shard
Definition: DatabaseShardImp.h:190
ripple::NodeStore::DatabaseShardImp::initConfig
bool initConfig(std::lock_guard< std::mutex > &)
Definition: DatabaseShardImp.cpp:1015
ripple::NodeStore::DatabaseShardImp::init_
bool init_
Definition: DatabaseShardImp.h:197
ripple::NodeStore::DatabaseShardImp::getCompleteShards
std::string getCompleteShards() override
Query which complete shards are stored.
Definition: DatabaseShardImp.cpp:551
ripple::NodeStore::DatabaseShardImp::ledgersPerShard
std::uint32_t ledgersPerShard() const override
Definition: DatabaseShardImp.h:83
ripple::NodeStore::DatabaseShardImp::shards_
std::map< std::uint32_t, ShardInfo > shards_
Definition: DatabaseShardImp.h:206
ripple::NodeStore::DatabaseShardImp::~DatabaseShardImp
~DatabaseShardImp() override
Definition: DatabaseShardImp.cpp:60
ripple::NodeStore::DatabaseShardImp::dir_
boost::filesystem::path dir_
Definition: DatabaseShardImp.h:212
ripple::NodeStore::DatabaseShardImp::updateStatus
void updateStatus(std::lock_guard< std::mutex > &)
Definition: DatabaseShardImp.cpp:1295
ripple::NodeStore::seqToShardIndex
constexpr std::uint32_t seqToShardIndex(std::uint32_t seq, std::uint32_t ledgersPerShard=DatabaseShard::ledgersPerShardDefault)
Definition: DatabaseShard.h:190
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:338
ripple::NodeStore::DatabaseShardImp::earliestShardIndex_
const std::uint32_t earliestShardIndex_
Definition: DatabaseShardImp.h:235
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
ripple::NodeStore::Database::earliestLedgerSeq
std::uint32_t earliestLedgerSeq() const
Definition: Database.h:236
ripple::NodeStore::DatabaseShardImp::setFileStats
void setFileStats()
Definition: DatabaseShardImp.cpp:1248
ripple::NodeStore::DatabaseShardImp::acquireIndex_
std::uint32_t acquireIndex_
Definition: DatabaseShardImp.h:209
std::map
STL class.
ripple::NodeStore::Scheduler
Scheduling for asynchronous backend activity.
Definition: ripple/nodestore/Scheduler.h:57
ripple::NodeStore::DatabaseShardImp::findAcquireIndex
boost::optional< std::uint32_t > findAcquireIndex(std::uint32_t validLedgerSeq, std::lock_guard< std::mutex > &)
Definition: DatabaseShardImp.cpp:1112
ripple::NodeStore::DatabaseShardImp::ShardInfo::ShardInfo
ShardInfo()=default
ripple::NodeStore::DatabaseShardImp::init
bool init() override
Initialize the database.
Definition: DatabaseShardImp.cpp:66
ripple::NodeStore::DatabaseShardImp::store
void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t seq) override
Store the object.
Definition: DatabaseShardImp.cpp:840
ripple::NodeStore::DatabaseShardImp::getRootDir
boost::filesystem::path const & getRootDir() const override
Returns the root database directory.
Definition: DatabaseShardImp.h:118
ripple::NodeStore::DatabaseShardImp::parent_
Stoppable & parent_
Definition: DatabaseShardImp.h:195
ripple::NodeStore::DatabaseShardImp::importMarker_
static constexpr auto importMarker_
Definition: DatabaseShardImp.h:241
ripple::NodeStore::DatabaseShard::ledgersPerShardDefault
static constexpr std::uint32_t ledgersPerShardDefault
The number of ledgers in a shard.
Definition: DatabaseShard.h:186
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::NodeStore::DatabaseShardImp::fetchLedger
std::shared_ptr< Ledger > fetchLedger(uint256 const &hash, std::uint32_t seq) override
Fetch a ledger from the shard store.
Definition: DatabaseShardImp.cpp:417
std
STL namespace.
std::mutex
STL class.
ripple::NodeStore::DatabaseShardImp::validate
void validate() override
Verifies shard store data is valid.
Definition: DatabaseShardImp.cpp:560
ripple::NodeStore::DatabaseShardImp::canAdd_
bool canAdd_
Definition: DatabaseShardImp.h:215
ripple::NodeStore::DatabaseShardImp::DatabaseShardImp
DatabaseShardImp()=delete
std::unique_ptr< nudb::context >
ripple::NodeStore::DatabaseShardImp::ShardInfo
Definition: DatabaseShardImp.h:174
ripple::NodeStore::DatabaseShardImp::finalizeShard
void finalizeShard(ShardInfo &shardInfo, bool writeSQLite, std::lock_guard< std::mutex > &)
Definition: DatabaseShardImp.cpp:1172
ripple::NodeStore::DatabaseShardImp::onStop
void onStop() override
Override called when the stop notification is issued.
Definition: DatabaseShardImp.cpp:588
ripple::NodeStore::DatabaseShardImp::ctx_
std::unique_ptr< nudb::context > ctx_
Definition: DatabaseShardImp.h:200
ripple::NodeStore::DatabaseShardImp::storeLedgerInShard
bool storeLedgerInShard(std::shared_ptr< Shard > &shard, std::shared_ptr< Ledger const > const &ledger)
Definition: DatabaseShardImp.cpp:1350
ripple::NodeStore::DatabaseShardImp::backendName_
std::string backendName_
Definition: DatabaseShardImp.h:221