Search in sources :

Example 1 with DLIllegalStateException

use of org.apache.distributedlog.exceptions.DLIllegalStateException in project bookkeeper by apache.

the class DistributedLogAdmin method fixInprogressSegmentWithLowerSequenceNumber.

/**
 * Fix inprogress segment with lower ledger sequence number.
 *
 * @param namespace
 *          dl namespace
 * @param metadataUpdater
 *          metadata updater.
 * @param streamName
 *          stream name.
 * @param verbose
 *          print verbose messages.
 * @param interactive
 *          is confirmation needed before executing actual action.
 * @throws IOException
 */
public static void fixInprogressSegmentWithLowerSequenceNumber(final Namespace namespace, final MetadataUpdater metadataUpdater, final String streamName, final boolean verbose, final boolean interactive) throws Exception {
    DistributedLogManager dlm = namespace.openLog(streamName);
    try {
        List<LogSegmentMetadata> segments = dlm.getLogSegments();
        if (verbose) {
            System.out.println("LogSegments for " + streamName + " : ");
            for (LogSegmentMetadata segment : segments) {
                System.out.println(segment.getLogSegmentSequenceNumber() + "\t: " + segment);
            }
        }
        LOG.info("Get log segments for {} : {}", streamName, segments);
        // validate log segments
        long maxCompletedLogSegmentSequenceNumber = -1L;
        LogSegmentMetadata inprogressSegment = null;
        for (LogSegmentMetadata segment : segments) {
            if (!segment.isInProgress()) {
                maxCompletedLogSegmentSequenceNumber = Math.max(maxCompletedLogSegmentSequenceNumber, segment.getLogSegmentSequenceNumber());
            } else {
                // we already found an inprogress segment
                if (null != inprogressSegment) {
                    throw new DLIllegalStateException("Multiple inprogress segments found for stream " + streamName + " : " + segments);
                }
                inprogressSegment = segment;
            }
        }
        if (null == inprogressSegment || inprogressSegment.getLogSegmentSequenceNumber() > maxCompletedLogSegmentSequenceNumber) {
            // nothing to fix
            return;
        }
        final long newLogSegmentSequenceNumber = maxCompletedLogSegmentSequenceNumber + 1;
        if (interactive && !IOUtils.confirmPrompt("Confirm to fix (Y/N), Ctrl+C to break : ")) {
            return;
        }
        final LogSegmentMetadata newSegment = FutureUtils.result(metadataUpdater.changeSequenceNumber(inprogressSegment, newLogSegmentSequenceNumber));
        LOG.info("Fixed {} : {} -> {} ", new Object[] { streamName, inprogressSegment, newSegment });
        if (verbose) {
            System.out.println("Fixed " + streamName + " : " + inprogressSegment.getZNodeName() + " -> " + newSegment.getZNodeName());
            System.out.println("\t old: " + inprogressSegment);
            System.out.println("\t new: " + newSegment);
            System.out.println();
        }
    } finally {
        dlm.close();
    }
}
Also used : DistributedLogManager(org.apache.distributedlog.api.DistributedLogManager) LogSegmentMetadata(org.apache.distributedlog.LogSegmentMetadata) DLIllegalStateException(org.apache.distributedlog.exceptions.DLIllegalStateException)

Example 2 with DLIllegalStateException

use of org.apache.distributedlog.exceptions.DLIllegalStateException in project bookkeeper by apache.

the class BKLogWriteHandler method doCompleteAndCloseLogSegmentAfterLogSegmentListFetched.

