MCPcopy Create free account
hub / github.com/apple/foundationdb / recover

Method recover

fdbserver/KeyValueStoreMemory.actor.cpp:543–735  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

541 }
542
543 ACTOR static Future<Void> recover(KeyValueStoreMemory* self, bool exactRecovery) {
544 loop {
545 // 'uncommitted' variables track something that might be rolled back by an OpRollback, and are copied into
546 // permanent variables (in self) in OpCommit. OpRollback does the reverse (copying the permanent versions
547 // over the uncommitted versions) the uncommitted and committed variables should be equal initially (to
548 // whatever makes sense if there are no committed transactions recovered)
549 state Key uncommittedNextKey = self->recoveredSnapshotKey;
550 state IDiskQueue::location uncommittedPrevSnapshotEnd = self->previousSnapshotEnd =
551 self->log->getNextReadLocation(); // not really, but popping up to here does nothing
552 state IDiskQueue::location uncommittedSnapshotEnd = self->currentSnapshotEnd = uncommittedPrevSnapshotEnd;
553
554 state int zeroFillSize = 0;
555 state int dbgSnapshotItemCount = 0;
556 state int dbgSnapshotEndCount = 0;
557 state int dbgMutationCount = 0;
558 state int dbgCommitCount = 0;
559 state double startt = now();
560 state UID dbgid = self->id;
561
562 state Future<Void> loggingDelay = delay(1.0);
563
564 state OpQueue recoveryQueue;
565 state OpHeader h;
566 state Standalone<StringRef> lastSnapshotKey;
567 state bool isZeroFilled;
568
569 TraceEvent("KVSMemRecoveryStarted", self->id).detail("SnapshotEndLocation", uncommittedSnapshotEnd);
570
571 try {
572 loop {
573 {
574 Standalone<StringRef> data = wait(self->log->readNext(sizeof(OpHeader)));
575 if (data.size() != sizeof(OpHeader)) {
576 if (data.size()) {
577 CODE_PROBE(true, "zero fill partial header in KeyValueStoreMemory");
578 memset(&h, 0, sizeof(OpHeader));
579 memcpy(&h, data.begin(), data.size());
580 zeroFillSize = sizeof(OpHeader) - data.size() + h.len1 + h.len2 + 1;
581 if (h.op == OpEncrypted) {
582 // encryption header, plus the real (encrypted) op type
583 zeroFillSize += BlobCipherEncryptHeader::headerSize + sizeof(int);
584 }
585 }
586 TraceEvent("KVSMemRecoveryComplete", self->id)
587 .detail("Reason", "Non-header sized data read")
588 .detail("DataSize", data.size())
589 .detail("ZeroFillSize", zeroFillSize)
590 .detail("SnapshotEndLocation", uncommittedSnapshotEnd)
591 .detail("NextReadLoc", self->log->getNextReadLocation());
592 break;
593 }
594 h = *(OpHeader*)data.begin();
595 }
596 state Standalone<StringRef> data = wait(readOpData(self, &h, &isZeroFilled, &zeroFillSize));
597 if (zeroFillSize > 0) {
598 TraceEvent("KVSMemRecoveryComplete", self->id)
599 .detail("Reason", "data specified by header does not exist")
600 .detail("DataSize", data.size())

Callers

nothing calls this directly

Calls 15

commit_queueMethod · 0.95
log_opMethod · 0.95
semiCommitMethod · 0.95
nowFunction · 0.85
delayFunction · 0.85
TraceEventClass · 0.85
memcpyFunction · 0.85
makeStringFunction · 0.85
mutateStringFunction · 0.85
yieldFunction · 0.85
detailMethod · 0.80
substrMethod · 0.80

Tested by

no test coverage detected