Search in sources :

Example 1 with PendingRow

use of org.apache.ignite.internal.processors.cache.tree.PendingRow in project ignite by apache.

the class IgniteCacheOffheapManagerImpl method expire.

/**
 * {@inheritDoc}
 */
@Override
public boolean expire(GridCacheContext cctx, IgniteInClosure2X<GridCacheEntryEx, GridCacheVersion> c, int amount) throws IgniteCheckedException {
    assert !cctx.isNear() : cctx.name();
    if (hasPendingEntries && pendingEntries != null) {
        GridCacheVersion obsoleteVer = null;
        long now = U.currentTimeMillis();
        GridCursor<PendingRow> cur;
        if (grp.sharedGroup())
            cur = pendingEntries.find(new PendingRow(cctx.cacheId()), new PendingRow(cctx.cacheId(), now, 0));
        else
            cur = pendingEntries.find(null, new PendingRow(CU.UNDEFINED_CACHE_ID, now, 0));
        if (!cur.next())
            return false;
        int cleared = 0;
        cctx.shared().database().checkpointReadLock();
        try {
            do {
                PendingRow row = cur.get();
                if (amount != -1 && cleared > amount)
                    return true;
                if (row.key.partition() == -1)
                    row.key.partition(cctx.affinity().partition(row.key));
                assert row.key != null && row.link != 0 && row.expireTime != 0 : row;
                if (pendingEntries.removex(row)) {
                    if (obsoleteVer == null)
                        obsoleteVer = ctx.versions().next();
                    c.apply(cctx.cache().entryEx(row.key), obsoleteVer);
                }
                cleared++;
            } while (cur.next());
        } finally {
            cctx.shared().database().checkpointReadUnlock();
        }
    }
    return false;
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) PendingRow(org.apache.ignite.internal.processors.cache.tree.PendingRow)

Example 2 with PendingRow

use of org.apache.ignite.internal.processors.cache.tree.PendingRow in project ignite by apache.

the class CachePartitionDefragmentationManager method copyPartitionData.

/**
 * Defragmentate partition.
 *
 * @param partCtx
 * @param treeIter
 * @throws IgniteCheckedException If failed.
 */
private void copyPartitionData(PartitionContext partCtx, TreeIterator treeIter) throws IgniteCheckedException {
    CacheDataTree tree = partCtx.oldCacheDataStore.tree();
    CacheDataTree newTree = partCtx.newCacheDataStore.tree();
    newTree.enableSequentialWriteMode();
    PendingEntriesTree newPendingTree = partCtx.newCacheDataStore.pendingTree();
    AbstractFreeList<CacheDataRow> freeList = partCtx.newCacheDataStore.getCacheStoreFreeList();
    long cpLockThreshold = 150L;
    defragmentationCheckpoint.checkpointTimeoutLock().checkpointReadLock();
    try {
        AtomicLong lastCpLockTs = new AtomicLong(System.currentTimeMillis());
        AtomicInteger entriesProcessed = new AtomicInteger();
        treeIter.iterate(tree, partCtx.cachePageMemory, (tree0, io, pageAddr, idx) -> {
            checkCancellation();
            if (System.currentTimeMillis() - lastCpLockTs.get() >= cpLockThreshold) {
                defragmentationCheckpoint.checkpointTimeoutLock().checkpointReadUnlock();
                defragmentationCheckpoint.checkpointTimeoutLock().checkpointReadLock();
                lastCpLockTs.set(System.currentTimeMillis());
            }
            AbstractDataLeafIO leafIo = (AbstractDataLeafIO) io;
            CacheDataRow row = tree.getRow(io, pageAddr, idx);
            int cacheId = row.cacheId();
            // Reuse row that we just read.
            row.link(0);
            // "insertDataRow" will corrupt page memory if we don't do this.
            if (row instanceof DataRow && !partCtx.oldGrpCtx.storeCacheIdInDataPage())
                ((DataRow) row).cacheId(CU.UNDEFINED_CACHE_ID);
            freeList.insertDataRow(row, IoStatisticsHolderNoOp.INSTANCE);
            // Put it back.
            if (row instanceof DataRow)
                ((DataRow) row).cacheId(cacheId);
            newTree.putx(row);
            long newLink = row.link();
            partCtx.linkMap.put(leafIo.getLink(pageAddr, idx), newLink);
            if (row.expireTime() != 0)
                newPendingTree.putx(new PendingRow(cacheId, row.expireTime(), newLink));
            entriesProcessed.incrementAndGet();
            return true;
        });
        checkCancellation();
        defragmentationCheckpoint.checkpointTimeoutLock().checkpointReadUnlock();
        defragmentationCheckpoint.checkpointTimeoutLock().checkpointReadLock();
        freeList.saveMetadata(IoStatisticsHolderNoOp.INSTANCE);
        copyCacheMetadata(partCtx);
    } finally {
        defragmentationCheckpoint.checkpointTimeoutLock().checkpointReadUnlock();
    }
}
Also used : CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) GridAtomicLong(org.apache.ignite.internal.util.GridAtomicLong) AtomicLong(java.util.concurrent.atomic.AtomicLong) AbstractDataLeafIO(org.apache.ignite.internal.processors.cache.tree.AbstractDataLeafIO) CacheDataTree(org.apache.ignite.internal.processors.cache.tree.CacheDataTree) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PendingEntriesTree(org.apache.ignite.internal.processors.cache.tree.PendingEntriesTree) DataRow(org.apache.ignite.internal.processors.cache.tree.DataRow) CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) SimpleDataRow(org.apache.ignite.internal.processors.cache.persistence.freelist.SimpleDataRow) PendingRow(org.apache.ignite.internal.processors.cache.tree.PendingRow)

