Search in sources :

Example 1 with DataLogCorruptedException

use of io.pravega.segmentstore.storage.DataLogCorruptedException in project pravega by pravega.

the class DurableLog method performRecovery.

@SneakyThrows(Exception.class)
private boolean performRecovery() {
    // Make sure we are in the correct state. We do not want to do recovery while we are in full swing.
    Preconditions.checkState(state() == State.STARTING || (state() == State.RUNNING && isOffline()), "Invalid State for recovery.");
    Timer timer = new Timer();
    try {
        // Initialize the DurableDataLog, which will acquire its lock and ensure we are the only active users of it.
        this.durableDataLog.initialize(DEFAULT_TIMEOUT);
        // Initiate the recovery.
        RecoveryProcessor p = new RecoveryProcessor(this.metadata, this.durableDataLog, this.memoryStateUpdater);
        int recoveredItemCount = p.performRecovery();
        this.operationProcessor.getMetrics().operationsCompleted(recoveredItemCount, timer.getElapsed());
        this.operationProcessor.getMetrics().reportOperationLogSize(recoveredItemCount, this.getId());
        // Verify that the Recovery Processor has left the metadata in a non-recovery mode.
        Preconditions.checkState(!this.metadata.isRecoveryMode(), "Recovery completed but Metadata is still in Recovery Mode.");
        return recoveredItemCount > 0;
    } catch (Exception ex) {
        log.error("{} Recovery FAILED.", this.traceObjectId, ex);
        Throwable cause = Exceptions.unwrap(ex);
        if (cause instanceof ServiceHaltException || cause instanceof DataLogCorruptedException) {
            // debugging information before someone can manually fix the problem).
            try {
                this.durableDataLog.disable();
                log.info("{} Log disabled due to {} during recovery.", this.traceObjectId, cause.getClass().getSimpleName());
            } catch (Exception disableEx) {
                log.warn("{}: Unable to disable log after DataCorruptionException during recovery.", this.traceObjectId, disableEx);
                ex.addSuppressed(disableEx);
            }
        }
        throw ex;
    }
}
Also used : DataLogCorruptedException(io.pravega.segmentstore.storage.DataLogCorruptedException) TimeoutTimer(io.pravega.common.TimeoutTimer) Timer(io.pravega.common.Timer) ServiceHaltException(io.pravega.segmentstore.server.ServiceHaltException) ObjectClosedException(io.pravega.common.ObjectClosedException) IllegalContainerStateException(io.pravega.segmentstore.server.IllegalContainerStateException) StreamingException(io.pravega.segmentstore.contracts.StreamingException) ServiceHaltException(io.pravega.segmentstore.server.ServiceHaltException) DataLogDisabledException(io.pravega.segmentstore.storage.DataLogDisabledException) ContainerOfflineException(io.pravega.segmentstore.server.ContainerOfflineException) CompletionException(java.util.concurrent.CompletionException) DataLogCorruptedException(io.pravega.segmentstore.storage.DataLogCorruptedException) SneakyThrows(lombok.SneakyThrows)

Example 2 with DataLogCorruptedException

use of io.pravega.segmentstore.storage.DataLogCorruptedException in project pravega by pravega.

the class BookKeeperLogTests method testReadWithBadLogId.

/**
 * Tests the ability to reject reading from a Log if it has been found it contains Ledgers that do not belong to it.
 */
