Storage Engine API
record_store.h
Go to the documentation of this file.
1 // record_store.h
2 
31 #pragma once
32 
33 #include <boost/optional.hpp>
34 
35 #include "mongo/base/owned_pointer_vector.h"
36 #include "mongo/bson/mutable/damage_vector.h"
37 #include "mongo/db/exec/collection_scan_common.h"
38 #include "mongo/db/record_id.h"
41 
42 namespace mongo {
43 
44 class CappedCallback;
45 class Collection;
46 struct CompactOptions;
47 struct CompactStats;
48 class MAdvise;
49 class NamespaceDetails;
50 class OperationContext;
51 class RecordFetcher;
52 
53 class RecordStoreCompactAdaptor;
54 class RecordStore;
55 
56 struct ValidateResults;
57 class ValidateAdaptor;
58 
62 class DocWriter {
63 public:
64  virtual void writeDocument(char* buf) const = 0;
65  virtual size_t documentSize() const = 0;
66  virtual bool addPadding() const {
67  return true;
68  }
69 
70 protected:
71  // Can't delete through base pointer.
72  ~DocWriter() = default;
73 };
74 
79 public:
80  virtual ~UpdateNotifier() {}
81  virtual Status recordStoreGoingToUpdateInPlace(OperationContext* opCtx,
82  const RecordId& loc) = 0;
83 };
84 
88 struct Record {
89  RecordId id;
91 };
92 
93 enum ValidateCmdLevel : int {
97 };
98 
99 
142 public:
143  virtual ~RecordCursor() = default;
144 
149  virtual boost::optional<Record> next() = 0;
150 
151  //
152  // Saving and restoring state
153  //
154 
162  virtual void save() = 0;
163 
177  virtual bool restore() = 0;
178 
186  virtual void detachFromOperationContext() = 0;
187 
194  virtual void reattachToOperationContext(OperationContext* opCtx) = 0;
195 
203  virtual void invalidate(OperationContext* opCtx, const RecordId& id) {}
204 
205  //
206  // RecordFetchers
207  //
208  // Storage engines which do not support document-level locking hold locks at collection or
209  // database granularity. As an optimization, these locks can be yielded when a record needs
210  // to be fetched from secondary storage. If this method returns non-NULL, then it indicates
211  // that the query system layer should yield its locks, following the protocol defined by the
212  // RecordFetcher class, so that a potential page fault is triggered out of the lock.
213  //
214  // Storage engines which support document-level locking need not implement this.
215  //
216  // TODO see if these can be replaced by WriteConflictException.
217  //
218 
222  virtual std::unique_ptr<RecordFetcher> fetcherForNext() const {
223  return {};
224  }
225 };
226 
237 public:
244  virtual boost::optional<Record> seekExact(const RecordId& id) = 0;
245 
256  virtual void saveUnpositioned() {
257  save();
258  }
259 
263  virtual std::unique_ptr<RecordFetcher> fetcherForId(const RecordId& id) const {
264  return {};
265  }
266 };
267 
282 class RecordStore {
283  MONGO_DISALLOW_COPYING(RecordStore);
284 
285 public:
286  RecordStore(StringData ns) : _ns(ns.toString()) {}
287 
288  virtual ~RecordStore() {}
289 
290  // META
291 
292  // name of the RecordStore implementation
293  virtual const char* name() const = 0;
294 
295  virtual const std::string& ns() const {
296  return _ns;
297  }
298 
303  virtual long long dataSize(OperationContext* opCtx) const = 0;
304 
309  virtual long long numRecords(OperationContext* opCtx) const = 0;
310 
311  virtual bool isCapped() const = 0;
312 
314  MONGO_UNREACHABLE;
315  }
316 
322  virtual int64_t storageSize(OperationContext* opCtx,
323  BSONObjBuilder* extraInfo = NULL,
324  int infoLevel = 0) const = 0;
325 
326  // CRUD related
327 
337  virtual RecordData dataFor(OperationContext* opCtx, const RecordId& loc) const {
339  invariant(findRecord(opCtx, loc, &data));
340  return data;
341  }
342 
357  virtual bool findRecord(OperationContext* opCtx, const RecordId& loc, RecordData* out) const {
358  auto cursor = getCursor(opCtx);
359  auto record = cursor->seekExact(loc);
360  if (!record)
361  return false;
362 
363  record->data.makeOwned(); // Unowned data expires when cursor goes out of scope.
364  *out = std::move(record->data);
365  return true;
366  }
367 
368  virtual void deleteRecord(OperationContext* opCtx, const RecordId& dl) = 0;
369 
370  virtual StatusWith<RecordId> insertRecord(OperationContext* opCtx,
371  const char* data,
372  int len,
373  Timestamp timestamp,
374  bool enforceQuota) = 0;
375 
376  virtual Status insertRecords(OperationContext* opCtx,
377  std::vector<Record>* records,
378  std::vector<Timestamp>* timestamps,
379  bool enforceQuota) {
380  int index = 0;
381  for (auto& record : *records) {
382  StatusWith<RecordId> res = insertRecord(opCtx,
383  record.data.data(),
384  record.data.size(),
385  (*timestamps)[index++],
386  enforceQuota);
387  if (!res.isOK())
388  return res.getStatus();
389 
390  record.id = res.getValue();
391  }
392  return Status::OK();
393  }
394 
404  virtual Status insertRecordsWithDocWriter(OperationContext* opCtx,
405  const DocWriter* const* docs,
406  const Timestamp* timestamps,
407  size_t nDocs,
408  RecordId* idsOut = nullptr) = 0;
409 
414  const DocWriter* doc,
415  Timestamp timestamp) {
416  RecordId out;
417  Status status = insertRecordsWithDocWriter(opCtx, &doc, &timestamp, 1, &out);
418  if (!status.isOK())
419  return status;
420  return out;
421  }
422 
435  virtual Status updateRecord(OperationContext* opCtx,
436  const RecordId& oldLocation,
437  const char* data,
438  int len,
439  bool enforceQuota,
440  UpdateNotifier* notifier) = 0;
441 
449  virtual bool updateWithDamagesSupported() const = 0;
450 
459  virtual StatusWith<RecordData> updateWithDamages(OperationContext* opCtx,
460  const RecordId& loc,
461  const RecordData& oldRec,
462  const char* damageSource,
463  const mutablebson::DamageVector& damages) = 0;
464 
473  virtual std::unique_ptr<SeekableRecordCursor> getCursor(OperationContext* opCtx,
474  bool forward = true) const = 0;
475 
481  virtual std::unique_ptr<RecordCursor> getCursorForRepair(OperationContext* opCtx) const {
482  return {};
483  }
484 
496  virtual std::unique_ptr<RecordCursor> getRandomCursor(OperationContext* opCtx) const {
497  return {};
498  }
499 
504  virtual std::vector<std::unique_ptr<RecordCursor>> getManyCursors(
505  OperationContext* opCtx) const {
506  std::vector<std::unique_ptr<RecordCursor>> out(1);
507  out[0] = getCursor(opCtx);
508  return out;
509  }
510 
511  // higher level
512 
513 
517  virtual Status truncate(OperationContext* opCtx) = 0;
518 
525  virtual void cappedTruncateAfter(OperationContext* opCtx, RecordId end, bool inclusive) = 0;
526 
532  virtual bool compactSupported() const {
533  return false;
534  }
535 
541  virtual bool compactsInPlace() const {
542  MONGO_UNREACHABLE;
543  }
544 
551  virtual Status compact(OperationContext* opCtx,
552  RecordStoreCompactAdaptor* adaptor,
553  const CompactOptions* options,
554  CompactStats* stats) {
555  MONGO_UNREACHABLE;
556  }
557 
567  virtual bool isInRecordIdOrder() const {
568  return false;
569  }
570 
576  virtual Status validate(OperationContext* opCtx,
577  ValidateCmdLevel level,
578  ValidateAdaptor* adaptor,
579  ValidateResults* results,
580  BSONObjBuilder* output) = 0;
581 
586  virtual void appendCustomStats(OperationContext* opCtx,
587  BSONObjBuilder* result,
588  double scale) const = 0;
589 
599  virtual Status touch(OperationContext* opCtx, BSONObjBuilder* output) const {
600  return Status(ErrorCodes::CommandNotSupported,
601  "this storage engine does not support touch");
602  }
603 
611  virtual boost::optional<RecordId> oplogStartHack(OperationContext* opCtx,
612  const RecordId& startingPosition) const {
613  return boost::none;
614  }
615 
629  virtual Status oplogDiskLocRegister(OperationContext* opCtx,
630  const Timestamp& opTime,
631  bool orderedCommit) {
632  return Status::OK();
633  }
634 
642  virtual void waitForAllEarlierOplogWritesToBeVisible(OperationContext* opCtx) const = 0;
643 
647  virtual void updateStatsAfterRepair(OperationContext* opCtx,
648  long long numRecords,
649  long long dataSize) = 0;
650 
654  virtual Status updateCappedSize(OperationContext* opCtx, long long cappedSize) {
655  return Status(ErrorCodes::CommandNotSupported,
656  "this storage engine does not support updateCappedSize");
657  }
658 
659 protected:
660  std::string _ns;
661 };
662 
664 public:
666  virtual bool isDataValid(const RecordData& recData) = 0;
667  virtual size_t dataSize(const RecordData& recData) = 0;
668  virtual void inserted(const RecordData& recData, const RecordId& newLocation) = 0;
669 };
670 
673  valid = true;
674  }
675  bool valid;
676  std::vector<std::string> errors;
677  std::vector<std::string> warnings;
678 };
679 
686 public:
687  virtual ~ValidateAdaptor() {}
688 
689  virtual Status validate(const RecordId& recordId,
690  const RecordData& recordData,
691  size_t* dataSize) = 0;
692 };
693 }
Definition: record_store.h:663
AtomicLockStats stats
Definition: lock_state.cpp:92
ValidateCmdLevel
Definition: record_store.h:93
Definition: record_store.h:94
virtual Status insertRecords(OperationContext *opCtx, std::vector< Record > *records, std::vector< Timestamp > *timestamps, bool enforceQuota)
Definition: record_store.h:376
virtual std::vector< std::unique_ptr< RecordCursor > > getManyCursors(OperationContext *opCtx) const
Returns many RecordCursors that partition the RecordStore into many disjoint sets.
Definition: record_store.h:504
Definition: record_store.h:671
Collection *const const NamespaceString & ns
Definition: collection_info_cache_impl.cpp:53
virtual Status oplogDiskLocRegister(OperationContext *opCtx, const Timestamp &opTime, bool orderedCommit)
When we write to an oplog, we call this so that if the storage engine supports doc locking...
Definition: record_store.h:629
virtual std::unique_ptr< RecordFetcher > fetcherForNext() const
Returns a RecordFetcher if needed for a call to next() or none if unneeded.
Definition: record_store.h:222
Copyright (C) 2014 MongoDB Inc.
Definition: bson_collection_catalog_entry.cpp:38
std::vector< std::string > errors
Definition: record_store.h:676
virtual bool compactsInPlace() const
Does compact() leave RecordIds alone or can they change.
Definition: record_store.h:541
virtual std::unique_ptr< RecordCursor > getRandomCursor(OperationContext *opCtx) const
Constructs a cursor over a record store that returns documents in a randomized order, and allows storage engines to provide a more efficient way of random sampling of a record store than MongoDB&#39;s default sampling methods, which is used when this method returns {}.
Definition: record_store.h:496
OperationContext Database StringData BSONObj CollectionOptions::ParseKind bool const BSONObj &idIndex Status
Definition: database_impl.cpp:956
A replacement for the Record class.
Definition: record_data.h:43
StatusWith< RecordId > insertRecordWithDocWriter(OperationContext *opCtx, const DocWriter *doc, Timestamp timestamp)
A thin wrapper around insertRecordsWithDocWriter() to simplify handling of single DocWriters...
Definition: record_store.h:413
Definition: record_store.h:96
This is so when a RecordStore is validating all records it can call back to someone to check if a rec...
Definition: record_store.h:685
Definition: record_store.h:78
virtual bool compactSupported() const
does this RecordStore support the compact operation?
Definition: record_store.h:532
bool inclusive
Definition: btree_interface.cpp:335
virtual ~RecordStore()
Definition: record_store.h:288
virtual bool isInRecordIdOrder() const
Does the RecordStore cursor retrieve its document in RecordId Order?
Definition: record_store.h:567
Definition: collection.h:77
Allows inserting a Record "in-place" without creating a copy ahead of time.
Definition: record_store.h:62
std::shared_ptr< void > data
Definition: ephemeral_for_test_record_store_test.cpp:74
The data items stored in a RecordStore.
Definition: record_store.h:88
virtual void invalidate(OperationContext *opCtx, const RecordId &id)
Inform the cursor that this id is being invalidated.
Definition: record_store.h:203
Status status
Definition: database_impl.cpp:975
Definition: index_key_validate.h:40
virtual std::unique_ptr< RecordFetcher > fetcherForId(const RecordId &id) const
Returns a RecordFetcher if needed to fetch the provided Record or none if unneeded.
Definition: record_store.h:263
virtual void saveUnpositioned()
Prepares for state changes in underlying data without necessarily saving the current state...
Definition: record_store.h:256
RecordId id
Definition: record_store.h:89
Retrieves Records from a RecordStore.
Definition: record_store.h:141
virtual RecordData dataFor(OperationContext *opCtx, const RecordId &loc) const
Get the RecordData at loc, which must exist.
Definition: record_store.h:337
An abstraction used for storing documents in a collection or entries in an index. ...
Definition: record_store.h:282
When a capped collection is modified (delete/insert/etc) then certain notifications need to be made...
Definition: capped_callback.h:44
virtual const std::string & ns() const
Definition: record_store.h:295
virtual bool findRecord(OperationContext *opCtx, const RecordId &loc, RecordData *out) const
Definition: record_store.h:357
virtual ~ValidateAdaptor()
Definition: record_store.h:687
virtual boost::optional< RecordId > oplogStartHack(OperationContext *opCtx, const RecordId &startingPosition) const
Return the RecordId of an oplog entry as close to startingPosition as possible without being higher...
Definition: record_store.h:611
virtual ~RecordStoreCompactAdaptor()
Definition: record_store.h:665
virtual size_t documentSize() const =0
virtual void writeDocument(char *buf) const =0
virtual std::unique_ptr< RecordCursor > getCursorForRepair(OperationContext *opCtx) const
Constructs a cursor over a potentially corrupted store, which can be used to salvage damaged records...
Definition: record_store.h:481
NamespaceString _ns
Definition: wiredtiger_record_store_mongod.cpp:128
Adds explicit seeking of records.
Definition: record_store.h:236
OperationContext Database StringData BSONObj options
Definition: database_impl.cpp:949
virtual Status compact(OperationContext *opCtx, RecordStoreCompactAdaptor *adaptor, const CompactOptions *options, CompactStats *stats)
Attempt to reduce the storage space used by this RecordStore.
Definition: record_store.h:551
std::vector< std::string > warnings
Definition: record_store.h:677
Definition: collection.h:97
virtual Status touch(OperationContext *opCtx, BSONObjBuilder *output) const
Load all data into cache.
Definition: record_store.h:599
bool valid
Definition: record_store.h:675
RecordData data
Definition: record_store.h:90
virtual bool addPadding() const
Definition: record_store.h:66
virtual void setCappedCallback(CappedCallback *)
Definition: record_store.h:313
Database *const OperationContext *const const StringData name
Definition: database_impl.cpp:82
virtual Status updateCappedSize(OperationContext *opCtx, long long cappedSize)
used to support online change oplog size.
Definition: record_store.h:654
Collection *const OperationContext *const opCtx
Definition: collection_impl.cpp:80
RecordStore(StringData ns)
Definition: record_store.h:286
~DocWriter()=default
Definition: record_store.h:95
std::string _ns
Definition: record_store.h:660
ValidateResults()
Definition: record_store.h:672
virtual ~UpdateNotifier()
Definition: record_store.h:80