// Derived class exposed API
        internal void RecoverFuzzyIndex(IndexCheckpointInfo info)
        {
            var token      = info.info.token;
            var ht_version = resizeInfo.version;

            if (state[ht_version].size != info.info.table_size)
            {
                throw new FasterException($"Incompatible hash table size during recovery; allocated {state[ht_version].size} buckets, recovering {info.info.table_size} buckets");
            }

            // Create devices to read from using Async API
            info.main_ht_device = checkpointManager.GetIndexDevice(token);

            BeginMainIndexRecovery(ht_version,
                                   info.main_ht_device,
                                   info.info.num_ht_bytes);

            var sectorSize       = info.main_ht_device.SectorSize;
            var alignedIndexSize = (uint)((info.info.num_ht_bytes + (sectorSize - 1)) & ~(sectorSize - 1));

            overflowBucketsAllocator.Recover(info.main_ht_device, alignedIndexSize, info.info.num_buckets, info.info.num_ofb_bytes);

            // Wait until reading is complete
            IsFuzzyIndexRecoveryComplete(true);

            // close index checkpoint files appropriately
            info.main_ht_device.Dispose();

            // Delete all tentative entries!
            DeleteTentativeEntries();
        }
Esempio n. 2
0
        // Derived class exposed API
        internal void RecoverFuzzyIndex(IndexCheckpointInfo info)
        {
            var token      = info.info.token;
            var ht_version = resizeInfo.version;

            Debug.Assert(state[ht_version].size == info.info.table_size);

            // Create devices to read from using Async API
            info.main_ht_device = Devices.CreateLogDevice(directoryConfiguration.GetPrimaryHashTableFileName(token), false);
            info.ofb_device     = Devices.CreateLogDevice(directoryConfiguration.GetOverflowBucketsFileName(token), false);

            BeginMainIndexRecovery(ht_version,
                                   info.main_ht_device,
                                   info.info.num_ht_bytes);

            overflowBucketsAllocator.Recover(
                info.ofb_device,
                info.info.num_buckets,
                info.info.num_ofb_bytes);

            // Wait until reading is complete
            IsFuzzyIndexRecoveryComplete(true);

            // close index checkpoint files appropriately
            info.main_ht_device.Close();
            info.ofb_device.Close();

            // Delete all tentative entries!
            DeleteTentativeEntries();
        }
Esempio n. 3
0
        private void FinalizeMainIndexRecovery(IndexCheckpointInfo info)
        {
            // close index checkpoint files appropriately
            info.main_ht_device.Dispose();

            // Delete all tentative entries!
            DeleteTentativeEntries();
        }
Esempio n. 4
0
        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");
            }
        }
Esempio n. 5
0
        private void InternalRecover(Guid indexToken, Guid hybridLogToken)
        {
            Debug.WriteLine("********* Primary Recovery Information ********");
            Debug.WriteLine("Index Checkpoint: {0}", indexToken);
            Debug.WriteLine("HybridLog Checkpoint: {0}", hybridLogToken);

            // Recovery appropriate context information
            var recoveredICInfo = new IndexCheckpointInfo();

            recoveredICInfo.Recover(indexToken, checkpointManager);
            recoveredICInfo.info.DebugPrint();

            var recoveredHLCInfo = new HybridLogCheckpointInfo();

            recoveredHLCInfo.Recover(hybridLogToken, checkpointManager);
            recoveredHLCInfo.info.DebugPrint();

            // Check if the two checkpoints are compatible for recovery
            if (!IsCompatible(recoveredICInfo.info, recoveredHLCInfo.info))
            {
                throw new Exception("Cannot recover from (" + indexToken.ToString() + "," + hybridLogToken.ToString() + ") checkpoint pair!\n");
            }

            // Set new system state after recovery
            var v = recoveredHLCInfo.info.version;

            _systemState.phase   = Phase.REST;
            _systemState.version = (v + 1);

            // Recover fuzzy index from checkpoint
            RecoverFuzzyIndex(recoveredICInfo);

            // Recover segment offsets for object log
            if (recoveredHLCInfo.info.objectLogSegmentOffsets != null)
            {
                Array.Copy(recoveredHLCInfo.info.objectLogSegmentOffsets,
                           hlog.GetSegmentOffsets(),
                           recoveredHLCInfo.info.objectLogSegmentOffsets.Length);
            }


            // Make index consistent for version v
            if (FoldOverSnapshot)
            {
                RecoverHybridLog(recoveredICInfo.info, recoveredHLCInfo.info);
            }
            else
            {
                RecoverHybridLogFromSnapshotFile(recoveredICInfo.info, recoveredHLCInfo.info);
            }


            // Read appropriate hybrid log pages into memory
            RestoreHybridLog(recoveredHLCInfo.info.finalLogicalAddress, recoveredHLCInfo.info.headAddress, recoveredHLCInfo.info.beginAddress);

            // Recover session information
            _recoveredSessions = recoveredHLCInfo.info.continueTokens;
        }
