use of org.apache.ignite.internal.processors.cache.persistence.wal.filehandle.FileWriteHandle in project ignite by apache.
the class FileWriteAheadLogManager method rollOver.
/**
* @param cur Handle that failed to fit the given entry.
* @param rec Optional record to be added right after header.
* @return Handle that will fit the entry.
*/
private FileWriteHandle rollOver(FileWriteHandle cur, @Nullable WALRecord rec) throws IgniteCheckedException {
FileWriteHandle hnd = currentHandle();
if (hnd != cur)
return hnd;
if (hnd.close(true)) {
if (metrics.metricsEnabled())
metrics.onWallRollOver();
if (switchSegmentRecordOffset != null) {
int idx = (int) (cur.getSegmentId() % dsCfg.getWalSegments());
switchSegmentRecordOffset.set(idx, hnd.getSwitchSegmentRecordOffset());
}
long idx = cur.getSegmentId() + 1;
long currSize = 0;
long reservedSize = maxWalSegmentSize;
if (archiver == null)
segmentAware.addSize(idx, reservedSize);
FileWriteHandle next;
try {
try {
next = initNextWriteHandle(cur);
} catch (IgniteCheckedException e) {
// Allow to avoid forever waiting in other threads.
cur.signalNextAvailable();
throw e;
}
if (rec != null) {
WALPointer ptr = next.addRecord(rec);
assert ptr != null;
}
currSize = reservedSize;
segmentSize.put(idx, currSize);
} finally {
if (archiver == null)
segmentAware.addSize(idx, currSize - reservedSize);
}
if (next.getSegmentId() - lastCheckpointPtr.index() >= maxSegCountWithoutCheckpoint)
cctx.database().forceCheckpoint("too big size of WAL without checkpoint");
boolean updated = updateCurrentHandle(next, hnd);
assert updated : "Concurrent updates on rollover are not allowed";
if (walAutoArchiveAfterInactivity > 0 || walForceArchiveTimeout > 0) {
lastRecordLoggedMs.set(0);
if (walForceArchiveTimeout > 0)
lastDataRecordLoggedMs.set(0);
}
// Let other threads to proceed with new segment.
hnd.signalNextAvailable();
} else
hnd.awaitNext();
return currentHandle();
}
use of org.apache.ignite.internal.processors.cache.persistence.wal.filehandle.FileWriteHandle in project ignite by apache.
the class FileWriteAheadLogManager method replay.
/**
* {@inheritDoc}
*/
@Override
public WALIterator replay(WALPointer start, @Nullable IgniteBiPredicate<WALRecord.RecordType, WALPointer> recordDeserializeFilter) throws IgniteCheckedException, StorageException {
FileWriteHandle hnd = currentHandle();
WALPointer end = null;
if (hnd != null)
end = hnd.position();
RecordsIterator iter = new RecordsIterator(cctx, walArchiveDir, walWorkDir, start, end, dsCfg, new RecordSerializerFactoryImpl(cctx).recordDeserializeFilter(recordDeserializeFilter), ioFactory, archiver, decompressor, log, segmentAware, segmentRouter, lockedSegmentFileInputFactory);
try {
// Make sure iterator is closed on any error.
iter.init();
} catch (Throwable t) {
iter.close();
throw t;
}
return iter;
}
use of org.apache.ignite.internal.processors.cache.persistence.wal.filehandle.FileWriteHandle in project ignite by apache.
the class FileWriteAheadLogManager method closeBufAndRollover.
/**
*/
private FileWriteHandle closeBufAndRollover(FileWriteHandle currWriteHandle, @Nullable WALRecord rec, RolloverType rolloverType) throws IgniteCheckedException {
long idx = currWriteHandle.getSegmentId();
currWriteHandle.closeBuffer();
FileWriteHandle res = rollOver(currWriteHandle, rolloverType == RolloverType.NEXT_SEGMENT ? rec : null);
if (log != null && log.isInfoEnabled()) {
log.info("Rollover segment [" + idx + " to " + res.getSegmentId() + "], recordType=" + (rec == null ? null : rec.type()));
}
return res;
}
use of org.apache.ignite.internal.processors.cache.persistence.wal.filehandle.FileWriteHandle in project ignite by apache.
the class FileWriteAheadLogManager method log.
/**
* {@inheritDoc}
*/
@Override
public WALPointer log(WALRecord rec, RolloverType rolloverType) throws IgniteCheckedException {
if (serializer == null || mode == WALMode.NONE)
return null;
// Only delta-records, page snapshots and memory recovery are allowed to write in recovery mode.
if (cctx.kernalContext().recoveryMode() && !(rec instanceof PageDeltaRecord || rec instanceof PageSnapshot || rec instanceof MemoryRecoveryRecord))
return null;
FileWriteHandle currWrHandle = currentHandle();
WALDisableContext isDisable = walDisableContext;
// Logging was not resumed yet.
if (currWrHandle == null || (isDisable != null && isDisable.check()))
return null;
// Do page snapshots compression if configured.
if (pageCompression != DiskPageCompression.DISABLED && rec instanceof PageSnapshot) {
PageSnapshot pageSnapshot = (PageSnapshot) rec;
int pageSize = pageSnapshot.realPageSize();
ByteBuffer pageData = pageSnapshot.pageDataBuffer();
ByteBuffer compressedPage = cctx.kernalContext().compress().compressPage(pageData, pageSize, 1, pageCompression, pageCompressionLevel);
if (compressedPage != pageData) {
assert compressedPage.isDirect() : "Is direct buffer: " + compressedPage.isDirect();
rec = new PageSnapshot(pageSnapshot.fullPageId(), GridUnsafe.bufferAddress(compressedPage), compressedPage.limit(), pageSize);
}
}
// Need to calculate record size first.
rec.size(serializer.size(rec));
while (true) {
WALPointer ptr;
if (rolloverType == RolloverType.NONE)
ptr = currWrHandle.addRecord(rec);
else {
assert cctx.database().checkpointLockIsHeldByThread();
if (rolloverType == RolloverType.NEXT_SEGMENT) {
WALPointer pos = rec.position();
do {
// This will change rec.position() unless concurrent rollover happened.
currWrHandle = closeBufAndRollover(currWrHandle, rec, rolloverType);
} while (Objects.equals(pos, rec.position()));
ptr = rec.position();
} else if (rolloverType == RolloverType.CURRENT_SEGMENT) {
if ((ptr = currWrHandle.addRecord(rec)) != null)
currWrHandle = closeBufAndRollover(currWrHandle, rec, rolloverType);
} else
throw new IgniteCheckedException("Unknown rollover type: " + rolloverType);
}
if (ptr != null) {
metrics.onWalRecordLogged(rec.size());
if (walAutoArchiveAfterInactivity > 0 || walForceArchiveTimeout > 0) {
long millis = U.currentTimeMillis();
lastRecordLoggedMs.set(millis);
// No need to forcefully rollover for other record types.
if (walForceArchiveTimeout > 0 && rec.type() == DATA_RECORD_V2)
lastDataRecordLoggedMs.set(millis);
}
return ptr;
} else
currWrHandle = rollOver(currWrHandle, null);
checkNode();
if (isStopping())
throw new IgniteCheckedException("Stopping.");
}
}
use of org.apache.ignite.internal.processors.cache.persistence.wal.filehandle.FileWriteHandle in project ignite by apache.
the class FileWriteAheadLogManager method initNextWriteHandle.
/**
* Fills the file header for a new segment. Calling this method signals we are done with the segment and it can be
* archived. If we don't have prepared file yet and achiever is busy this method blocks.
*
* @param cur Current file write handle released by WAL writer.
* @return Initialized file handle.
* @throws IgniteCheckedException If exception occurred.
*/
private FileWriteHandle initNextWriteHandle(FileWriteHandle cur) throws IgniteCheckedException {
IgniteCheckedException error = null;
try {
File nextFile = pollNextFile(cur.getSegmentId());
if (log.isDebugEnabled())
log.debug("Switching to a new WAL segment: " + nextFile.getAbsolutePath());
SegmentIO fileIO = null;
FileWriteHandle hnd;
boolean interrupted = false;
if (switchSegmentRecordOffset != null)
switchSegmentRecordOffset.set((int) ((cur.getSegmentId() + 1) % dsCfg.getWalSegments()), 0);
while (true) {
try {
fileIO = new SegmentIO(cur.getSegmentId() + 1, ioFactory.create(nextFile));
IgniteInClosure<FileIO> lsnr = createWalFileListener;
if (lsnr != null)
lsnr.apply(fileIO);
hnd = fileHandleManager.nextHandle(fileIO, serializer);
if (interrupted)
Thread.currentThread().interrupt();
break;
} catch (ClosedByInterruptException ignore) {
interrupted = true;
Thread.interrupted();
if (fileIO != null) {
try {
fileIO.close();
} catch (IOException ignored) {
// No-op.
}
fileIO = null;
}
}
}
hnd.writeHeader();
return hnd;
} catch (IgniteCheckedException e) {
throw error = e;
} catch (IOException e) {
throw error = new StorageException("Unable to initialize WAL segment", e);
} finally {
if (error != null)
cctx.kernalContext().failure().process(new FailureContext(CRITICAL_ERROR, error));
}
}
Aggregations