Storage Engine API
record_store_v1_base.h
Go to the documentation of this file.
1 
29 #pragma once
30 
31 #include "mongo/stdx/unordered_set.h"
32 #include "mongo/util/concurrency/spin_lock.h"
33 
36 
37 namespace mongo {
38 
39 class DeletedRecord;
40 class ExtentManager;
41 class MmapV1RecordHeader;
42 class OperationContext;
43 
44 struct Extent;
45 
47 public:
49 
50  virtual const DiskLoc& capExtent() const = 0;
51  virtual void setCapExtent(OperationContext* opCtx, const DiskLoc& loc) = 0;
52 
53  virtual const DiskLoc& capFirstNewRecord() const = 0;
54  virtual void setCapFirstNewRecord(OperationContext* opCtx, const DiskLoc& loc) = 0;
55 
56  bool capLooped() const {
57  return capFirstNewRecord().isValid();
58  }
59 
60  virtual long long dataSize() const = 0;
61  virtual long long numRecords() const = 0;
62 
63  virtual void incrementStats(OperationContext* opCtx,
64  long long dataSizeIncrement,
65  long long numRecordsIncrement) = 0;
66 
67  virtual void setStats(OperationContext* opCtx, long long dataSize, long long numRecords) = 0;
68 
69  virtual DiskLoc deletedListEntry(int bucket) const = 0;
70  virtual void setDeletedListEntry(OperationContext* opCtx, int bucket, const DiskLoc& loc) = 0;
71 
72  virtual DiskLoc deletedListLegacyGrabBag() const = 0;
73  virtual void setDeletedListLegacyGrabBag(OperationContext* opCtx, const DiskLoc& loc) = 0;
74 
75  virtual void orphanDeletedList(OperationContext* opCtx) = 0;
76 
77  virtual const DiskLoc& firstExtent(OperationContext* opCtx) const = 0;
78  virtual void setFirstExtent(OperationContext* opCtx, const DiskLoc& loc) = 0;
79 
80  virtual const DiskLoc& lastExtent(OperationContext* opCtx) const = 0;
81  virtual void setLastExtent(OperationContext* opCtx, const DiskLoc& loc) = 0;
82 
83  virtual bool isCapped() const = 0;
84 
85  virtual bool isUserFlagSet(int flag) const = 0;
86  virtual int userFlags() const = 0;
87  virtual bool setUserFlag(OperationContext* opCtx, int flag) = 0;
88  virtual bool clearUserFlag(OperationContext* opCtx, int flag) = 0;
89  virtual bool replaceUserFlags(OperationContext* opCtx, int flags) = 0;
90 
91  virtual int lastExtentSize(OperationContext* opCtx) const = 0;
92  virtual void setLastExtentSize(OperationContext* opCtx, int newMax) = 0;
93 
94  virtual long long maxCappedDocs() const = 0;
95 };
96 
105 public:
110  struct SavedCursor {
111  SavedCursor() : _registry(NULL) {}
112  virtual ~SavedCursor() {
113  if (_registry)
114  _registry->unregisterCursor(this);
115  }
117  BSONObj key;
119 
120  private:
121  friend class SavedCursorRegistry;
122  // Non-null iff registered. Accessed by owner or writer with MODE_X collection lock
124  };
125 
127 
131  void registerCursor(SavedCursor* cursor);
132 
137  bool unregisterCursor(SavedCursor* cursor);
138 
143  void invalidateCursorsForBucket(DiskLoc bucket);
144 
145 private:
146  SpinLock _mutex;
147  typedef stdx::unordered_set<SavedCursor*>
148  SavedCursorSet; // SavedCursor pointers not owned here
150 };
151 
153 public:
154  static const int Buckets = 26;
155  static const int MaxAllowedAllocation = 16 * 1024 * 1024 + 512 * 1024;
156 
157  static const int bucketSizes[];
158 
159  // ------------
160 
161  class IntraExtentIterator;
162 
167  RecordStoreV1Base(StringData ns,
169  ExtentManager* em,
170  bool isSystemIndexes);
171 
172  virtual ~RecordStoreV1Base();
173 
174  virtual long long dataSize(OperationContext* opCtx) const {
175  return _details->dataSize();
176  }
177  virtual long long numRecords(OperationContext* opCtx) const {
178  return _details->numRecords();
179  }
180 
181  virtual int64_t storageSize(OperationContext* opCtx,
182  BSONObjBuilder* extraInfo = NULL,
183  int level = 0) const;
184 
185  virtual RecordData dataFor(OperationContext* opCtx, const RecordId& loc) const;
186 
187  virtual bool findRecord(OperationContext* opCtx, const RecordId& loc, RecordData* rd) const;
188 
189  void deleteRecord(OperationContext* opCtx, const RecordId& dl);
190 
191  StatusWith<RecordId> insertRecord(
192  OperationContext* opCtx, const char* data, int len, Timestamp, bool enforceQuota);
193 
194  Status insertRecordsWithDocWriter(OperationContext* opCtx,
195  const DocWriter* const* docs,
196  const Timestamp*,
197  size_t nDocs,
198  RecordId* idsOut) final;
199 
200  virtual Status updateRecord(OperationContext* opCtx,
201  const RecordId& oldLocation,
202  const char* data,
203  int len,
204  bool enforceQuota,
205  UpdateNotifier* notifier);
206 
207  virtual bool updateWithDamagesSupported() const;
208 
209  virtual StatusWith<RecordData> updateWithDamages(OperationContext* opCtx,
210  const RecordId& loc,
211  const RecordData& oldRec,
212  const char* damageSource,
213  const mutablebson::DamageVector& damages);
214 
215  virtual std::unique_ptr<RecordCursor> getCursorForRepair(OperationContext* opCtx) const;
216 
217  void increaseStorageSize(OperationContext* opCtx, int size, bool enforceQuota);
218 
219  virtual Status validate(OperationContext* opCtx,
220  ValidateCmdLevel level,
221  ValidateAdaptor* adaptor,
222  ValidateResults* results,
223  BSONObjBuilder* output);
224 
225  virtual void appendCustomStats(OperationContext* opCtx,
226  BSONObjBuilder* result,
227  double scale) const;
228 
229  virtual Status touch(OperationContext* opCtx, BSONObjBuilder* output) const;
230 
232  return _details.get();
233  }
234 
235  // This keeps track of cursors saved during yielding, for invalidation purposes.
237 
238  DiskLoc getExtentLocForRecord(OperationContext* opCtx, const DiskLoc& loc) const;
239 
240  DiskLoc getNextRecord(OperationContext* opCtx, const DiskLoc& loc) const;
241  DiskLoc getPrevRecord(OperationContext* opCtx, const DiskLoc& loc) const;
242 
243  DiskLoc getNextRecordInExtent(OperationContext* opCtx, const DiskLoc& loc) const;
244  DiskLoc getPrevRecordInExtent(OperationContext* opCtx, const DiskLoc& loc) const;
245 
249  static int quantizeAllocationSpace(int minSize);
250 
251  static bool isQuantized(int recordSize);
252 
253  /* return which "deleted bucket" for this size object */
254  static int bucket(int size);
255 
256  void waitForAllEarlierOplogWritesToBeVisible(OperationContext* opCtx) const override {}
257 
258  virtual void updateStatsAfterRepair(OperationContext* opCtx,
259  long long numRecords,
260  long long dataSize) {
261  MONGO_UNREACHABLE; // MMAPv1 has its own repair which doesn't call this.
262  }
263 
264 protected:
265  virtual MmapV1RecordHeader* recordFor(const DiskLoc& loc) const;
266 
267  const DeletedRecord* deletedRecordFor(const DiskLoc& loc) const;
268 
269  virtual bool isCapped() const = 0;
270 
271  virtual bool shouldPadInserts() const = 0;
272 
273  virtual StatusWith<DiskLoc> allocRecord(OperationContext* opCtx,
274  int lengthWithHeaders,
275  bool enforceQuota) = 0;
276 
277  // TODO: document, remove, what have you
278  virtual void addDeletedRec(OperationContext* opCtx, const DiskLoc& dloc) = 0;
279 
280  // TODO: another sad one
281  virtual DeletedRecord* drec(const DiskLoc& loc) const;
282 
283  // just a wrapper for _extentManager->getExtent( loc );
284  Extent* _getExtent(OperationContext* opCtx, const DiskLoc& loc) const;
285 
286  DiskLoc _getExtentLocForRecord(OperationContext* opCtx, const DiskLoc& loc) const;
287 
288  DiskLoc _getNextRecord(OperationContext* opCtx, const DiskLoc& loc) const;
289  DiskLoc _getPrevRecord(OperationContext* opCtx, const DiskLoc& loc) const;
290 
291  DiskLoc _getNextRecordInExtent(OperationContext* opCtx, const DiskLoc& loc) const;
292  DiskLoc _getPrevRecordInExtent(OperationContext* opCtx, const DiskLoc& loc) const;
293 
298  DiskLoc _findFirstSpot(OperationContext* opCtx, const DiskLoc& extDiskLoc, Extent* e);
299 
303  void _addRecordToRecListInExtent(OperationContext* opCtx, MmapV1RecordHeader* r, DiskLoc loc);
304 
309  StatusWith<RecordId> _insertRecord(OperationContext* opCtx,
310  const char* data,
311  int len,
312  bool enforceQuota);
313 
314  std::unique_ptr<RecordStoreV1MetaData> _details;
317 
319 };
320 
327 public:
328  IntraExtentIterator(OperationContext* opCtx,
329  DiskLoc start,
330  const RecordStoreV1Base* rs,
331  bool forward = true)
332  : _opCtx(opCtx), _curr(start), _rs(rs), _forward(forward) {}
333 
334  boost::optional<Record> next() final;
335  void invalidate(OperationContext* opCtx, const RecordId& dl) final;
336  void save() final {}
337  bool restore() final {
338  return true;
339  }
341  _opCtx = nullptr;
342  }
343  void reattachToOperationContext(OperationContext* opCtx) final {
344  _opCtx = opCtx;
345  }
346  std::unique_ptr<RecordFetcher> fetcherForNext() const final;
347 
348 private:
349  virtual const MmapV1RecordHeader* recordFor(const DiskLoc& loc) const {
350  return _rs->recordFor(loc);
351  }
352 
353  void advance();
354 
355  OperationContext* _opCtx;
358  bool _forward;
359 };
360 } // namespace mongo
std::unique_ptr< RecordStore > _rs
Definition: kv_catalog_feature_tracker_test.cpp:102
ValidateCmdLevel
Definition: record_store.h:93
stdx::unordered_set< SavedCursor * > SavedCursorSet
Definition: record_store_v1_base.h:148
IntraExtentIterator(OperationContext *opCtx, DiskLoc start, const RecordStoreV1Base *rs, bool forward=true)
Definition: record_store_v1_base.h:328
DiskLoc _curr
Definition: record_store_v1_base.h:356
Collection *const OperationContext *const const StringData OptionalCollectionUUID CollectionCatalogEntry *const details
Definition: collection_impl.cpp:80
Definition: record_store.h:671
virtual bool setUserFlag(OperationContext *opCtx, int flag)=0
Definition: extent.h:50
Collection *const const NamespaceString & ns
Definition: collection_info_cache_impl.cpp:53
virtual void setStats(OperationContext *opCtx, long long dataSize, long long numRecords)=0
virtual bool isCapped() const =0
virtual const DiskLoc & firstExtent(OperationContext *opCtx) const =0
Copyright (C) 2014 MongoDB Inc.
Definition: bson_collection_catalog_entry.cpp:38
virtual long long numRecords(OperationContext *opCtx) const
Total number of record in the RecordStore.
Definition: record_store_v1_base.h:177
virtual void updateStatsAfterRepair(OperationContext *opCtx, long long numRecords, long long dataSize)
Called after a repair operation is run with the recomputed numRecords and dataSize.
Definition: record_store_v1_base.h:258
DiskLoc loc
Definition: record_store_v1_base.h:118
virtual const MmapV1RecordHeader * recordFor(const DiskLoc &loc) const
Definition: record_store_v1_base.h:349
Definition: record_store_v1_base.h:152
OperationContext Database StringData BSONObj CollectionOptions::ParseKind bool const BSONObj &idIndex Status
Definition: database_impl.cpp:956
virtual const DiskLoc & capExtent() const =0
virtual void setDeletedListEntry(OperationContext *opCtx, int bucket, const DiskLoc &loc)=0
A replacement for the Record class.
Definition: record_data.h:43
virtual DiskLoc deletedListEntry(int bucket) const =0
void save() final
Prepares for state changes in underlying data in a way that allows the cursor&#39;s current position to b...
Definition: record_store_v1_base.h:336
virtual const DiskLoc & lastExtent(OperationContext *opCtx) const =0
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
virtual void setLastExtent(OperationContext *opCtx, const DiskLoc &loc)=0
const bool _forward
Definition: ephemeral_for_test_btree_impl.cpp:449
Definition: record_store.h:78
represents a disk location/offset on disk in a database.
Definition: diskloc.h:53
virtual long long maxCappedDocs() const =0
SavedCursorSet _cursors
Definition: record_store_v1_base.h:149
Definition: record.h:58
ExtentManager * _extentManager
Definition: record_store_v1_base.h:315
Allows inserting a Record "in-place" without creating a copy ahead of time.
Definition: record_store.h:62
Definition: record.h:150
std::shared_ptr< void > data
Definition: ephemeral_for_test_record_store_test.cpp:74
std::unique_ptr< RecordStore > rs
Definition: kv_engine_test_timestamps.cpp:207
virtual DiskLoc deletedListLegacyGrabBag() const =0
virtual void setCapFirstNewRecord(OperationContext *opCtx, const DiskLoc &loc)=0
SpinLock _mutex
Definition: record_store_v1_base.h:146
Iterates over all records within a single extent.
Definition: record_store_v1_base.h:326
DiskLoc bucket
Definition: record_store_v1_base.h:116
The destructor ensures the cursor is unregistered when an exception is thrown.
Definition: record_store_v1_base.h:110
const RecordStoreV1Base * _rs
Definition: record_store_v1_base.h:357
bool capLooped() const
Definition: record_store_v1_base.h:56
SavedCursor()
Definition: record_store_v1_base.h:111
virtual void setDeletedListLegacyGrabBag(OperationContext *opCtx, const DiskLoc &loc)=0
bool _isSystemIndexes
Definition: record_store_v1_base.h:316
Definition: index_key_validate.h:40
std::unique_ptr< RecordStoreV1MetaData > _details
Definition: record_store_v1_base.h:314
BSONObj key
Definition: record_store_v1_base.h:117
virtual long long dataSize(OperationContext *opCtx) const
The dataSize is an approximation of the sum of the sizes (in bytes) of the documents or entries in th...
Definition: record_store_v1_base.h:174
virtual bool replaceUserFlags(OperationContext *opCtx, int flags)=0
This iterator will go over the collection twice - once going forward (first extent -> last extent) an...
Definition: record_store_v1_repair_iterator.h:43
virtual void orphanDeletedList(OperationContext *opCtx)=0
OperationContext * _opCtx
Definition: record_store_v1_base.h:355
Retrieves Records from a RecordStore.
Definition: record_store.h:141
virtual bool clearUserFlag(OperationContext *opCtx, int flag)=0
An abstraction used for storing documents in a collection or entries in an index. ...
Definition: record_store.h:282
DiskLoc bucket
Definition: btree_interface.cpp:336
void reattachToOperationContext(OperationContext *opCtx) final
Reattaches to the OperationContext and reacquires any storage-engine state.
Definition: record_store_v1_base.h:343
virtual bool isUserFlagSet(int flag) const =0
bool isValid() const
Definition: diskloc.h:115
virtual ~RecordStoreV1MetaData()
Definition: record_store_v1_base.h:48
bool _forward
Definition: record_store_v1_base.h:358
virtual long long dataSize() const =0
virtual void incrementStats(OperationContext *opCtx, long long dataSizeIncrement, long long numRecordsIncrement)=0
virtual const DiskLoc & capFirstNewRecord() const =0
virtual long long numRecords() const =0
virtual int lastExtentSize(OperationContext *opCtx) const =0
const RecordStoreV1MetaData * details() const
Definition: record_store_v1_base.h:231
ExtentManager basics.
Definition: extent_manager.h:64
SavedCursorRegistry savedCursors
Definition: record_store_v1_base.h:236
Definition: record_store_v1_base.h:46
OperationContext * _opCtx
Definition: ephemeral_for_test_btree_impl.cpp:447
void waitForAllEarlierOplogWritesToBeVisible(OperationContext *opCtx) const override
Waits for all writes that completed before this call to be visible to forward scans.
Definition: record_store_v1_base.h:256
void detachFromOperationContext() final
Detaches from the OperationContext and releases any storage-engine state.
Definition: record_store_v1_base.h:340
virtual void setCapExtent(OperationContext *opCtx, const DiskLoc &loc)=0
Collection *const OperationContext *const opCtx
Definition: collection_impl.cpp:80
virtual int userFlags() const =0
Class that stores active cursors that have been saved (as part of yielding) to allow them to be inval...
Definition: record_store_v1_base.h:104
virtual void setFirstExtent(OperationContext *opCtx, const DiskLoc &loc)=0
bool restore() final
Recovers from potential state changes in underlying data.
Definition: record_store_v1_base.h:337
SavedCursorRegistry * _registry
Definition: record_store_v1_base.h:123
virtual ~SavedCursor()
Definition: record_store_v1_base.h:112
virtual void setLastExtentSize(OperationContext *opCtx, int newMax)=0