Search in sources :

Example 1 with DataPageIO

use of org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO in project ignite by apache.

the class CacheDataTree method scanDataPages.

/**
 * @param rowData Required row data.
 * @param c Optional MVCC closure.
 * @return Cache row cursor.
 * @throws IgniteCheckedException If failed.
 */
private GridCursor<CacheDataRow> scanDataPages(CacheDataRowAdapter.RowData rowData, MvccDataPageClosure c) throws IgniteCheckedException {
    lastFindWithDataPageScan = TRUE;
    checkDestroyed();
    assert rowData != null;
    assert grp.persistenceEnabled();
    int partId = rowStore.getPartitionId();
    GridCacheSharedContext shared = grp.shared();
    GridCacheDatabaseSharedManager db = (GridCacheDatabaseSharedManager) shared.database();
    PageStore pageStore = db.getPageStore(grpId, partId);
    boolean mvccEnabled = grp.mvccEnabled();
    int pageSize = pageSize();
    long startPageId = ((PageMemoryEx) pageMem).partitionMetaPageId(grp.groupId(), partId);
    /**
     */
    final class DataPageScanCursor implements GridCursor<CacheDataRow> {

        /**
         */
        int pagesCnt = pageStore.pages();

        /**
         */
        int curPage = -1;

        /**
         */
        CacheDataRow[] rows = EMPTY_ROWS;

        /**
         */
        int curRow = -1;

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean next() throws IgniteCheckedException {
            if (rows == null)
                return false;
            if (++curRow < rows.length && rows[curRow] != null)
                return true;
            return readNextDataPage();
        }

        /**
         * @return {@code true} If new rows were fetched.
         * @throws IgniteCheckedException If failed.
         */
        private boolean readNextDataPage() throws IgniteCheckedException {
            checkDestroyed();
            for (; ; ) {
                if (++curPage >= pagesCnt) {
                    // Reread number of pages when we reach it (it may grow).
                    int newPagesCnt = pageStore.pages();
                    if (newPagesCnt <= pagesCnt) {
                        rows = null;
                        return false;
                    }
                    pagesCnt = newPagesCnt;
                }
                long pageId = startPageId + curPage;
                long page = pageMem.acquirePage(grpId, pageId);
                try {
                    boolean skipVer = CacheDataRowStore.getSkipVersion();
                    long pageAddr = ((PageMemoryEx) pageMem).readLock(page, pageId, true, false);
                    try {
                        // Here we should also exclude fragmented pages that don't contain the head of the entry.
                        if (PageIO.getType(pageAddr) != T_DATA)
                            // Not a data page.
                            continue;
                        DataPageIO io = PageIO.getPageIO(T_DATA, PageIO.getVersion(pageAddr));
                        int rowsCnt = io.getRowsCount(pageAddr);
                        if (rowsCnt == 0)
                            // Empty page.
                            continue;
                        if (rowsCnt > rows.length)
                            rows = new CacheDataRow[rowsCnt];
                        else
                            clearTail(rows, rowsCnt);
                        int r = 0;
                        for (int i = 0; i < rowsCnt; i++) {
                            if (c == null || c.applyMvcc(io, pageAddr, i, pageSize)) {
                                DataRow row = mvccEnabled ? new MvccDataRow() : new DataRow();
                                row.initFromDataPage(io, pageAddr, i, grp, shared, pageMem, rowData, skipVer);
                                rows[r++] = row;
                            }
                        }
                        if (r == 0)
                            // No rows fetched in this page.
                            continue;
                        curRow = 0;
                        return true;
                    } finally {
                        pageMem.readUnlock(grpId, pageId, page);
                    }
                } finally {
                    pageMem.releasePage(grpId, pageId, page);
                }
            }
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public CacheDataRow get() {
            return rows[curRow];
        }
    }
    return new DataPageScanCursor();
}
Also used : DataPageIO(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO) CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) GridCursor(org.apache.ignite.internal.util.lang.GridCursor) GridCacheDatabaseSharedManager(org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager) PageStore(org.apache.ignite.internal.pagemem.store.PageStore) MvccDataRow(org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataRow) GridCacheSharedContext(org.apache.ignite.internal.processors.cache.GridCacheSharedContext) CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) MvccDataRow(org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataRow) PageMemoryEx(org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx)

