private void GetRecoveryInfoFromLatestCheckpoints(out HybridLogCheckpointInfo recoveredHLCInfo, out IndexCheckpointInfo recoveredICInfo) { Debug.WriteLine("********* Primary Recovery Information ********"); recoveredHLCInfo = default; foreach (var hybridLogToken in checkpointManager.GetLogCheckpointTokens()) { try { recoveredHLCInfo = new HybridLogCheckpointInfo(); recoveredHLCInfo.Recover(hybridLogToken, checkpointManager, hlog.LogPageSizeBits); } catch { continue; } Debug.WriteLine("HybridLog Checkpoint: {0}", hybridLogToken); break; } if (recoveredHLCInfo.IsDefault()) { throw new FasterException("Unable to find valid index token"); } recoveredHLCInfo.info.DebugPrint(); recoveredICInfo = default; foreach (var indexToken in checkpointManager.GetIndexCheckpointTokens()) { try { // Recovery appropriate context information recoveredICInfo = new IndexCheckpointInfo(); recoveredICInfo.Recover(indexToken, checkpointManager); } catch { continue; } if (!IsCompatible(recoveredICInfo.info, recoveredHLCInfo.info)) { recoveredICInfo = default; continue; } Debug.WriteLine("Index Checkpoint: {0}", indexToken); recoveredICInfo.info.DebugPrint(); break; } if (recoveredICInfo.IsDefault()) { Debug.WriteLine("No index checkpoint found, recovering from beginning of log"); } }
private void FindRecoveryInfo(long requestedVersion, out HybridLogCheckpointInfo recoveredHlcInfo, out IndexCheckpointInfo recoveredICInfo) { Debug.WriteLine("********* Primary Recovery Information ********"); HybridLogCheckpointInfo current, closest = default; Guid closestToken = default; long closestVersion = long.MaxValue; byte[] cookie = default; // Traverse through all current tokens to find either the largest version or the version that's closest to // but smaller than the requested version. Need to iterate through all unpruned versions because file system // is not guaranteed to return tokens in order of freshness. foreach (var hybridLogToken in checkpointManager.GetLogCheckpointTokens()) { try { current = new HybridLogCheckpointInfo(); current.Recover(hybridLogToken, checkpointManager, hlog.LogPageSizeBits, out var currCookie, false); var distanceToTarget = (requestedVersion == -1 ? long.MaxValue : requestedVersion) - current.info.version; // This is larger than intended version, cannot recover to this. if (distanceToTarget < 0) { continue; } // We have found the exact version to recover to --- the above conditional establishes that the // checkpointed version is <= requested version, and if next version is larger than requestedVersion, // there cannot be any closer version. if (current.info.nextVersion > requestedVersion) { closest = current; closestToken = hybridLogToken; cookie = currCookie; break; } // Otherwise, write it down and wait to see if there's a closer one; if (distanceToTarget < closestVersion) { closestVersion = distanceToTarget; closest.Dispose(); closest = current; closestToken = hybridLogToken; cookie = currCookie; } else { current.Dispose(); } } catch { continue; } Debug.WriteLine("HybridLog Checkpoint: {0}", hybridLogToken); } recoveredHlcInfo = closest; recoveredCommitCookie = cookie; if (recoveredHlcInfo.IsDefault()) { throw new FasterException("Unable to find valid HybridLog token"); } if (recoveredHlcInfo.deltaLog != null) { recoveredHlcInfo.Dispose(); // need to actually scan delta log now recoveredHlcInfo.Recover(closestToken, checkpointManager, hlog.LogPageSizeBits, out _, true); } recoveredHlcInfo.info.DebugPrint(); recoveredICInfo = default; foreach (var indexToken in checkpointManager.GetIndexCheckpointTokens()) { try { // Recovery appropriate context information recoveredICInfo = new IndexCheckpointInfo(); recoveredICInfo.Recover(indexToken, checkpointManager); } catch { continue; } if (!IsCompatible(recoveredICInfo.info, recoveredHlcInfo.info)) { recoveredICInfo = default; continue; } Debug.WriteLine("Index Checkpoint: {0}", indexToken); recoveredICInfo.info.DebugPrint(); break; } if (recoveredICInfo.IsDefault()) { Debug.WriteLine("No index checkpoint found, recovering from beginning of log"); } }