@Test
public void testReadWithBadLogId() throws Exception {
    final BookKeeper bk = this.factory.get().getBookKeeperClient();
    try (val log = (BookKeeperLog) createDurableDataLog()) {
        log.initialize(TIMEOUT);
        log.append(new CompositeByteArraySegment(new byte[100]), TIMEOUT).join();
    }
    // Add some bad ledgers to the log's metadata.
    val writeLog = (BookKeeperLog) createDurableDataLog();
    val wrapper = this.factory.get().createDebugLogWrapper(writeLog.getLogId());
    wrapper.disable();
    val ledgerNoLogId = createCustomLedger(null);
    val corruptedId = new HashMap<>(Ledgers.createLedgerCustomMetadata(CONTAINER_ID));
    corruptedId.put(Ledgers.PROPERTY_LOG_ID, "abc".getBytes());
    val ledgerBadLogId = createCustomLedger(corruptedId);
    val ledgerOtherLogId = createCustomLedger(Ledgers.createLedgerCustomMetadata(CONTAINER_ID + 1));
    val ledgerGoodLogId = Ledgers.create(bk, this.config.get(), CONTAINER_ID);
    val candidateLedgers = Arrays.asList(ledgerNoLogId, ledgerBadLogId, ledgerOtherLogId, ledgerGoodLogId);
    for (val lh : candidateLedgers) {
        lh.append(new byte[100]);
    }
    // Persist the metadata with bad ledgers.
    val initialMetadata = wrapper.fetchMetadata();
    val newLedgers = new ArrayList<LedgerMetadata>();
    newLedgers.addAll(initialMetadata.getLedgers());
    candidateLedgers.forEach(l -> newLedgers.add(new LedgerMetadata(l.getId(), newLedgers.size() + 1)));
    val badMetadata = LogMetadata.builder().enabled(false).epoch(initialMetadata.getEpoch() + 1).truncationAddress(LogMetadata.INITIAL_TRUNCATION_ADDRESS).updateVersion(wrapper.fetchMetadata().getUpdateVersion()).ledgers(newLedgers).build();
    writeLog.overWriteMetadata(badMetadata);
    // Perform an initial read. This should fail.
    val readLog = (BookKeeperLog) createDurableDataLog();
    readLog.enable();
    readLog.initialize(TIMEOUT);
    @Cleanup val reader = readLog.getReader();
    AssertExtensions.assertThrows("No read exception thrown.", () -> {
        while (reader.getNext() != null) {
        // This is intentionally left blank. We do not care what we read back.
        }
    }, ex -> ex instanceof DataLogCorruptedException);
    // Perform reconciliation.
    BookKeeperLog reconcileLog = (BookKeeperLog) createDurableDataLog();
    DebugBookKeeperLogWrapper reconcileWrapper = this.factory.get().createDebugLogWrapper(reconcileLog.getLogId());
    reconcileWrapper.disable();
    val allLedgers = new ArrayList<ReadHandle>();
    for (LedgerMetadata lm : reconcileWrapper.fetchMetadata().getLedgers()) {
        allLedgers.add(reconcileWrapper.openLedgerNoFencing(lm));
    }
    boolean isChanged = reconcileWrapper.reconcileLedgers(allLedgers);
    Assert.assertTrue("Expected something to change.", isChanged);
    // There should only be two ledgers that survived: the one where we wrote to the original log and ledgerGoodLogId.
    checkLogReadAfterReconciliation(2);
}
Also used : lombok.val(lombok.val) CompositeByteArraySegment(io.pravega.common.util.CompositeByteArraySegment) DataLogCorruptedException(io.pravega.segmentstore.storage.DataLogCorruptedException) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BookKeeper(org.apache.bookkeeper.client.api.BookKeeper) Cleanup(lombok.Cleanup) Test(org.junit.Test)

Aggregations

DataLogCorruptedException (io.pravega.segmentstore.storage.DataLogCorruptedException)2 ObjectClosedException (io.pravega.common.ObjectClosedException)1 TimeoutTimer (io.pravega.common.TimeoutTimer)1 Timer (io.pravega.common.Timer)1 CompositeByteArraySegment (io.pravega.common.util.CompositeByteArraySegment)1 StreamingException (io.pravega.segmentstore.contracts.StreamingException)1 ContainerOfflineException (io.pravega.segmentstore.server.ContainerOfflineException)1 IllegalContainerStateException (io.pravega.segmentstore.server.IllegalContainerStateException)1 ServiceHaltException (io.pravega.segmentstore.server.ServiceHaltException)1 DataLogDisabledException (io.pravega.segmentstore.storage.DataLogDisabledException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 CompletionException (java.util.concurrent.CompletionException)1 Cleanup (lombok.Cleanup)1 SneakyThrows (lombok.SneakyThrows)1 lombok.val (lombok.val)1 BookKeeper (org.apache.bookkeeper.client.api.BookKeeper)1 Test (org.junit.Test)1