diff options
Diffstat (limited to 'src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp')
-rw-r--r-- | src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp | 234 |
1 files changed, 115 insertions, 119 deletions
diff --git a/src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp b/src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp index a4cb9977fe3..728f07d6013 100644 --- a/src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp +++ b/src/mongo/db/storage/mmap_v1/record_store_v1_repair_iterator.cpp @@ -38,49 +38,47 @@ namespace mongo { - using std::endl; - - RecordStoreV1RepairCursor::RecordStoreV1RepairCursor(OperationContext* txn, - const RecordStoreV1Base* recordStore) - : _txn(txn), _recordStore(recordStore), _stage(FORWARD_SCAN) { - - // Position the iterator at the first record - // - advance(); - } - - boost::optional<Record> RecordStoreV1RepairCursor::next() { - if (_currRecord.isNull()) return {}; - auto out = _currRecord.toRecordId(); - advance(); - return {{out, _recordStore->dataFor(_txn, out)}}; - } - - boost::optional<Record> RecordStoreV1RepairCursor::seekExact(const RecordId& id) { - invariant(!"seekExact not supported"); - } - - void RecordStoreV1RepairCursor::advance() { - const ExtentManager* em = _recordStore->_extentManager; - - while (true) { - if (_currRecord.isNull()) { - - if (!_advanceToNextValidExtent()) { - return; - } +using std::endl; + +RecordStoreV1RepairCursor::RecordStoreV1RepairCursor(OperationContext* txn, + const RecordStoreV1Base* recordStore) + : _txn(txn), _recordStore(recordStore), _stage(FORWARD_SCAN) { + // Position the iterator at the first record + // + advance(); +} + +boost::optional<Record> RecordStoreV1RepairCursor::next() { + if (_currRecord.isNull()) + return {}; + auto out = _currRecord.toRecordId(); + advance(); + return {{out, _recordStore->dataFor(_txn, out)}}; +} + +boost::optional<Record> RecordStoreV1RepairCursor::seekExact(const RecordId& id) { + invariant(!"seekExact not supported"); +} + +void RecordStoreV1RepairCursor::advance() { + const ExtentManager* em = _recordStore->_extentManager; + + while (true) { + if (_currRecord.isNull()) { + if (!_advanceToNextValidExtent()) { + return; + } - _seenInCurrentExtent.clear(); + _seenInCurrentExtent.clear(); - // Otherwise _advanceToNextValidExtent would have returned false - // - invariant(!_currExtent.isNull()); + // Otherwise _advanceToNextValidExtent would have returned false + // + invariant(!_currExtent.isNull()); - const Extent* e = em->getExtent(_currExtent, false); - _currRecord = (FORWARD_SCAN == _stage ? e->firstRecord : e->lastRecord); - } - else { - switch (_stage) { + const Extent* e = em->getExtent(_currExtent, false); + _currRecord = (FORWARD_SCAN == _stage ? e->firstRecord : e->lastRecord); + } else { + switch (_stage) { case FORWARD_SCAN: _currRecord = _recordStore->getNextRecordInExtent(_txn, _currRecord); break; @@ -90,37 +88,37 @@ namespace mongo { default: invariant(!"This should never be reached."); break; - } - } - - if (_currRecord.isNull()) { - continue; } + } - // Validate the contents of the record's disk location and deduplicate - // - if (!_seenInCurrentExtent.insert(_currRecord).second) { - error() << "infinite loop in extent, seen: " << _currRecord << " before" << endl; - _currRecord = DiskLoc(); - continue; - } + if (_currRecord.isNull()) { + continue; + } - if (_currRecord.getOfs() <= 0){ - error() << "offset is 0 for record which should be impossible" << endl; - _currRecord = DiskLoc(); - continue; - } + // Validate the contents of the record's disk location and deduplicate + // + if (!_seenInCurrentExtent.insert(_currRecord).second) { + error() << "infinite loop in extent, seen: " << _currRecord << " before" << endl; + _currRecord = DiskLoc(); + continue; + } - return; + if (_currRecord.getOfs() <= 0) { + error() << "offset is 0 for record which should be impossible" << endl; + _currRecord = DiskLoc(); + continue; } + + return; } +} - bool RecordStoreV1RepairCursor::_advanceToNextValidExtent() { - const ExtentManager* em = _recordStore->_extentManager; +bool RecordStoreV1RepairCursor::_advanceToNextValidExtent() { + const ExtentManager* em = _recordStore->_extentManager; - while (true) { - if (_currExtent.isNull()) { - switch (_stage) { + while (true) { + if (_currExtent.isNull()) { + switch (_stage) { case FORWARD_SCAN: _currExtent = _recordStore->details()->firstExtent(_txn); break; @@ -130,35 +128,34 @@ namespace mongo { default: invariant(DONE == _stage); return false; - } - } - else { - // If _currExtent is not NULL, then it must point to a valid extent, so no extra - // checks here. - // - const Extent* e = em->getExtent(_currExtent, false); - _currExtent = (FORWARD_SCAN == _stage ? e->xnext : e->xprev); } - - bool hasNextExtent = !_currExtent.isNull(); - - // Sanity checks for the extent's disk location + } else { + // If _currExtent is not NULL, then it must point to a valid extent, so no extra + // checks here. // - if (hasNextExtent && (!_currExtent.isValid() || (_currExtent.getOfs() < 0))) { - error() << "Invalid extent location: " << _currExtent << endl; + const Extent* e = em->getExtent(_currExtent, false); + _currExtent = (FORWARD_SCAN == _stage ? e->xnext : e->xprev); + } - // Switch the direction of scan - // - hasNextExtent = false; - } + bool hasNextExtent = !_currExtent.isNull(); - if (hasNextExtent) { - break; - } + // Sanity checks for the extent's disk location + // + if (hasNextExtent && (!_currExtent.isValid() || (_currExtent.getOfs() < 0))) { + error() << "Invalid extent location: " << _currExtent << endl; - // Swap the direction of scan and loop again + // Switch the direction of scan // - switch (_stage) { + hasNextExtent = false; + } + + if (hasNextExtent) { + break; + } + + // Swap the direction of scan and loop again + // + switch (_stage) { case FORWARD_SCAN: _stage = BACKWARD_SCAN; break; @@ -168,49 +165,48 @@ namespace mongo { default: invariant(!"This should never be reached."); break; - } - - _currExtent = DiskLoc(); } + _currExtent = DiskLoc(); + } - // Check _currExtent's contents for validity, but do not count is as failure if they - // don't check out. - // - const Extent* e = em->getExtent(_currExtent, false); - if (!e->isOk()){ - warning() << "Extent not ok magic: " << e->magic << " going to try to continue" - << endl; - } - - log() << (FORWARD_SCAN == _stage ? "FORWARD" : "BACKWARD") << " Extent loc: " - << _currExtent << ", length: " << e->length << endl; - return true; + // Check _currExtent's contents for validity, but do not count is as failure if they + // don't check out. + // + const Extent* e = em->getExtent(_currExtent, false); + if (!e->isOk()) { + warning() << "Extent not ok magic: " << e->magic << " going to try to continue" << endl; } - void RecordStoreV1RepairCursor::invalidate(const RecordId& id) { - // If we see this record again it probably means it was reinserted rather than an infinite - // loop. If we do loop, we should quickly hit another seen record that hasn't been - // invalidated. - DiskLoc dl = DiskLoc::fromRecordId(id); - _seenInCurrentExtent.erase(dl); + log() << (FORWARD_SCAN == _stage ? "FORWARD" : "BACKWARD") << " Extent loc: " << _currExtent + << ", length: " << e->length << endl; - if (_currRecord == dl) { - // The DiskLoc being invalidated is also the one pointed at by this iterator. We - // advance the iterator so it's not pointing at invalid data. - advance(); + return true; +} - if (_currRecord == dl) { - // Even after advancing the iterator, we're still pointing at the DiskLoc being - // invalidated. This is expected when 'dl' is the last DiskLoc in the FORWARD scan, - // and the initial call to getNext() moves the iterator to the first loc in the - // BACKWARDS scan. - advance(); - } +void RecordStoreV1RepairCursor::invalidate(const RecordId& id) { + // If we see this record again it probably means it was reinserted rather than an infinite + // loop. If we do loop, we should quickly hit another seen record that hasn't been + // invalidated. + DiskLoc dl = DiskLoc::fromRecordId(id); + _seenInCurrentExtent.erase(dl); + + if (_currRecord == dl) { + // The DiskLoc being invalidated is also the one pointed at by this iterator. We + // advance the iterator so it's not pointing at invalid data. + advance(); - invariant(_currRecord != dl); + if (_currRecord == dl) { + // Even after advancing the iterator, we're still pointing at the DiskLoc being + // invalidated. This is expected when 'dl' is the last DiskLoc in the FORWARD scan, + // and the initial call to getNext() moves the iterator to the first loc in the + // BACKWARDS scan. + advance(); } + + invariant(_currRecord != dl); } +} } // namespace mongo |