Storage Engine API
index_consistency.h
Go to the documentation of this file.
1 
29 #pragma once
30 
32 #include "mongo/db/index/index_descriptor.h"
36 #include "mongo/util/elapsed_tracker.h"
37 
38 namespace mongo {
39 
45 
53 
65 struct IndexInfo {
66  // Informs us if the index was ready or not for consumption during the start of validation.
67  bool isReady;
68  // Contains the pre-computed hashed of the index namespace.
69  uint32_t indexNsHash;
70  // True if the index has finished scanning from the index scan stage, otherwise false.
72  // The number of index entries belonging to the index.
73  int64_t numKeys;
74  // The number of long keys that are not indexed for the index.
75  int64_t numLongKeys;
76  // The number of records that have a key in their document that referenced back to the
77  // this index
78  int64_t numRecords;
79  // Keeps track of how many indexes were removed (-1) and added (+1) after the
80  // point of validity was set for this index.
82 };
83 
84 class IndexConsistency final {
85 public:
86  IndexConsistency(OperationContext* opCtx,
88  NamespaceString nss,
90  std::unique_ptr<Lock::CollectionLock> collLk,
91  const bool background);
92 
97  void addDocKey(const KeyString& ks, int indexNumber);
98  void removeDocKey(const KeyString& ks, int indexNumber);
99  void addIndexKey(const KeyString& ks, int indexNumber);
100  void removeIndexKey(const KeyString& ks, int indexNumber);
101 
106  void addLongIndexKey(int indexNumber);
107 
111  int64_t getNumKeys(int indexNumber) const;
112 
116  int64_t getNumLongKeys(int indexNumber) const;
117 
121  int64_t getNumRecords(int indexNumber) const;
122 
127  bool haveEntryMismatch() const;
128 
136  int64_t getNumExtraIndexKeys(int indexNumber) const;
137 
167  void applyChange(const IndexDescriptor* descriptor,
168  const boost::optional<IndexKeyEntry>& indexEntry,
169  ValidationOperation operation);
170 
177  void nextStage();
178 
182  ValidationStage getStage() const;
183 
187  void setLastProcessedRecordId(RecordId recordId);
188 
192  void setLastProcessedIndexEntry(const IndexDescriptor& descriptor,
193  const boost::optional<IndexKeyEntry>& indexEntry);
194 
200  void notifyStartIndex(int indexNumber);
201 
207  void notifyDoneIndex(int indexNumber);
208 
212  int getIndexNumber(const std::string& indexNs);
213 
220  bool shouldGetNewSnapshot(const RecordId recordId) const;
221 
228  bool shouldGetNewSnapshot(const KeyString& keyString) const;
229 
234  void relockCollectionWithMode(LockMode mode);
235 
239  bool scanLimitHit();
240 
241 private:
242  OperationContext* _opCtx;
244  const NamespaceString _nss;
246  std::unique_ptr<Lock::CollectionLock> _collLk;
247  const bool _isBackground;
248  ElapsedTracker _tracker;
249 
250  // We map the hashed KeyString values to a bucket which contain the count of how many
251  // index keys and document keys we've seen in each bucket.
252  // Count rules:
253  // - If the count is 0 in the bucket, we have index consistency for
254  // KeyStrings that mapped to it
255  // - If the count is > 0 in the bucket at the end of the validation pass, then there
256  // are too few index entries.
257  // - If the count is < 0 in the bucket at the end of the validation pass, then there
258  // are too many index entries.
259  std::map<uint32_t, uint32_t> _indexKeyCount;
260 
261  // Contains the corresponding index number for each index namespace
262  std::map<std::string, int> _indexNumber;
263 
264  // A mapping of index numbers to IndexInfo
265  std::map<int, IndexInfo> _indexesInfo;
266 
267  // RecordId of the last processed document during the collection scan.
268  boost::optional<RecordId> _lastProcessedRecordId = boost::none;
269 
270  // KeyString of the last processed index entry during the index scan.
271  std::unique_ptr<KeyString> _lastProcessedIndexEntry = nullptr;
272 
273  // The current index namespace being scanned in the index scan phase.
274  int _currentIndex = -1;
275 
276  // The stage that the validation is currently on.
278 
279  // Contains the RecordId of when we should yield collection scan.
280  boost::optional<RecordId> _yieldAtRecordId = boost::none;
281 
282  // Contains the KeyString of when we should yield during the index scan.
283  std::unique_ptr<KeyString> _yieldAtIndexEntry = nullptr;
284 
285  // Threshold for the number of errors to record before returning "There are too many errors".
286  static const int _kErrorThreshold = 100;
287 
288  // The current number of errors that are recorded.
289  int _numErrorsRecorded = 0;
290 
291  // Only one thread can use the class at a time
292  mutable stdx::mutex _classMutex;
293 
298  void _addDocKey_inlock(const KeyString& ks, int indexNumber);
299 
304  void _removeDocKey_inlock(const KeyString& ks, int indexNumber);
305 
310  void _addIndexKey_inlock(const KeyString& ks, int indexNumber);
311 
316  void _removeIndexKey_inlock(const KeyString& ks, int indexNumber);
317 
322  bool _isIndexFinished_inlock(int indexNumber) const;
323 
328  bool _isIndexScanning_inlock(int indexNumber) const;
329 
335  void _setYieldAtRecord_inlock(const RecordId recordId);
336 
342  void _setYieldAtIndexEntry_inlock(const KeyString& keyString);
343 
348  bool _isBeforeLastProcessedRecordId_inlock(RecordId recordId) const;
349 
354  bool _isBeforeLastProcessedIndexEntry_inlock(const KeyString& keyString) const;
355 
359  uint32_t _hashKeyString(const KeyString& ks, int indexNumbers) const;
360 
370  Status _throwExceptionIfError();
371 
372 }; // IndexConsistency
373 } // namespace mongo
bool indexScanFinished
Definition: index_consistency.h:71
Collection * _collection
Definition: index_consistency.h:243
ValidationOperation
The ValidationOperation is used by classes using the IndexObserver to let us know what operation was ...
Definition: index_consistency.h:52
const NamespaceString _nss
Definition: index_consistency.h:244
int64_t numKeys
Definition: index_consistency.h:73
Copyright (C) 2014 MongoDB Inc.
Definition: bson_collection_catalog_entry.cpp:38
OperationContext * _opCtx
Definition: index_consistency.h:242
std::unique_ptr< Lock::CollectionLock > _collLk
Definition: index_consistency.h:246
Collection *const collection
Definition: collection_info_cache_impl.cpp:53
OperationContext Database StringData BSONObj CollectionOptions::ParseKind bool const BSONObj &idIndex Status
Definition: database_impl.cpp:956
int64_t numExtraIndexKeys
Definition: index_consistency.h:81
const RecordStore * _recordStore
Definition: index_consistency.h:245
Definition: key_string.h:47
const bool _isBackground
Definition: index_consistency.h:247
this is NOT safe through a yield right now.
Definition: collection.h:160
ElapsedTracker _tracker
Definition: index_consistency.h:248
Collection *const OperationContext *const const StringData OptionalCollectionUUID CollectionCatalogEntry *const RecordStore *const recordStore
Definition: collection_impl.cpp:80
Definition: index_consistency.h:84
int64_t numLongKeys
Definition: index_consistency.h:75
LockMode
Lock modes.
Definition: lock_manager_defs.h:59
An abstraction used for storing documents in a collection or entries in an index. ...
Definition: record_store.h:282
ValidationStage
The ValidationStage allows the IndexConsistency class to perform the correct operations that depend o...
Definition: index_consistency.h:44
uint32_t indexNsHash
Definition: index_consistency.h:69
IndexCatalogEntry *const OperationContext *const const StringData CollectionCatalogEntry *const std::unique_ptr< IndexDescriptor > descriptor
Definition: index_catalog_entry_impl.cpp:58
std::map< uint32_t, uint32_t > _indexKeyCount
Definition: index_consistency.h:259
bool isReady
Definition: index_consistency.h:67
int64_t numRecords
Definition: index_consistency.h:78
The IndexConsistency class is used to keep track of the index consistency.
Definition: index_consistency.h:65
std::map< int, IndexInfo > _indexesInfo
Definition: index_consistency.h:265
stdx::mutex _classMutex
Definition: index_consistency.h:292
std::map< std::string, int > _indexNumber
Definition: index_consistency.h:262
Collection *const OperationContext *const opCtx
Definition: collection_impl.cpp:80