Example 3 with PendingRow

use of org.apache.ignite.internal.processors.cache.tree.PendingRow in project ignite by apache.

the class IgniteCacheOffheapManagerImpl method removeCacheData.

/**
 * @param cacheId Cache ID.
 */
private void removeCacheData(int cacheId) {
    assert grp.affinityNode();
    try {
        if (grp.sharedGroup()) {
            assert cacheId != CU.UNDEFINED_CACHE_ID;
            for (CacheDataStore store : cacheDataStores()) store.clear(cacheId);
            // Clear non-persistent pending tree if needed.
            if (pendingEntries != null) {
                PendingRow row = new PendingRow(cacheId);
                GridCursor<PendingRow> cursor = pendingEntries.find(row, row, PendingEntriesTree.WITHOUT_KEY);
                while (cursor.next()) {
                    boolean res = pendingEntries.removex(cursor.get());
                    assert res;
                }
            }
        }
    } catch (IgniteCheckedException e) {
        throw new IgniteException(e.getMessage(), e);
    }
}
Also used : IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) PendingRow(org.apache.ignite.internal.processors.cache.tree.PendingRow)

Example 4 with PendingRow

use of org.apache.ignite.internal.processors.cache.tree.PendingRow in project ignite by apache.

the class PendingTreeCorruptionTest method testCorruptionWhileLoadingData.

/**
 */
@Test
public void testCorruptionWhileLoadingData() throws Exception {
    IgniteEx ig = startGrid(0);
    ig.cluster().state(ClusterState.ACTIVE);
    String expireCacheName = "cacheWithExpire";
    String regularCacheName = "cacheWithoutExpire";
    String grpName = "cacheGroup";
    IgniteCache<Object, Object> expireCache = ig.getOrCreateCache(new CacheConfiguration<>(expireCacheName).setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(new Duration(MINUTES, 10))).setGroupName(grpName));
    IgniteCache<Object, Object> regularCache = ig.getOrCreateCache(new CacheConfiguration<>(regularCacheName).setGroupName(grpName));
    // This will initialize partition and cache structures.
    expireCache.put(0, 0);
    expireCache.remove(0);
    int expireCacheId = CU.cacheGroupId(expireCacheName, grpName);
    CacheGroupContext grp = ig.context().cache().cacheGroup(CU.cacheId(grpName));
    IgniteCacheOffheapManager.CacheDataStore store = grp.topology().localPartition(0).dataStore();
    assertNotNull(store);
    // Get pending tree of expire cache.
    PendingEntriesTree pendingTree = store.pendingTree();
    long year = TimeUnit.DAYS.toMillis(365);
    long expiration = System.currentTimeMillis() + year;
    ig.context().cache().context().database().checkpointReadLock();
    try {
        // Carefully calculated number. Just enough for the first split to happen, but not more.
        for (int i = 0; i < 202; i++) // link != 0
        pendingTree.putx(new PendingRow(expireCacheId, expiration, expiration + i));
        // Open cursor, it'll cache first leaf of the tree.
        GridCursor<PendingRow> cur = pendingTree.find(null, new PendingRow(expireCacheId, expiration + year, 0), PendingEntriesTree.WITHOUT_KEY);
        // Required for "do" loop to work.
        assertTrue(cur.next());
        int cnt = 0;
        // Emulate real expiry loop but with a more precise control.
        do {
            PendingRow row = cur.get();
            pendingTree.removex(row);
            // with its sibling, meaning that cached "nextPageId" points to empty page from reuse list.
            if (row.link - row.expireTime == 100) {
                // Put into another cache will take a page from reuse list first. This means that cached
                // "nextPageId" points to a data page.
                regularCache.put(0, 0);
            }
            cnt++;
        } while (cur.next());
        assertEquals(202, cnt);
    } finally {
        ig.context().cache().context().database().checkpointReadUnlock();
    }
}
Also used : Duration(javax.cache.expiry.Duration) PendingEntriesTree(org.apache.ignite.internal.processors.cache.tree.PendingEntriesTree) PendingRow(org.apache.ignite.internal.processors.cache.tree.PendingRow) IgniteCacheOffheapManager(org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManager) IgniteEx(org.apache.ignite.internal.IgniteEx) CacheGroupContext(org.apache.ignite.internal.processors.cache.CacheGroupContext) CacheConfiguration(org.apache.ignite.configuration.CacheConfiguration) GridCommonAbstractTest(org.apache.ignite.testframework.junits.common.GridCommonAbstractTest) Test(org.junit.Test)

