private bool IsCompatible(IndexRecoveryInfo indexInfo, HybridLogRecoveryInfo recoveryInfo) { var l1 = indexInfo.finalLogicalAddress; var l2 = recoveryInfo.finalLogicalAddress; return(l1 <= l2); }
// Derived class exposed API protected void RecoverFuzzyIndex(IndexRecoveryInfo info) { var ht_version = resizeInfo.version; var token = info.token; Debug.Assert(state[ht_version].size == info.table_size); BeginMainIndexRecovery(ht_version, DirectoryConfiguration.GetPrimaryHashTableFileName(token), info.num_ht_bytes); overflowBucketsAllocator.Recover( DirectoryConfiguration.GetOverflowBucketsFileName(token), info.num_buckets, info.num_ofb_bytes); }
private void RecoverHybridLogFromSnapshotFile( IndexRecoveryInfo indexRecoveryInfo, HybridLogRecoveryInfo recoveryInfo) { var fileStartAddress = recoveryInfo.flushedLogicalAddress; var fromAddress = indexRecoveryInfo.startLogicalAddress; var untilAddress = recoveryInfo.finalLogicalAddress; // Compute startPage and endPage var startPage = hlog.GetPage(fileStartAddress); var endPage = hlog.GetPage(untilAddress); if (untilAddress > hlog.GetStartLogicalAddress(endPage)) { endPage++; } // By default first page has one extra record var capacity = hlog.GetCapacityNumPages(); var recoveryDevice = Devices.CreateLogDevice(directoryConfiguration.GetHybridLogCheckpointFileName(recoveryInfo.guid), false); var objectLogRecoveryDevice = Devices.CreateLogDevice(directoryConfiguration.GetHybridLogObjectCheckpointFileName(recoveryInfo.guid), false); recoveryDevice.Initialize(hlog.GetSegmentSize()); objectLogRecoveryDevice.Initialize(hlog.GetSegmentSize()); var recoveryStatus = new RecoveryStatus(capacity, startPage, endPage, untilAddress) { recoveryDevice = recoveryDevice, objectLogRecoveryDevice = objectLogRecoveryDevice, recoveryDevicePageOffset = startPage }; // Initially issue read request for all pages that can be held in memory int totalPagesToRead = (int)(endPage - startPage); int numPagesToReadFirst = Math.Min(capacity, totalPagesToRead); hlog.AsyncReadPagesFromDevice(startPage, numPagesToReadFirst, untilAddress, AsyncReadPagesCallbackForRecovery, recoveryStatus, recoveryStatus.recoveryDevicePageOffset, recoveryStatus.recoveryDevice, recoveryStatus.objectLogRecoveryDevice); for (long page = startPage; page < endPage; page++) { // Ensure the page is read from file int pageIndex = hlog.GetPageIndexForPage(page); while (recoveryStatus.readStatus[pageIndex] == ReadStatus.Pending) { Thread.Sleep(10); } // Page at hand var startLogicalAddress = hlog.GetStartLogicalAddress(page); var endLogicalAddress = hlog.GetStartLogicalAddress(page + 1); // Perform recovery if page in fuzzy portion of the log if ((fromAddress < endLogicalAddress) && (fromAddress < untilAddress)) { /* * Handling corner-cases: * ---------------------- * When fromAddress is in the middle of the page, * then start recovery only from corresponding offset * in page. Similarly, if untilAddress falls in the * middle of the page, perform recovery only until that * offset. Otherwise, scan the entire page [0, PageSize) */ var pageFromAddress = 0L; if (fromAddress > startLogicalAddress && fromAddress < endLogicalAddress) { pageFromAddress = hlog.GetOffsetInPage(fromAddress); } var pageUntilAddress = hlog.GetPageSize(); if (endLogicalAddress > untilAddress) { pageUntilAddress = hlog.GetOffsetInPage(untilAddress); } var physicalAddress = hlog.GetPhysicalAddress(startLogicalAddress); RecoverFromPage(fromAddress, pageFromAddress, pageUntilAddress, startLogicalAddress, physicalAddress, recoveryInfo.version); } // OS thread flushes current page and issues a read request if necessary recoveryStatus.readStatus[pageIndex] = ReadStatus.Pending; recoveryStatus.flushStatus[pageIndex] = FlushStatus.Pending; // Write back records from snapshot to main hybrid log hlog.AsyncFlushPages(page, 1, AsyncFlushPageCallbackForRecovery, recoveryStatus); } // Assert and wait until all pages have been flushed var done = false; while (!done) { done = true; for (long page = startPage; page < endPage; page++) { int pageIndex = hlog.GetPageIndexForPage(page); if (recoveryStatus.flushStatus[pageIndex] == FlushStatus.Pending) { done = false; break; } } } recoveryStatus.recoveryDevice.Close(); recoveryStatus.objectLogRecoveryDevice.Close(); }
private void RecoverHybridLog(IndexRecoveryInfo indexRecoveryInfo, HybridLogRecoveryInfo recoveryInfo) { var fromAddress = indexRecoveryInfo.startLogicalAddress; var untilAddress = recoveryInfo.finalLogicalAddress; var startPage = hlog.GetPage(fromAddress); var endPage = hlog.GetPage(untilAddress); if ((untilAddress > hlog.GetStartLogicalAddress(endPage)) && (untilAddress > fromAddress)) { endPage++; } // By default first page has one extra record var capacity = hlog.GetCapacityNumPages(); var recoveryStatus = new RecoveryStatus(capacity, startPage, endPage, untilAddress); int totalPagesToRead = (int)(endPage - startPage); int numPagesToReadFirst = Math.Min(capacity, totalPagesToRead); // Issue request to read pages as much as possible hlog.AsyncReadPagesFromDevice(startPage, numPagesToReadFirst, untilAddress, AsyncReadPagesCallbackForRecovery, recoveryStatus); for (long page = startPage; page < endPage; page++) { // Ensure page has been read into memory int pageIndex = hlog.GetPageIndexForPage(page); while (recoveryStatus.readStatus[pageIndex] == ReadStatus.Pending) { Thread.Sleep(10); } var startLogicalAddress = hlog.GetStartLogicalAddress(page); var endLogicalAddress = hlog.GetStartLogicalAddress(page + 1); var pageFromAddress = 0L; if (fromAddress > startLogicalAddress && fromAddress < endLogicalAddress) { pageFromAddress = hlog.GetOffsetInPage(fromAddress); } var pageUntilAddress = hlog.GetPageSize(); if (endLogicalAddress > untilAddress) { pageUntilAddress = hlog.GetOffsetInPage(untilAddress); } var physicalAddress = hlog.GetPhysicalAddress(startLogicalAddress); RecoverFromPage(fromAddress, pageFromAddress, pageUntilAddress, startLogicalAddress, physicalAddress, recoveryInfo.version); // OS thread flushes current page and issues a read request if necessary recoveryStatus.readStatus[pageIndex] = ReadStatus.Pending; recoveryStatus.flushStatus[pageIndex] = FlushStatus.Pending; hlog.AsyncFlushPages(page, 1, AsyncFlushPageCallbackForRecovery, recoveryStatus); } // Assert that all pages have been flushed var done = false; while (!done) { done = true; for (long page = startPage; page < endPage; page++) { int pageIndex = hlog.GetPageIndexForPage(page); if (recoveryStatus.flushStatus[pageIndex] == FlushStatus.Pending) { done = false; break; } } } }
public void Reset() { info = default; main_ht_device.Close(); }