Example 2 with DataPageIO

use of org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO in project ignite by apache.

the class DataPageMvccMarkUpdatedRecord method applyDelta.

/**
 * {@inheritDoc}
 */
@Override
public void applyDelta(PageMemory pageMem, long pageAddr) throws IgniteCheckedException {
    DataPageIO io = PageIO.getPageIO(pageAddr);
    io.updateNewVersion(pageAddr, itemId, pageMem.realPageSize(groupId()), newMvccCrd, newMvccCntr, newMvccOpCntr);
}
Also used : DataPageIO(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO)

Example 3 with DataPageIO

use of org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO in project ignite by apache.

the class DataPageMvccUpdateTxStateHintRecord method applyDelta.

/**
 * {@inheritDoc}
 */
@Override
public void applyDelta(PageMemory pageMem, long pageAddr) throws IgniteCheckedException {
    DataPageIO io = PageIO.getPageIO(pageAddr);
    io.updateTxState(pageAddr, itemId, pageMem.realPageSize(groupId()), txState);
}
Also used : DataPageIO(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO)

Example 4 with DataPageIO

use of org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO in project ignite by apache.

the class CorruptedTreeFailureHandlingTest method testCorruptedPage.

/**
 * Check that if a corrupted page exists, an {@link CorruptedTreeException}
 * will be thrown and a diagnostic file will be generated.
 *
 * @throws Exception If failed.
 */