private void doCompleteAndCloseLogSegmentAfterLogSegmentListFetched(final String inprogressZnodeName, long logSegmentSeqNo, long logSegmentId, long firstTxId, long lastTxId, int recordCount, long lastEntryId, long lastSlotId, final CompletableFuture<LogSegmentMetadata> promise) {
    try {
        lock.checkOwnershipAndReacquire();
    } catch (IOException ioe) {
        FutureUtils.completeExceptionally(promise, ioe);
        return;
    }
    LOG.debug("Completing and Closing Log Segment {} {}", firstTxId, lastTxId);
    LogSegmentMetadata inprogressLogSegment = readLogSegmentFromCache(inprogressZnodeName);
    // validate log segment
    if (inprogressLogSegment.getLogSegmentId() != logSegmentId) {
        FutureUtils.completeExceptionally(promise, new IOException("Active ledger has different ID to inprogress. " + inprogressLogSegment.getLogSegmentId() + " found, " + logSegmentId + " expected"));
        return;
    }
    // validate the transaction id
    if (inprogressLogSegment.getFirstTxId() != firstTxId) {
        FutureUtils.completeExceptionally(promise, new IOException("Transaction id not as expected, " + inprogressLogSegment.getFirstTxId() + " found, " + firstTxId + " expected"));
        return;
    }
    // validate the log sequence number
    if (validateLogSegmentSequenceNumber) {
        synchronized (inprogressLSSNs) {
            if (inprogressLSSNs.isEmpty()) {
                FutureUtils.completeExceptionally(promise, new UnexpectedException("Didn't find matched inprogress log segments when completing inprogress " + inprogressLogSegment));
                return;
            }
            long leastInprogressLSSN = inprogressLSSNs.getFirst();
            // tracked in {@link inprogressLSSNs}
            if ((inprogressLogSegment.getLogSegmentSequenceNumber() != logSegmentSeqNo) || (leastInprogressLSSN != logSegmentSeqNo)) {
                FutureUtils.completeExceptionally(promise, new UnexpectedException("Didn't find matched inprogress log segments when completing inprogress " + inprogressLogSegment));
                return;
            }
        }
    }
    // store max sequence number.
    long maxSeqNo = Math.max(logSegmentSeqNo, maxLogSegmentSequenceNo.getSequenceNumber());
    if (maxLogSegmentSequenceNo.getSequenceNumber() == logSegmentSeqNo || (maxLogSegmentSequenceNo.getSequenceNumber() == logSegmentSeqNo + 1)) {
        // ignore the case that a new inprogress log segment is pre-allocated
        // before completing current inprogress one
        LOG.info("Try storing max sequence number {} in completing {}.", new Object[] { logSegmentSeqNo, inprogressLogSegment.getZkPath() });
    } else {
        LOG.warn("Unexpected max ledger sequence number {} found while completing log segment {} for {}", new Object[] { maxLogSegmentSequenceNo.getSequenceNumber(), logSegmentSeqNo, getFullyQualifiedName() });
        if (validateLogSegmentSequenceNumber) {
            FutureUtils.completeExceptionally(promise, new DLIllegalStateException("Unexpected max log segment sequence number " + maxLogSegmentSequenceNo.getSequenceNumber() + " for " + getFullyQualifiedName() + ", expected " + (logSegmentSeqNo - 1)));
            return;
        }
    }
    // Prepare the completion
    final String pathForCompletedLedger = completedLedgerZNode(firstTxId, lastTxId, logSegmentSeqNo);
    long startSequenceId;
    try {
        startSequenceId = computeStartSequenceId(inprogressLogSegment);
    } catch (IOException ioe) {
        FutureUtils.completeExceptionally(promise, ioe);
        return;
    }
    // write completed ledger znode
    final LogSegmentMetadata completedLogSegment = inprogressLogSegment.completeLogSegment(pathForCompletedLedger, lastTxId, recordCount, lastEntryId, lastSlotId, startSequenceId);
    setLastLedgerRollingTimeMillis(completedLogSegment.getCompletionTime());
    // prepare the transaction
    Transaction<Object> txn = streamMetadataStore.newTransaction();
    // create completed log segment
    writeLogSegment(txn, completedLogSegment);
    // delete inprogress log segment
    deleteLogSegment(txn, inprogressLogSegment);
    // store max sequence number
    storeMaxSequenceNumber(txn, maxLogSegmentSequenceNo, maxSeqNo, false);
    // update max txn id.
    LOG.debug("Trying storing LastTxId in Finalize Path {} LastTxId {}", pathForCompletedLedger, lastTxId);
    storeMaxTxId(txn, maxTxId, lastTxId);
    txn.execute().whenCompleteAsync(new FutureEventListener<Void>() {

        @Override
        public void onSuccess(Void value) {
            LOG.info("Completed {} to {} for {} : {}", new Object[] { inprogressZnodeName, completedLogSegment.getSegmentName(), getFullyQualifiedName(), completedLogSegment });
            FutureUtils.complete(promise, completedLogSegment);
        }

        @Override
        public void onFailure(Throwable cause) {
            FutureUtils.completeExceptionally(promise, cause);
        }
    }, scheduler);
}
Also used : UnexpectedException(org.apache.distributedlog.exceptions.UnexpectedException) DLIllegalStateException(org.apache.distributedlog.exceptions.DLIllegalStateException) IOException(java.io.IOException)