Esempio n. 6
0
        internal async ValueTask RecoverFuzzyIndexAsync(IndexCheckpointInfo info, CancellationToken cancellationToken)
        {
            ulong alignedIndexSize = InitializeMainIndexRecovery(ref info, isAsync: true);

            await this.recoveryCountdown.WaitAsync(cancellationToken).ConfigureAwait(false);

            await overflowBucketsAllocator.RecoverAsync(info.main_ht_device, alignedIndexSize, info.info.num_buckets, info.info.num_ofb_bytes, cancellationToken).ConfigureAwait(false);

            FinalizeMainIndexRecovery(info);
        }
Esempio n. 7
0
        // Derived class exposed API
        internal void RecoverFuzzyIndex(IndexCheckpointInfo info)
        {
            ulong alignedIndexSize = InitializeMainIndexRecovery(ref info, isAsync: false);

            overflowBucketsAllocator.Recover(info.main_ht_device, alignedIndexSize, info.info.num_buckets, info.info.num_ofb_bytes);

            // Wait until reading is complete
            IsFuzzyIndexRecoveryComplete(true);
            FinalizeMainIndexRecovery(info);
        }
Esempio n. 8
0
        // Derived class exposed API
        internal void RecoverFuzzyIndex(IndexCheckpointInfo info)
        {
            var ht_version = resizeInfo.version;
            var token      = info.info.token;

            Debug.Assert(state[ht_version].size == info.info.table_size);

            BeginMainIndexRecovery(ht_version,
                                   info.main_ht_device,
                                   info.info.num_ht_bytes);

            overflowBucketsAllocator.Recover(
                info.ofb_device,
                info.info.num_buckets,
                info.info.num_ofb_bytes);
        }
Esempio n. 9
0
        private uint InitializeMainIndexRecovery(ref IndexCheckpointInfo info, bool isAsync)
        {
            var token      = info.info.token;
            var ht_version = resizeInfo.version;

            if (state[ht_version].size != info.info.table_size)
            {
                throw new FasterException($"Incompatible hash table size during recovery; allocated {state[ht_version].size} buckets, recovering {info.info.table_size} buckets");
            }

            // Create devices to read from using Async API
            info.main_ht_device = checkpointManager.GetIndexDevice(token);

            BeginMainIndexRecovery(ht_version, info.main_ht_device, info.info.num_ht_bytes, isAsync);

            var sectorSize       = info.main_ht_device.SectorSize;
            var alignedIndexSize = (uint)((info.info.num_ht_bytes + (sectorSize - 1)) & ~(sectorSize - 1));

            return(alignedIndexSize);
        }
Esempio n. 10
0
        private ulong InitializeMainIndexRecovery(ref IndexCheckpointInfo info, bool isAsync)
        {
            var token      = info.info.token;
            var ht_version = resizeInfo.version;

            // Create devices to read from using Async API
            info.main_ht_device = checkpointManager.GetIndexDevice(token);
            var sectorSize = info.main_ht_device.SectorSize;

            if (state[ht_version].size != info.info.table_size)
            {
                Free(ht_version);
                Initialize(info.info.table_size, (int)sectorSize);
            }


            BeginMainIndexRecovery(ht_version, info.main_ht_device, info.info.num_ht_bytes, isAsync);


            var alignedIndexSize = (info.info.num_ht_bytes + (sectorSize - 1)) & ~((ulong)sectorSize - 1);

            return(alignedIndexSize);
        }