Example 5 with PendingRow

use of org.apache.ignite.internal.processors.cache.tree.PendingRow in project ignite by apache.

the class UpgradePendingTreeToPerPartitionTask method processPendingTree.

/**
 * Move pending rows for CacheGroup entries to per-partition PendingTree.
 * Invalid pending rows will be ignored.
 *
 * @param grp Cache group.
 * @param oldPendingEntries Old-style PendingTree.
 * @throws IgniteCheckedException If error occurs.
 */
private void processPendingTree(CacheGroupContext grp, PendingEntriesTree oldPendingEntries) throws IgniteCheckedException {
    final PageMemory pageMemory = grp.dataRegion().pageMemory();
    final IgniteCacheDatabaseSharedManager db = grp.shared().database();
    final Set<Integer> cacheIds = grp.cacheIds();
    PendingRow row = null;
    int processedEntriesCnt = 0;
    int skippedEntries = 0;
    // Re-acquire checkpoint lock for every next batch.
    while (!Thread.currentThread().isInterrupted()) {
        int cnt = 0;
        db.checkpointReadLock();
        try {
            GridCursor<PendingRow> cursor = oldPendingEntries.find(row, null, WITHOUT_KEY);
            while (cnt++ < BATCH_SIZE && cursor.next()) {
                row = cursor.get();
                assert row.link != 0 && row.expireTime != 0 : row;
                GridCacheEntryEx entry;
                // Lost cache or lost entry.
                if (!cacheIds.contains(row.cacheId) || (entry = getEntry(grp, row)) == null) {
                    skippedEntries++;
                    oldPendingEntries.removex(row);
                    continue;
                }
                entry.lockEntry();
                try {
                    if (processRow(pageMemory, grp, row))
                        processedEntriesCnt++;
                    else
                        skippedEntries++;
                } finally {
                    entry.unlockEntry();
                }
                oldPendingEntries.removex(row);
            }
            if (cnt < BATCH_SIZE)
                break;
        } finally {
            db.checkpointReadUnlock();
        }
    }
    log.info("PendingTree upgraded: " + "[grpId=" + grp.groupId() + ", grpName=" + grp.name() + ", processedEntries=" + processedEntriesCnt + ", failedEntries=" + skippedEntries + ']');
}
Also used : GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) PageMemory(org.apache.ignite.internal.pagemem.PageMemory) PendingRow(org.apache.ignite.internal.processors.cache.tree.PendingRow) IgniteCacheDatabaseSharedManager(org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager)

Aggregations

PendingRow (org.apache.ignite.internal.processors.cache.tree.PendingRow)6 PendingEntriesTree (org.apache.ignite.internal.processors.cache.tree.PendingEntriesTree)2 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 Duration (javax.cache.expiry.Duration)1 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 IgniteException (org.apache.ignite.IgniteException)1 CacheConfiguration (org.apache.ignite.configuration.CacheConfiguration)1 IgniteEx (org.apache.ignite.internal.IgniteEx)1 PageMemory (org.apache.ignite.internal.pagemem.PageMemory)1 CacheGroupContext (org.apache.ignite.internal.processors.cache.CacheGroupContext)1 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)1 IgniteCacheOffheapManager (org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManager)1 CacheDataRow (org.apache.ignite.internal.processors.cache.persistence.CacheDataRow)1 IgniteCacheDatabaseSharedManager (org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager)1 SimpleDataRow (org.apache.ignite.internal.processors.cache.persistence.freelist.SimpleDataRow)1 AbstractDataLeafIO (org.apache.ignite.internal.processors.cache.tree.AbstractDataLeafIO)1 CacheDataTree (org.apache.ignite.internal.processors.cache.tree.CacheDataTree)1 DataRow (org.apache.ignite.internal.processors.cache.tree.DataRow)1