Example 3 with DLIllegalStateException

use of org.apache.distributedlog.exceptions.DLIllegalStateException in project bookkeeper by apache.

the class TestAsyncReaderWriter method testReadBrokenEntriesWithGapDetection.

@Test(timeout = 60000)
public void testReadBrokenEntriesWithGapDetection() throws Exception {
    String name = runtime.getMethodName();
    DistributedLogConfiguration confLocal = new DistributedLogConfiguration();
    confLocal.loadConf(testConf);
    confLocal.setOutputBufferSize(0);
    confLocal.setPeriodicFlushFrequencyMilliSeconds(0);
    confLocal.setImmediateFlushEnabled(true);
    confLocal.setReadAheadWaitTime(10);
    confLocal.setReadAheadBatchSize(1);
    confLocal.setPositionGapDetectionEnabled(true);
    confLocal.setReadAheadSkipBrokenEntries(true);
    confLocal.setEIInjectReadAheadBrokenEntries(true);
    DistributedLogManager dlm = createNewDLM(confLocal, name);
    int numLogSegments = 1;
    int numRecordsPerLogSegment = 100;
    long txid = 1L;
    txid = writeRecords(dlm, numLogSegments, numRecordsPerLogSegment, txid, false);
    AsyncLogReader reader = dlm.getAsyncLogReader(DLSN.InvalidDLSN);
    try {
        // record in each ledger is discarded, for 30 - 3 = 27 records.
        for (int i = 0; i < 30; i++) {
            LogRecordWithDLSN record = Utils.ioResult(reader.readNext());
            assertFalse(record.getDlsn().getEntryId() % 10 == 0);
        }
        fail("should have thrown");
    } catch (DLIllegalStateException e) {
    }
    Utils.close(reader);
    dlm.close();
}
Also used : DynamicDistributedLogConfiguration(org.apache.distributedlog.config.DynamicDistributedLogConfiguration) AsyncLogReader(org.apache.distributedlog.api.AsyncLogReader) DistributedLogManager(org.apache.distributedlog.api.DistributedLogManager) DLIllegalStateException(org.apache.distributedlog.exceptions.DLIllegalStateException) Test(org.junit.Test)

Example 4 with DLIllegalStateException

use of org.apache.distributedlog.exceptions.DLIllegalStateException in project bookkeeper by apache.

the class TestZKTransaction method testAbortTransaction.

@Test(timeout = 60000)
public void testAbortTransaction() throws Exception {
    ZooKeeperClient zkc = mock(ZooKeeperClient.class);
    ZKTransaction transaction = new ZKTransaction(zkc);
    int numOps = 3;
    final CountDownLatch commitLatch = new CountDownLatch(numOps);
    final CountDownLatch abortLatch = new CountDownLatch(numOps);
    for (int i = 0; i < numOps; i++) {
        transaction.addOp(new CountDownZKOp(commitLatch, abortLatch));
    }
    transaction.abort(new DLIllegalStateException("Illegal State"));
    abortLatch.await();
    assertEquals(0, abortLatch.getCount());
    assertEquals(numOps, commitLatch.getCount());
}
Also used : ZooKeeperClient(org.apache.distributedlog.ZooKeeperClient) DLIllegalStateException(org.apache.distributedlog.exceptions.DLIllegalStateException) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 5 with DLIllegalStateException

use of org.apache.distributedlog.exceptions.DLIllegalStateException in project bookkeeper by apache.

the class BKLogWriteHandler method assignLogSegmentSequenceNumber.