Esempio n. 11
0
        private void InternalRecover(Guid indexToken, Guid hybridLogToken)
        {
            Debug.WriteLine("********* Primary Recovery Information ********");
            Debug.WriteLine("Index Checkpoint: {0}", indexToken);
            Debug.WriteLine("HybridLog Checkpoint: {0}", hybridLogToken);

            // Assert corresponding checkpoints are safe to recover from
            Debug.Assert(IsCheckpointSafe(indexToken, CheckpointType.INDEX_ONLY),
                         "Cannot recover from incomplete index checkpoint " + indexToken.ToString());

            Debug.Assert(IsCheckpointSafe(hybridLogToken, CheckpointType.HYBRID_LOG_ONLY),
                         "Cannot recover from incomplete hybrid log checkpoint " + hybridLogToken.ToString());

            // Recovery appropriate context information
            var recoveredICInfo = new IndexCheckpointInfo();

            recoveredICInfo.Recover(indexToken, directoryConfiguration);
            recoveredICInfo.info.DebugPrint();

            var recoveredHLCInfo = new HybridLogCheckpointInfo();

            recoveredHLCInfo.Recover(hybridLogToken, directoryConfiguration);
            recoveredHLCInfo.info.DebugPrint();

            // Check if the two checkpoints are compatible for recovery
            if (!IsCompatible(recoveredICInfo.info, recoveredHLCInfo.info))
            {
                throw new Exception("Cannot recover from (" + indexToken.ToString() + "," + hybridLogToken.ToString() + ") checkpoint pair!\n");
            }

            // Set new system state after recovery
            var v = recoveredHLCInfo.info.version;

            _systemState.phase   = Phase.REST;
            _systemState.version = (v + 1);

            // Recover fuzzy index from checkpoint
            RecoverFuzzyIndex(recoveredICInfo);

            // Recover segment offsets for object log
            if (recoveredHLCInfo.info.objectLogSegmentOffsets != null)
            {
                Array.Copy(recoveredHLCInfo.info.objectLogSegmentOffsets,
                           hlog.GetSegmentOffsets(),
                           recoveredHLCInfo.info.objectLogSegmentOffsets.Length);
            }


            // Make index consistent for version v
            if (FoldOverSnapshot)
            {
                RecoverHybridLog(recoveredICInfo.info, recoveredHLCInfo.info);
            }
            else
            {
                RecoverHybridLogFromSnapshotFile(recoveredICInfo.info, recoveredHLCInfo.info);
            }


            // Read appropriate hybrid log pages into memory
            RestoreHybridLog(recoveredHLCInfo.info.finalLogicalAddress);

            // Recover session information
            _recoveredSessions = new SafeConcurrentDictionary <Guid, long>();
            foreach (var sessionInfo in recoveredHLCInfo.info.continueTokens)
            {
                _recoveredSessions.GetOrAdd(sessionInfo.Key, sessionInfo.Value);
            }
        }
Esempio n. 12
0
        private void InternalRecoverFromLatestCheckpoints(int numPagesToPreload, bool undoFutureVersions)
        {
            Debug.WriteLine("********* Primary Recovery Information ********");

            HybridLogCheckpointInfo recoveredHLCInfo = default;

            foreach (var hybridLogToken in checkpointManager.GetLogCheckpointTokens())
            {
                try
                {
                    recoveredHLCInfo = new HybridLogCheckpointInfo();
                    recoveredHLCInfo.Recover(hybridLogToken, checkpointManager);
                }
                catch
                {
                    continue;
                }

                Debug.WriteLine("HybridLog Checkpoint: {0}", hybridLogToken);
                break;
            }

            if (recoveredHLCInfo.IsDefault())
            {
                throw new FasterException("Unable to find valid index token");
            }

            recoveredHLCInfo.info.DebugPrint();

            IndexCheckpointInfo 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");
            }

            InternalRecover(recoveredICInfo, recoveredHLCInfo, numPagesToPreload, undoFutureVersions);
        }