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 
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.
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 
371 
372 }; // IndexConsistency
373 } // namespace mongo
bool indexScanFinished
Definition: index_consistency.h:71
void _addIndexKey_inlock(const KeyString &ks, int indexNumber)
Given the index entry's KeyString, decrement the corresponding _indexKeyCount by hashing it.
Definition: index_consistency.cpp:422
Collection * _collection
Definition: index_consistency.h:243
int64_t getNumKeys(int indexNumber) const
Returns the number of index entries for the given indexNs.
Definition: index_consistency.cpp:151
void addDocKey(const KeyString &ks, int indexNumber)
Helper functions for _addDocKey, _removeDocKey, _addIndexKey, and _removeIndexKey for concurrency con...
Definition: index_consistency.cpp:100
void _setYieldAtRecord_inlock(const RecordId recordId)
Allows the IndexObserver to set a yield point at recordId so that during the collection scan we must ...
Definition: index_consistency.cpp:456
bool shouldGetNewSnapshot(const RecordId recordId) const
Returns true if a new snapshot should be accquired.
Definition: index_consistency.cpp:357
ValidationOperation
The ValidationOperation is used by classes using the IndexObserver to let us know what operation was ...
Definition: index_consistency.h:52
void applyChange(const IndexDescriptor *descriptor, const boost::optional< IndexKeyEntry > &indexEntry, ValidationOperation operation)
This is the entry point for the IndexObserver to apply its observed changes while it is listening for...
Definition: index_consistency.cpp:203
bool _isBeforeLastProcessedIndexEntry_inlock(const KeyString &keyString) const
Returns true if the keyString is before or equal to the last processed index entry.
Definition: index_consistency.cpp:489
void setLastProcessedIndexEntry(const IndexDescriptor &descriptor, const boost::optional< IndexKeyEntry > &indexEntry)
Sets _lastProcessedIndexEntry to the KeyString of indexEntry.
Definition: index_consistency.cpp:308
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
int64_t getNumLongKeys(int indexNumber) const
Returns the number of long keys that were not indexed for the given indexNs.
Definition: index_consistency.cpp:161
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
int64_t getNumExtraIndexKeys(int indexNumber) const
Index entries may be added or removed by concurrent writes during the index scan phase,...
Definition: index_consistency.cpp:193
int64_t numExtraIndexKeys
Definition: index_consistency.h:81
int getIndexNumber(const std::string &indexNs)
Returns the index number for the corresponding index namespace's.
Definition: index_consistency.cpp:347
uint32_t _hashKeyString(const KeyString &ks, int indexNumbers) const
Returns a hashed value from the given KeyString and index namespace.
Definition: index_consistency.cpp:498
const RecordStore * _recordStore
Definition: index_consistency.h:245
Definition: key_string.h:47
const bool _isBackground
Definition: index_consistency.h:247
bool _isIndexFinished_inlock(int indexNumber) const
Returns true if the index for the given indexNs has finished being scanned by the validation,...
Definition: index_consistency.cpp:446
ValidationStage getStage() const
Returns the _stage that the validation is on.
Definition: index_consistency.cpp:292
void relockCollectionWithMode(LockMode mode)
Gives up the lock that the collection is currently held in and requests the the collection again in L...
Definition: index_consistency.cpp:377
IndexConsistency(OperationContext *opCtx, Collection *collection, NamespaceString nss, RecordStore *recordStore, std::unique_ptr< Lock::CollectionLock > collLk, const bool background)
Definition: index_consistency.cpp:52
bool _isIndexScanning_inlock(int indexNumber) const
Returns true if this is the current indexNs being scanned by validation, otherwise it returns false.
Definition: index_consistency.cpp:451
void notifyDoneIndex(int indexNumber)
Informs the IndexConsistency instance that the index scan has finished scanning the index with namesp...
Definition: index_consistency.cpp:335
void _removeIndexKey_inlock(const KeyString &ks, int indexNumber)
Given the index entry's KeyString, increment the corresponding _indexKeyCount by hashing it.
Definition: index_consistency.cpp:434
this is NOT safe through a yield right now.
Definition: collection.h:160
Status _throwExceptionIfError()
Used alongside yield() and relockCollectionWithMode() to ensure that after the execution of them it i...
Definition: index_consistency.cpp:507
bool _isBeforeLastProcessedRecordId_inlock(RecordId recordId) const
Returns true if the recordId is before or equal to the last processed RecordId.
Definition: index_consistency.cpp:480
void setLastProcessedRecordId(RecordId recordId)
Sets _lastProcessedRecordId to recordId.
Definition: index_consistency.cpp:298
void _addDocKey_inlock(const KeyString &ks, int indexNumber)
Given the document's key KeyString, increment the corresponding _indexKeyCount by hashing it.
Definition: index_consistency.cpp:398
void addIndexKey(const KeyString &ks, int indexNumber)
Definition: index_consistency.cpp:120
ElapsedTracker _tracker
Definition: index_consistency.h:248
ValidationStage _stage
Definition: index_consistency.h:277
int _currentIndex
Definition: index_consistency.h:274
Collection *const OperationContext *const const StringData OptionalCollectionUUID CollectionCatalogEntry *const RecordStore *const recordStore
Definition: collection_impl.cpp:80
void removeIndexKey(const KeyString &ks, int indexNumber)
Definition: index_consistency.cpp:130
OperationContext Database StringData CollectionOptions bool const BSONObj &idIndex Status
Definition: database_impl.cpp:955
Definition: index_consistency.h:84
int64_t numLongKeys
Definition: index_consistency.h:75
void notifyStartIndex(int indexNumber)
Informs the IndexConsistency instance that the index scan is beginning to scan the index with namespa...
Definition: index_consistency.cpp:324
LockMode
LockMode compatibility matrix.
Definition: lock_manager_defs.h:61
An abstraction used for storing documents in a collection or entries in an index.
Definition: record_store.h:282
bool haveEntryMismatch() const
Returns true if any value in the _indexKeyCount map is not equal to 0, otherwise return false.
Definition: index_consistency.cpp:181
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
std::unique_ptr< KeyString > _yieldAtIndexEntry
Definition: index_consistency.h:283
bool scanLimitHit()
Returns true if the ElapsedTracker says its time to yield during background validation.
Definition: index_consistency.cpp:390
boost::optional< RecordId > _yieldAtRecordId
Definition: index_consistency.h:280
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
static const int _kErrorThreshold
Definition: index_consistency.h:286
void removeDocKey(const KeyString &ks, int indexNumber)
Definition: index_consistency.cpp:110
int64_t getNumRecords(int indexNumber) const
Return the number of records with keys for the given indexNs.
Definition: index_consistency.cpp:171
int _numErrorsRecorded
Definition: index_consistency.h:289
std::map< std::string, int > _indexNumber
Definition: index_consistency.h:262
void _removeDocKey_inlock(const KeyString &ks, int indexNumber)
Given the document's key KeyString, decrement the corresponding _indexKeyCount by hashing it.
Definition: index_consistency.cpp:410
void _setYieldAtIndexEntry_inlock(const KeyString &keyString)
Allows the IndexObserver to set a yield point at the KeyString of indexEntry so that during the index...
Definition: index_consistency.cpp:467
Collection *const OperationContext *const opCtx
Definition: collection_impl.cpp:80
boost::optional< RecordId > _lastProcessedRecordId
Definition: index_consistency.h:268
void nextStage()
Moves the _stage variable to the next corresponding stage in the following order: DOCUMENT -> INDEX I...
Definition: index_consistency.cpp:282
std::unique_ptr< KeyString > _lastProcessedIndexEntry
Definition: index_consistency.h:271
void addLongIndexKey(int indexNumber)
Add one to the _longKeys count for the given indexNs.
Definition: index_consistency.cpp:140