protected long assignLogSegmentSequenceNumber() throws IOException {
    // For any active stream we will always make sure that there is at least one
    // active ledger (except when the stream first starts out). Therefore when we
    // see no ledger metadata for a stream, we assume that this is the first ledger
    // in the stream
    long logSegmentSeqNo = DistributedLogConstants.UNASSIGNED_LOGSEGMENT_SEQNO;
    boolean logSegmentsFound = false;
    if (LogSegmentMetadata.supportsLogSegmentSequenceNo(conf.getDLLedgerMetadataLayoutVersion())) {
        List<LogSegmentMetadata> ledgerListDesc = getCachedLogSegments(LogSegmentMetadata.DESC_COMPARATOR);
        Long nextLogSegmentSeqNo = DLUtils.nextLogSegmentSequenceNumber(ledgerListDesc);
        if (null == nextLogSegmentSeqNo) {
            logSegmentsFound = false;
            // we don't find last assigned log segment sequence number
            // then we start the log segment with configured FirstLogSegmentSequenceNumber.
            logSegmentSeqNo = conf.getFirstLogSegmentSequenceNumber();
        } else {
            logSegmentsFound = true;
            // latest log segment is assigned with a sequence number, start with next sequence number
            logSegmentSeqNo = nextLogSegmentSeqNo;
        }
    }
    // the maximum log segment sequence number is "UNASSIGNED".
    if (!logSegmentsFound && (DistributedLogConstants.UNASSIGNED_LOGSEGMENT_SEQNO == maxLogSegmentSequenceNo.getSequenceNumber())) {
        // no ledger seqno stored in /ledgers before
        LOG.info("No max ledger sequence number found while creating log segment {} for {}.", logSegmentSeqNo, getFullyQualifiedName());
    } else if (maxLogSegmentSequenceNo.getSequenceNumber() + 1 != logSegmentSeqNo) {
        LOG.warn("Unexpected max log segment sequence number {} for {} : list of cached segments = {}", new Object[] { maxLogSegmentSequenceNo.getSequenceNumber(), getFullyQualifiedName(), getCachedLogSegments(LogSegmentMetadata.DESC_COMPARATOR) });
        // there is max log segment number recorded there and it isn't match. throw exception.
        throw new DLIllegalStateException("Unexpected max log segment sequence number " + maxLogSegmentSequenceNo.getSequenceNumber() + " for " + getFullyQualifiedName() + ", expected " + (logSegmentSeqNo - 1));
    }
    return logSegmentSeqNo;
}
Also used : DLIllegalStateException(org.apache.distributedlog.exceptions.DLIllegalStateException)

Aggregations

DLIllegalStateException (org.apache.distributedlog.exceptions.DLIllegalStateException)12 DistributedLogManager (org.apache.distributedlog.api.DistributedLogManager)4 Test (org.junit.Test)4 IOException (java.io.IOException)3 AsyncLogReader (org.apache.distributedlog.api.AsyncLogReader)2 DLInterruptedException (org.apache.distributedlog.exceptions.DLInterruptedException)2 LogNotFoundException (org.apache.distributedlog.exceptions.LogNotFoundException)2 Stopwatch (com.google.common.base.Stopwatch)1 URI (java.net.URI)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 LogSegmentMetadata (org.apache.distributedlog.LogSegmentMetadata)1 ZooKeeperClient (org.apache.distributedlog.ZooKeeperClient)1 LogReader (org.apache.distributedlog.api.LogReader)1 Namespace (org.apache.distributedlog.api.namespace.Namespace)1 DynamicDistributedLogConfiguration (org.apache.distributedlog.config.DynamicDistributedLogConfiguration)1 BKTransmitException (org.apache.distributedlog.exceptions.BKTransmitException)1 EndOfLogSegmentException (org.apache.distributedlog.exceptions.EndOfLogSegmentException)1 EndOfStreamException (org.apache.distributedlog.exceptions.EndOfStreamException)1 LogReadException (org.apache.distributedlog.exceptions.LogReadException)1 UnexpectedException (org.apache.distributedlog.exceptions.UnexpectedException)1