@VisibleForTesting LogSegmentMetadata completeAndCloseLogSegment(long logSegmentSeqNo, long ledgerId, long firstTxId, long lastTxId, int recordCount) throws IOException { return completeAndCloseLogSegment(inprogressZNodeName(ledgerId, firstTxId, logSegmentSeqNo), logSegmentSeqNo, ledgerId, firstTxId, lastTxId, recordCount, -1, -1); }
/** * Finalize a log segment. If the journal manager is currently * writing to a ledger, ensure that this is the ledger of the log segment * being finalized. * <p/> * Otherwise this is the recovery case. In the recovery case, ensure that * the firstTxId of the ledger matches firstTxId for the segment we are * trying to finalize. */ Future<LogSegmentMetadata> completeAndCloseLogSegment(final BKLogSegmentWriter writer) { final Promise<LogSegmentMetadata> promise = new Promise<LogSegmentMetadata>(); completeAndCloseLogSegment(writer, promise); return promise; }
final Promise<Void> completePromise, final boolean shouldThrow) { writeHandler.completeAndCloseLogSegment(segmentWriter) .addEventListener(new FutureEventListener<LogSegmentMetadata>() { @Override
private Future<BKLogSegmentWriter> completeOldSegmentAndCacheNewLogSegmentWriter( BKLogSegmentWriter oldSegmentWriter, final BKLogSegmentWriter newSegmentWriter) { final Promise<BKLogSegmentWriter> completePromise = new Promise<BKLogSegmentWriter>(); // complete the old log segment writeHandler.completeAndCloseLogSegment(oldSegmentWriter) .addEventListener(new FutureEventListener<LogSegmentMetadata>() { @Override public void onSuccess(LogSegmentMetadata value) { cacheLogWriter(newSegmentWriter); removeAllocatedLogWriter(); FutureUtils.setValue(completePromise, newSegmentWriter); } @Override public void onFailure(Throwable cause) { FutureUtils.setException(completePromise, cause); } }); return completePromise; }
@Override public Future<BKLogSegmentWriter> apply(Void result) { removeCachedLogWriter(); if (ledgerWriter.isLogSegmentInError()) { return Future.value(null); } BKLogWriteHandler writeHandler; try { writeHandler = getWriteHandler(); } catch (IOException e) { return Future.exception(e); } if (null != writeHandler && forceRecovery) { return writeHandler.completeAndCloseLogSegment(ledgerWriter) .map(new AbstractFunction1<LogSegmentMetadata, BKLogSegmentWriter>() { @Override public BKLogSegmentWriter apply(LogSegmentMetadata completedLogSegment) { return null; } }); } else { return Future.value(null); } } });
private void prepareLogSegments(String name, int numSegments, int numEntriesPerSegment) throws Exception { DLMTestUtil.BKLogPartitionWriteHandlerAndClients bkdlmAndClients = createNewBKDLM(conf, name); long txid = 1; for (int sid = 0; sid < numSegments; ++sid) { BKLogSegmentWriter out = bkdlmAndClients.getWriteHandler().startLogSegment(txid); for (int eid = 0; eid < numEntriesPerSegment; ++eid) { LogRecord record = DLMTestUtil.getLargeLogRecordInstance(txid); out.write(record); ++txid; } FutureUtils.result(out.asyncClose()); bkdlmAndClients.getWriteHandler().completeAndCloseLogSegment( out.getLogSegmentSequenceNumber(), out.getLogSegmentId(), 1 + sid * numEntriesPerSegment, (sid + 1) * numEntriesPerSegment, numEntriesPerSegment); } bkdlmAndClients.close(); }
@Test(timeout = 60000) public void testRecoveryEmptyLedger() throws Exception { DLMTestUtil.BKLogPartitionWriteHandlerAndClients bkdlmAndClients = createNewBKDLM(conf, "distrlog-recovery-empty-ledger"); BKLogSegmentWriter out = bkdlmAndClients.getWriteHandler().startLogSegment(1); long txid = 1; for (long i = 1; i <= 100; i++) { LogRecord op = DLMTestUtil.getLogRecordInstance(txid++); out.write(op); if ((i % 10) == 0) { FutureUtils.result(out.flushAndCommit()); } } FutureUtils.result(out.flushAndCommit()); FutureUtils.result(out.asyncClose()); bkdlmAndClients.getWriteHandler().completeAndCloseLogSegment(out.getLogSegmentSequenceNumber(), out.getLogSegmentId(), 1, 100, 100); assertNotNull(zkc.exists(bkdlmAndClients.getWriteHandler().completedLedgerZNode(1, 100, out.getLogSegmentSequenceNumber()), false)); BKLogSegmentWriter outEmpty = bkdlmAndClients.getWriteHandler().startLogSegment(101); Abortables.abort(outEmpty, false); assertNull(zkc.exists(bkdlmAndClients.getWriteHandler().completedLedgerZNode(101, 101, outEmpty.getLogSegmentSequenceNumber()), false)); assertNotNull(zkc.exists(bkdlmAndClients.getWriteHandler().inprogressZNode(outEmpty.getLogSegmentId(), 101, outEmpty.getLogSegmentSequenceNumber()), false)); FutureUtils.result(bkdlmAndClients.getWriteHandler().recoverIncompleteLogSegments()); assertNull(zkc.exists(bkdlmAndClients.getWriteHandler().inprogressZNode(outEmpty.getLogSegmentId(), outEmpty.getLogSegmentSequenceNumber(), 101), false)); assertNotNull(zkc.exists(bkdlmAndClients.getWriteHandler().completedLedgerZNode(101, 101, outEmpty.getLogSegmentSequenceNumber()), false)); }
perStreamLogWriter.getLogSegmentSequenceNumber()), false)); BKLogSegmentWriter writer = blplm.startLogSegment(txid - 1); blplm.completeAndCloseLogSegment(writer.getLogSegmentSequenceNumber(), writer.getLogSegmentId(), txid - 1, txid - 1, 0); assertNotNull(
if (recordWrongLastDLSN) { FutureUtils.result(writer.asyncClose()); writeHandler.completeAndCloseLogSegment( writeHandler.inprogressZNodeName(writer.getLogSegmentId(), writer.getStartTxId(), writer.getLogSegmentSequenceNumber()), writer.getLogSegmentSequenceNumber(), wrongDLSN.getSlotId()); } else { FutureUtils.result(writeHandler.completeAndCloseLogSegment(writer));
FutureUtils.result(writeHandler.completeAndCloseLogSegment(writer));
writer.getLogSegmentSequenceNumber()), false)); BKLogSegmentWriter perStreamLogWriter = blplm.startLogSegment(txid - 1); blplm.completeAndCloseLogSegment(perStreamLogWriter.getLogSegmentSequenceNumber(), perStreamLogWriter.getLogSegmentId(), txid - 1, txid - 1, 0); assertNotNull(
writeHandler.completeAndCloseLogSegment( writeHandler.inprogressZNodeName(perStreamWriter.getLogSegmentId(), perStreamWriter.getStartTxId(), perStreamWriter.getLogSegmentSequenceNumber()), perStreamWriter.getLogSegmentSequenceNumber(),