Search in sources :

Example 11 with FailureContext

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;
            }
        }
    }
}
Also used : CIX1(org.apache.ignite.internal.util.typedef.CIX1) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteInternalTx(org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx) FailureContext(org.apache.ignite.failure.FailureContext) GridNearTxPrepareResponse(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse) IgniteInterruptedException(org.apache.ignite.IgniteInterruptedException) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) TraceSurroundings(org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings)

Example 12 with FailureContext

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;
}
Also used : DataRegionConfiguration(org.apache.ignite.configuration.DataRegionConfiguration) IgniteOutOfMemoryException(org.apache.ignite.internal.mem.IgniteOutOfMemoryException) FailureContext(org.apache.ignite.failure.FailureContext) InitNewPageRecord(org.apache.ignite.internal.pagemem.wal.record.delta.InitNewPageRecord) FullPageId(org.apache.ignite.internal.pagemem.FullPageId) PageSnapshot(org.apache.ignite.internal.pagemem.wal.record.PageSnapshot)

Example 13 with FailureContext

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));
            }
        }
    }
}
Also used : IgniteDataIntegrityViolationException(org.apache.ignite.internal.processors.cache.persistence.wal.crc.IgniteDataIntegrityViolationException) IgniteOutOfMemoryException(org.apache.ignite.internal.mem.IgniteOutOfMemoryException) FailureContext(org.apache.ignite.failure.FailureContext) ByteBuffer(java.nio.ByteBuffer) FullPageId(org.apache.ignite.internal.pagemem.FullPageId)

Example 14 with FailureContext

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;
}
Also used : FailureContext(org.apache.ignite.failure.FailureContext) PageStore(org.apache.ignite.internal.pagemem.store.PageStore) ByteBuffer(java.nio.ByteBuffer) StorageException(org.apache.ignite.internal.processors.cache.persistence.StorageException)

Example 15 with FailureContext

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;
    }
}
Also used : FailureContext(org.apache.ignite.failure.FailureContext) PageStore(org.apache.ignite.internal.pagemem.store.PageStore) StorageException(org.apache.ignite.internal.processors.cache.persistence.StorageException)

Aggregations

FailureContext (org.apache.ignite.failure.FailureContext)54 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)20 IgniteConfiguration (org.apache.ignite.configuration.IgniteConfiguration)13 Ignite (org.apache.ignite.Ignite)11 IOException (java.io.IOException)9 AbstractFailureHandler (org.apache.ignite.failure.AbstractFailureHandler)9 IgniteEx (org.apache.ignite.internal.IgniteEx)9 GridCommonAbstractTest (org.apache.ignite.testframework.junits.common.GridCommonAbstractTest)9 Test (org.junit.Test)9 IgniteException (org.apache.ignite.IgniteException)8 File (java.io.File)6 DataRegionConfiguration (org.apache.ignite.configuration.DataRegionConfiguration)6 StorageException (org.apache.ignite.internal.processors.cache.persistence.StorageException)6 LogListener (org.apache.ignite.testframework.LogListener)5 WithSystemProperty (org.apache.ignite.testframework.junits.WithSystemProperty)4 ByteBuffer (java.nio.ByteBuffer)3 UUID (java.util.UUID)3 DataStorageConfiguration (org.apache.ignite.configuration.DataStorageConfiguration)3 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)3 IgniteInterruptedCheckedException (org.apache.ignite.internal.IgniteInterruptedCheckedException)3