use of org.apache.ignite.failure.FailureContext in project ignite by apache.
the class GridDhtTxPrepareFuture method onDone.
/**
* {@inheritDoc}
*/
@Override
public boolean onDone(GridNearTxPrepareResponse res0, Throwable err) {
try (TraceSurroundings ignored2 = MTC.support(span)) {
assert err != null || (initialized() && !hasPending()) : "On done called for prepare future that has " + "pending mini futures: " + this;
ERR_UPD.compareAndSet(this, null, err);
// Must clear prepare future before response is sent or listeners are notified.
if (tx.optimistic())
tx.clearPrepareFuture(this);
// Do not commit one-phase commit transaction if originating node has near cache enabled.
if (tx.commitOnPrepare()) {
assert last;
Throwable prepErr = this.err;
// Must create prepare response before transaction is committed to grab correct return value.
final GridNearTxPrepareResponse res = createPrepareResponse(prepErr);
onComplete(res);
if (tx.markFinalizing(IgniteInternalTx.FinalizationStatus.USER_FINISH)) {
CIX1<IgniteInternalFuture<IgniteInternalTx>> resClo = new CIX1<IgniteInternalFuture<IgniteInternalTx>>() {
@Override
public void applyx(IgniteInternalFuture<IgniteInternalTx> fut) {
if (res.error() == null && fut.error() != null)
res.error(fut.error());
if (REPLIED_UPD.compareAndSet(GridDhtTxPrepareFuture.this, 0, 1))
sendPrepareResponse(res);
}
};
try {
if (prepErr == null) {
try {
tx.commitAsync().listen(resClo);
} catch (Throwable e) {
res.error(e);
tx.systemInvalidate(true);
try {
tx.rollbackAsync().listen(resClo);
} catch (Throwable e1) {
e.addSuppressed(e1);
}
throw e;
}
} else if (!cctx.kernalContext().isStopping()) {
try {
tx.rollbackAsync().listen(resClo);
} catch (Throwable e) {
if (err != null)
err.addSuppressed(e);
throw err;
}
}
} catch (Throwable e) {
tx.logTxFinishErrorSafe(log, true, e);
cctx.kernalContext().failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
}
}
return true;
} else {
if (REPLIED_UPD.compareAndSet(this, 0, 1)) {
GridNearTxPrepareResponse res = createPrepareResponse(this.err);
// Will call super.onDone().
onComplete(res);
sendPrepareResponse(res);
return true;
} else {
// Other thread is completing future. Wait for it to complete.
try {
if (err != null)
get();
} catch (IgniteInterruptedException e) {
onError(new IgniteCheckedException("Got interrupted while waiting for replies to be sent.", e));
} catch (IgniteCheckedException ignored) {
// No-op, get() was just synchronization.
}
return false;
}
}
}
}
use of org.apache.ignite.failure.FailureContext in project ignite by apache.
the class PageMemoryImpl method allocatePage.
/**
* {@inheritDoc}
*/
@Override
public long allocatePage(int grpId, int partId, byte flags) throws IgniteCheckedException {
assert flags != PageIdAllocator.FLAG_IDX && partId <= PageIdAllocator.MAX_PARTITION_ID || flags == PageIdAllocator.FLAG_IDX && partId == PageIdAllocator.INDEX_PARTITION : "flags = " + flags + ", partId = " + partId;
assert started;
assert stateChecker.checkpointLockIsHeldByThread();
if (isThrottlingEnabled())
writeThrottle.onMarkDirty(false);
long pageId = pmPageMgr.allocatePage(grpId, partId, flags);
// it's crucial for tracking pages (zero page is super one)
assert PageIdUtils.pageIndex(pageId) > 0;
// We need to allocate page in memory for marking it dirty to save it in the next checkpoint.
// Otherwise it is possible that on file will be empty page which will be saved at snapshot and read with error
// because there is no crc inside them.
Segment seg = segment(grpId, pageId);
seg.writeLock().lock();
boolean isTrackingPage = changeTracker != null && PageIdUtils.pageIndex(trackingIO.trackingPageFor(pageId, realPageSize(grpId))) == PageIdUtils.pageIndex(pageId);
if (isTrackingPage && PageIdUtils.flag(pageId) == PageIdAllocator.FLAG_AUX)
pageId = PageIdUtils.pageId(PageIdUtils.partId(pageId), PageIdAllocator.FLAG_DATA, PageIdUtils.pageIndex(pageId));
FullPageId fullId = new FullPageId(pageId, grpId);
try {
long relPtr = seg.loadedPages.get(grpId, PageIdUtils.effectivePageId(pageId), seg.partGeneration(grpId, partId), INVALID_REL_PTR, OUTDATED_REL_PTR);
if (relPtr == OUTDATED_REL_PTR) {
relPtr = seg.refreshOutdatedPage(grpId, pageId, false);
seg.pageReplacementPolicy.onRemove(relPtr);
}
if (relPtr == INVALID_REL_PTR)
relPtr = seg.borrowOrAllocateFreePage(pageId);
if (relPtr == INVALID_REL_PTR)
relPtr = seg.removePageForReplacement();
long absPtr = seg.absolute(relPtr);
GridUnsafe.setMemory(absPtr + PAGE_OVERHEAD, pageSize(), (byte) 0);
PageHeader.fullPageId(absPtr, fullId);
PageHeader.writeTimestamp(absPtr, U.currentTimeMillis());
rwLock.init(absPtr + PAGE_LOCK_OFFSET, PageIdUtils.tag(pageId));
// TODO GG-11480
assert PageIO.getCrc(absPtr + PAGE_OVERHEAD) == 0;
assert !PageHeader.isAcquired(absPtr) : "Pin counter must be 0 for a new page [relPtr=" + U.hexLong(relPtr) + ", absPtr=" + U.hexLong(absPtr) + ", pinCntr=" + PageHeader.pinCount(absPtr) + ']';
setDirty(fullId, absPtr, true, true);
if (isTrackingPage) {
long pageAddr = absPtr + PAGE_OVERHEAD;
// We can modify page buffer directly.
if (PageIO.getType(pageAddr) == 0) {
PageMetrics metrics = dataRegionMetrics.cacheGrpPageMetrics(grpId);
trackingIO.initNewPage(pageAddr, pageId, realPageSize(grpId), metrics);
if (!ctx.wal().disabled(fullId.groupId())) {
if (!ctx.wal().isAlwaysWriteFullPages())
ctx.wal().log(new InitNewPageRecord(grpId, pageId, trackingIO.getType(), trackingIO.getVersion(), pageId));
else {
ctx.wal().log(new PageSnapshot(fullId, absPtr + PAGE_OVERHEAD, pageSize(), realPageSize(fullId.groupId())));
}
}
}
}
seg.pageReplacementPolicy.onMiss(relPtr);
seg.loadedPages.put(grpId, PageIdUtils.effectivePageId(pageId), relPtr, seg.partGeneration(grpId, partId));
} catch (IgniteOutOfMemoryException oom) {
DataRegionConfiguration dataRegionCfg = getDataRegionConfiguration();
IgniteOutOfMemoryException e = new IgniteOutOfMemoryException("Out of memory in data region [" + "name=" + dataRegionCfg.getName() + ", initSize=" + U.readableSize(dataRegionCfg.getInitialSize(), false) + ", maxSize=" + U.readableSize(dataRegionCfg.getMaxSize(), false) + ", persistenceEnabled=" + dataRegionCfg.isPersistenceEnabled() + "] Try the following:" + U.nl() + " ^-- Increase maximum off-heap memory size (DataRegionConfiguration.maxSize)" + U.nl() + " ^-- Enable eviction or expiration policies");
e.initCause(oom);
ctx.kernalContext().failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
throw e;
} finally {
seg.writeLock().unlock();
}
// Finish replacement only when an exception wasn't thrown otherwise it possible to corrupt B+Tree.
if (delayedPageReplacementTracker != null)
delayedPageReplacementTracker.delayedPageWrite().finishReplacement();
// we have allocated 'tracking' page, we need to allocate regular one
return isTrackingPage ? allocatePage(grpId, partId, flags) : pageId;
}
use of org.apache.ignite.failure.FailureContext in project ignite by apache.
the class PageMemoryImpl method acquirePage.
/**
* @param grpId Group id.
* @param pageId Page id.
* @param statHolder Stat holder.
* @param restore Restore.
* @param pageAllocated Page allocated.
*/
private long acquirePage(int grpId, long pageId, IoStatisticsHolder statHolder, boolean restore, @Nullable AtomicBoolean pageAllocated) throws IgniteCheckedException {
assert started;
int partId = PageIdUtils.partId(pageId);
Segment seg = segment(grpId, pageId);
seg.readLock().lock();
try {
long relPtr = seg.loadedPages.get(grpId, PageIdUtils.effectivePageId(pageId), seg.partGeneration(grpId, partId), INVALID_REL_PTR, INVALID_REL_PTR);
// The page is loaded to the memory.
if (relPtr != INVALID_REL_PTR) {
long absPtr = seg.absolute(relPtr);
seg.acquirePage(absPtr);
seg.pageReplacementPolicy.onHit(relPtr);
statHolder.trackLogicalRead(absPtr + PAGE_OVERHEAD);
return absPtr;
}
} finally {
seg.readLock().unlock();
}
FullPageId fullId = new FullPageId(pageId, grpId);
seg.writeLock().lock();
long lockedPageAbsPtr = -1;
boolean readPageFromStore = false;
try {
// Double-check.
long relPtr = seg.loadedPages.get(grpId, fullId.effectivePageId(), seg.partGeneration(grpId, partId), INVALID_REL_PTR, OUTDATED_REL_PTR);
long absPtr;
if (relPtr == INVALID_REL_PTR) {
relPtr = seg.borrowOrAllocateFreePage(pageId);
if (pageAllocated != null)
pageAllocated.set(true);
if (relPtr == INVALID_REL_PTR)
relPtr = seg.removePageForReplacement();
absPtr = seg.absolute(relPtr);
PageHeader.fullPageId(absPtr, fullId);
PageHeader.writeTimestamp(absPtr, U.currentTimeMillis());
assert !PageHeader.isAcquired(absPtr) : "Pin counter must be 0 for a new page [relPtr=" + U.hexLong(relPtr) + ", absPtr=" + U.hexLong(absPtr) + ']';
// We can clear dirty flag after the page has been allocated.
setDirty(fullId, absPtr, false, false);
seg.pageReplacementPolicy.onMiss(relPtr);
seg.loadedPages.put(grpId, fullId.effectivePageId(), relPtr, seg.partGeneration(grpId, partId));
long pageAddr = absPtr + PAGE_OVERHEAD;
if (!restore) {
if (delayedPageReplacementTracker != null)
delayedPageReplacementTracker.waitUnlock(fullId);
readPageFromStore = true;
} else {
GridUnsafe.setMemory(absPtr + PAGE_OVERHEAD, pageSize(), (byte) 0);
// Must init page ID in order to ensure RWLock tag consistency.
PageIO.setPageId(pageAddr, pageId);
}
rwLock.init(absPtr + PAGE_LOCK_OFFSET, PageIdUtils.tag(pageId));
if (readPageFromStore) {
boolean locked = rwLock.writeLock(absPtr + PAGE_LOCK_OFFSET, OffheapReadWriteLock.TAG_LOCK_ALWAYS);
assert locked : "Page ID " + fullId + " expected to be locked";
lockedPageAbsPtr = absPtr;
}
} else if (relPtr == OUTDATED_REL_PTR) {
assert PageIdUtils.pageIndex(pageId) == 0 : fullId;
relPtr = seg.refreshOutdatedPage(grpId, pageId, false);
absPtr = seg.absolute(relPtr);
long pageAddr = absPtr + PAGE_OVERHEAD;
GridUnsafe.setMemory(pageAddr, pageSize(), (byte) 0);
PageHeader.fullPageId(absPtr, fullId);
PageHeader.writeTimestamp(absPtr, U.currentTimeMillis());
PageIO.setPageId(pageAddr, pageId);
assert !PageHeader.isAcquired(absPtr) : "Pin counter must be 0 for a new page [relPtr=" + U.hexLong(relPtr) + ", absPtr=" + U.hexLong(absPtr) + ']';
rwLock.init(absPtr + PAGE_LOCK_OFFSET, PageIdUtils.tag(pageId));
seg.pageReplacementPolicy.onRemove(relPtr);
seg.pageReplacementPolicy.onMiss(relPtr);
} else {
absPtr = seg.absolute(relPtr);
seg.pageReplacementPolicy.onHit(relPtr);
}
seg.acquirePage(absPtr);
if (!readPageFromStore)
statHolder.trackLogicalRead(absPtr + PAGE_OVERHEAD);
return absPtr;
} catch (IgniteOutOfMemoryException oom) {
ctx.kernalContext().failure().process(new FailureContext(FailureType.CRITICAL_ERROR, oom));
throw oom;
} finally {
seg.writeLock().unlock();
if (delayedPageReplacementTracker != null)
delayedPageReplacementTracker.delayedPageWrite().finishReplacement();
if (readPageFromStore) {
assert lockedPageAbsPtr != -1 : "Page is expected to have a valid address [pageId=" + fullId + ", lockedPageAbsPtr=" + U.hexLong(lockedPageAbsPtr) + ']';
assert isPageWriteLocked(lockedPageAbsPtr) : "Page is expected to be locked: [pageId=" + fullId + "]";
long pageAddr = lockedPageAbsPtr + PAGE_OVERHEAD;
ByteBuffer buf = wrapPointer(pageAddr, pageSize());
long actualPageId = 0;
try {
pmPageMgr.read(grpId, pageId, buf, false);
statHolder.trackPhysicalAndLogicalRead(pageAddr);
actualPageId = PageIO.getPageId(buf);
dataRegionMetrics.onPageRead();
if (PageIO.isIndexPage(PageIO.getType(buf)))
dataRegionMetrics.cacheGrpPageMetrics(grpId).indexPages().increment();
} catch (IgniteDataIntegrityViolationException e) {
U.warn(log, "Failed to read page (data integrity violation encountered, will try to " + "restore using existing WAL) [fullPageId=" + fullId + ']', e);
buf.rewind();
tryToRestorePage(fullId, buf);
// Mark the page as dirty because it has been restored.
setDirty(fullId, lockedPageAbsPtr, true, false);
// And save the page snapshot in the WAL.
beforeReleaseWrite(fullId, pageAddr, true);
statHolder.trackPhysicalAndLogicalRead(pageAddr);
dataRegionMetrics.onPageRead();
} finally {
rwLock.writeUnlock(lockedPageAbsPtr + PAGE_LOCK_OFFSET, actualPageId == 0 ? OffheapReadWriteLock.TAG_LOCK_ALWAYS : PageIdUtils.tag(actualPageId));
}
}
}
}
use of org.apache.ignite.failure.FailureContext in project ignite by apache.
the class PageReadWriteManagerImpl method write.
/**
* {@inheritDoc}
*/
@Override
public PageStore write(int grpId, long pageId, ByteBuffer pageBuf, int tag, boolean calculateCrc) throws IgniteCheckedException {
int partId = PageIdUtils.partId(pageId);
PageStore store = pageStores.getStore(grpId, partId);
try {
int pageSize = store.getPageSize();
int compressedPageSize = pageSize;
GridCacheContext<?, ?> cctx0 = ctx.cache().context().cacheContext(grpId);
if (cctx0 != null) {
assert pageBuf.position() == 0 && pageBuf.limit() == pageSize : pageBuf;
ByteBuffer compressedPageBuf = cctx0.compress().compressPage(pageBuf, store);
if (compressedPageBuf != pageBuf) {
compressedPageSize = PageIO.getCompressedSize(compressedPageBuf);
if (!calculateCrc) {
calculateCrc = true;
// It will be recalculated over compressed data further.
PageIO.setCrc(compressedPageBuf, 0);
}
// It is expected to be reset to 0 after each write.
PageIO.setCrc(pageBuf, 0);
pageBuf = compressedPageBuf;
}
}
store.write(pageId, pageBuf, tag, calculateCrc);
if (pageSize > compressedPageSize)
// TODO maybe add async punch mode?
store.punchHole(pageId, compressedPageSize);
} catch (StorageException e) {
ctx.failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
throw e;
}
return store;
}
use of org.apache.ignite.failure.FailureContext in project ignite by apache.
the class PageReadWriteManagerImpl method read.
/**
* {@inheritDoc}
*/
@Override
public void read(int grpId, long pageId, ByteBuffer pageBuf, boolean keepCrc) throws IgniteCheckedException {
PageStore store = pageStores.getStore(grpId, PageIdUtils.partId(pageId));
try {
store.read(pageId, pageBuf, keepCrc);
ctx.compress().decompressPage(pageBuf, store.getPageSize());
} catch (StorageException e) {
ctx.failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
throw e;
}
}
Aggregations