@Test
public void testCorruptedPage() throws Exception {
    IgniteEx srv = startGrid(0);
    File diagnosticDir = new File(srv.context().config().getWorkDirectory(), "diagnostic");
    FileUtils.deleteDirectory(diagnosticDir);
    srv.cluster().state(ClusterState.ACTIVE);
    IgniteCache<Integer, Integer> cache = srv.getOrCreateCache(DEFAULT_CACHE_NAME);
    for (int i = 0; i < 10; i++) cache.put(i, i);
    int pageSize = srv.configuration().getDataStorageConfiguration().getPageSize();
    int grpId = srv.context().cache().cacheGroups().stream().filter(context -> context.cacheOrGroupName().equals(DEFAULT_CACHE_NAME)).findAny().orElseThrow(() -> new RuntimeException("Cache group not found")).groupId();
    stopGrid(0, false);
    // Node is stopped, we're ready to corrupt partition data.
    long link = linkRef.get();
    long pageId = PageIdUtils.pageId(link);
    int itemId = PageIdUtils.itemId(link);
    ByteBuffer pageBuf = ByteBuffer.allocateDirect(pageSize);
    OpenOption[] options = { StandardOpenOption.READ, StandardOpenOption.WRITE };
    try (RandomAccessFileIO fileIO = new RandomAccessFileIO(fileRef.get(), options)) {
        DataPageIO dataPageIO = DataPageIO.VERSIONS.latest();
        long pageOff = pageSize + PageIdUtils.pageIndex(pageId) * pageSize;
        // Read index page.
        fileIO.position(pageOff);
        fileIO.readFully(pageBuf);
        long pageAddr = GridUnsafe.bufferAddress(pageBuf);
        // Remove existing item from index page.
        dataPageIO.removeRow(pageAddr, itemId, pageSize);
        // Recalculate CRC.
        PageIO.setCrc(pageAddr, 0);
        pageBuf.rewind();
        PageIO.setCrc(pageAddr, FastCrc.calcCrc(pageBuf, pageSize));
        // Write it back.
        pageBuf.rewind();
        fileIO.position(pageOff);
        fileIO.writeFully(pageBuf);
    }
    LogListener logLsnr = LogListener.matches("CorruptedTreeException has occurred. " + "To diagnose it, make a backup of the following directories: ").build();
    srv = startGrid(0, cfg -> {
        cfg.setGridLogger(new ListeningTestLogger(cfg.getGridLogger(), logLsnr));
    });
    // Add modified page to WAL so it won't be restored to previous (valid) state.
    pageBuf.rewind();
    ByteBuffer cpBuf = ByteBuffer.allocate(pageBuf.capacity());
    cpBuf.put(pageBuf);
    PageSnapshot pageSnapshot = new PageSnapshot(new FullPageId(pageId, grpId), cpBuf.array(), pageSize);
    srv.context().cache().context().wal().log(pageSnapshot);
    // Access cache.
    cache = srv.cache(DEFAULT_CACHE_NAME);
    try {
        for (int i = 0; i < CACHE_ENTRIES; i++) cache.get(i);
        fail("Cache operations are expected to fail");
    } catch (Throwable e) {
        assertTrue(X.hasCause(e, CorruptedTreeException.class));
    }
    assertTrue(GridTestUtils.waitForCondition(() -> G.allGrids().isEmpty(), 10_000L));
    assertTrue(diagnosticDir.exists());
    assertTrue(diagnosticDir.isDirectory());
    Pattern corruptedPagesFileNamePtrn = corruptedPagesFileNamePattern();
    File[] txtFiles = diagnosticDir.listFiles((dir, name) -> corruptedPagesFileNamePtrn.matcher(name).matches());
    assertFalse(F.isEmpty(txtFiles));
    assertEquals(1, txtFiles.length);
    assertTrue(logLsnr.check());
}
Also used : CacheAtomicityMode(org.apache.ignite.cache.CacheAtomicityMode) ListeningTestLogger(org.apache.ignite.testframework.ListeningTestLogger) LogListener(org.apache.ignite.testframework.LogListener) FullPageId(org.apache.ignite.internal.pagemem.FullPageId) RandomAccessFileIO(org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIO) ClusterState(org.apache.ignite.cluster.ClusterState) IgniteEx(org.apache.ignite.internal.IgniteEx) CorruptedTreeException(org.apache.ignite.internal.processors.cache.persistence.tree.CorruptedTreeException) AtomicReference(java.util.concurrent.atomic.AtomicReference) ByteBuffer(java.nio.ByteBuffer) RendezvousAffinityFunction(org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction) FileIO(org.apache.ignite.internal.processors.cache.persistence.file.FileIO) MvccDataLeafIO(org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataLeafIO) X(org.apache.ignite.internal.util.typedef.X) After(org.junit.After) FileIOFactory(org.apache.ignite.internal.processors.cache.persistence.file.FileIOFactory) DataStorageConfiguration(org.apache.ignite.configuration.DataStorageConfiguration) PageIO(org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO) FileIODecorator(org.apache.ignite.internal.processors.cache.persistence.file.FileIODecorator) AbstractDataLeafIO(org.apache.ignite.internal.processors.cache.tree.AbstractDataLeafIO) Before(org.junit.Before) G(org.apache.ignite.internal.util.typedef.G) F(org.apache.ignite.internal.util.typedef.F) RandomAccessFileIOFactory(org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory) GridCommonAbstractTest(org.apache.ignite.testframework.junits.common.GridCommonAbstractTest) OpenOption(java.nio.file.OpenOption) StandardOpenOption(java.nio.file.StandardOpenOption) GridUnsafe(org.apache.ignite.internal.util.GridUnsafe) IOException(java.io.IOException) FileUtils(org.apache.commons.io.FileUtils) FailureHandler(org.apache.ignite.failure.FailureHandler) Test(org.junit.Test) File(java.io.File) IgniteCache(org.apache.ignite.IgniteCache) Serializable(java.io.Serializable) StopNodeFailureHandler(org.apache.ignite.failure.StopNodeFailureHandler) DataLeafIO(org.apache.ignite.internal.processors.cache.tree.DataLeafIO) GridTestUtils(org.apache.ignite.testframework.GridTestUtils) AtomicLong(java.util.concurrent.atomic.AtomicLong) IgniteConfiguration(org.apache.ignite.configuration.IgniteConfiguration) FastCrc(org.apache.ignite.internal.processors.cache.persistence.wal.crc.FastCrc) CacheConfiguration(org.apache.ignite.configuration.CacheConfiguration) PageIdUtils(org.apache.ignite.internal.pagemem.PageIdUtils) DataPageIO(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO) Pattern(java.util.regex.Pattern) PageSnapshot(org.apache.ignite.internal.pagemem.wal.record.PageSnapshot) DataPageIO(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO) Pattern(java.util.regex.Pattern) LogListener(org.apache.ignite.testframework.LogListener) RandomAccessFileIO(org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIO) ListeningTestLogger(org.apache.ignite.testframework.ListeningTestLogger) ByteBuffer(java.nio.ByteBuffer) OpenOption(java.nio.file.OpenOption) StandardOpenOption(java.nio.file.StandardOpenOption) IgniteEx(org.apache.ignite.internal.IgniteEx) File(java.io.File) PageSnapshot(org.apache.ignite.internal.pagemem.wal.record.PageSnapshot) FullPageId(org.apache.ignite.internal.pagemem.FullPageId) GridCommonAbstractTest(org.apache.ignite.testframework.junits.common.GridCommonAbstractTest) Test(org.junit.Test)

Example 5 with DataPageIO

use of org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO in project ignite by apache.

the class CacheDataRowAdapter method initFromLink.

/**
 * Read row from data pages.
 * Can be called with cctx == null, if cache instance is unknown, but its ID is stored in the data row.
 *
 * @param grp Cache group.
 * @param sharedCtx Shared context.
 * @param pageMem Page memory.
 * @param rowData Row data.
 * @throws IgniteCheckedException If failed.
 */
public final void initFromLink(@Nullable CacheGroupContext grp, GridCacheSharedContext<?, ?> sharedCtx, PageMemory pageMem, RowData rowData) throws IgniteCheckedException {
    assert link != 0 : "link";
    assert key == null : "key";
    CacheObjectContext coctx = grp != null ? grp.cacheObjectContext() : null;
    boolean readCacheId = grp == null || grp.storeCacheIdInDataPage();
    long nextLink = link;
    IncompleteObject<?> incomplete = null;
    boolean first = true;
    do {
        final long pageId = pageId(nextLink);
        // Group is null if try evict page, with persistence evictions should be disabled.
        assert grp != null || pageMem instanceof PageMemoryNoStoreImpl;
        int grpId = grp != null ? grp.groupId() : 0;
        final long page = pageMem.acquirePage(grpId, pageId);
        try {
            // Non-empty data page must not be recycled.
            long pageAddr = pageMem.readLock(grpId, pageId, page);
            assert pageAddr != 0L : nextLink;
            try {
                DataPageIO io = DataPageIO.VERSIONS.forPage(pageAddr);
                DataPagePayload data = io.readPayload(pageAddr, itemId(nextLink), pageMem.pageSize());
                nextLink = data.nextLink();
                if (first) {
                    if (nextLink == 0) {
                        // Fast path for a single page row.
                        readFullRow(sharedCtx, coctx, pageAddr + data.offset(), rowData, readCacheId);
                        return;
                    }
                    first = false;
                }
                ByteBuffer buf = pageMem.pageBuffer(pageAddr);
                buf.position(data.offset());
                buf.limit(data.offset() + data.payloadSize());
                boolean keyOnly = rowData == RowData.KEY_ONLY;
                incomplete = readFragment(sharedCtx, coctx, buf, keyOnly, readCacheId, incomplete);
                if (keyOnly && key != null)
                    return;
            } finally {
                pageMem.readUnlock(grpId, pageId, page);
            }
        } finally {
            pageMem.releasePage(grpId, pageId, page);
        }
    } while (nextLink != 0);
    assert isReady() : "ready";
}
Also used : DataPageIO(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO) PageMemoryNoStoreImpl(org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl) DataPagePayload(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPagePayload) CacheObjectContext(org.apache.ignite.internal.processors.cache.CacheObjectContext) ByteBuffer(java.nio.ByteBuffer)

Aggregations

DataPageIO (org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO)11 DataPagePayload (org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPagePayload)3 ByteBuffer (java.nio.ByteBuffer)2 CacheDataRowAdapter (org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter)2 File (java.io.File)1 IOException (java.io.IOException)1 Serializable (java.io.Serializable)1 OpenOption (java.nio.file.OpenOption)1 StandardOpenOption (java.nio.file.StandardOpenOption)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Pattern (java.util.regex.Pattern)1 FileUtils (org.apache.commons.io.FileUtils)1 IgniteCache (org.apache.ignite.IgniteCache)1 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 CacheAtomicityMode (org.apache.ignite.cache.CacheAtomicityMode)1 RendezvousAffinityFunction (org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction)1 ClusterState (org.apache.ignite.cluster.ClusterState)1 CacheConfiguration (org.apache.ignite.configuration.CacheConfiguration)1 DataStorageConfiguration (org.apache.ignite.configuration.DataStorageConfiguration)1