Search in sources :

Example 46 with GridDhtLocalPartition

use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.

the class GridDhtTxPrepareFuture method map.

/**
 * @param entry Transaction entry.
 */
private void map(IgniteTxEntry entry) throws IgniteTxRollbackCheckedException {
    if (entry.cached().isLocal())
        return;
    GridDhtCacheEntry cached = (GridDhtCacheEntry) entry.cached();
    GridCacheContext cacheCtx = entry.context();
    GridDhtCacheAdapter<?, ?> dht = cacheCtx.isNear() ? cacheCtx.near().dht() : cacheCtx.dht();
    ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(entry);
    if (expiry != null && (entry.op() == READ || entry.op() == NOOP)) {
        entry.op(NOOP);
        entry.ttl(CU.toTtl(expiry.getExpiryForAccess()));
    }
    while (true) {
        try {
            List<ClusterNode> dhtNodes = dht.topology().nodes(cached.partition(), tx.topologyVersion());
            GridDhtPartitionTopology top = cacheCtx.topology();
            GridDhtLocalPartition part = top.localPartition(cached.partition());
            if (part != null && !part.primary(top.readyTopologyVersion())) {
                log.warning("Failed to map a transaction on outdated topology, rolling back " + "[tx=" + CU.txString(tx) + ", readyTopVer=" + top.readyTopologyVersion() + ", lostParts=" + top.lostPartitions() + ", part=" + part.toString() + ']');
                throw new IgniteTxRollbackCheckedException("Failed to map a transaction on outdated " + "topology, please try again [timeout=" + tx.timeout() + ", tx=" + CU.txString(tx) + ']');
            }
            assert !dhtNodes.isEmpty() && dhtNodes.get(0).id().equals(cctx.localNodeId()) : "cacheId=" + cacheCtx.cacheId() + ", localNode = " + cctx.localNodeId() + ", dhtNodes = " + dhtNodes;
            if (log.isDebugEnabled())
                log.debug("Mapping entry to DHT nodes [nodes=" + U.toShortString(dhtNodes) + ", entry=" + entry + ']');
            for (int i = 1; i < dhtNodes.size(); i++) {
                ClusterNode node = dhtNodes.get(i);
                addMapping(entry, node, dhtMap);
            }
            Collection<UUID> readers = cached.readers();
            if (!F.isEmpty(readers)) {
                for (UUID readerId : readers) {
                    if (readerId.equals(tx.nearNodeId()))
                        continue;
                    ClusterNode readerNode = cctx.discovery().node(readerId);
                    if (readerNode == null || canSkipNearReader(dht, readerNode, dhtNodes))
                        continue;
                    if (log.isDebugEnabled())
                        log.debug("Mapping entry to near node [node=" + readerNode + ", entry=" + entry + ']');
                    addMapping(entry, readerNode, nearMap);
                }
            } else if (log.isDebugEnabled())
                log.debug("Entry has no near readers: " + entry);
            break;
        } catch (GridCacheEntryRemovedException ignore) {
            cached = dht.entryExx(entry.key(), tx.topologyVersion());
            entry.cached(cached);
        }
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) GridDhtPartitionTopology(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology) IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException) ExpiryPolicy(javax.cache.expiry.ExpiryPolicy) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition) UUID(java.util.UUID)

Example 47 with GridDhtLocalPartition

use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.

the class GridDhtTransactionalCacheAdapter method startRemoteTx.

/**
 * @param nodeId Primary node ID.
 * @param req Request.
 * @param res Response.
 * @return Remote transaction.
 * @throws IgniteCheckedException If failed.
 * @throws GridDistributedLockCancelledException If lock has been cancelled.
 */
@Nullable
private GridDhtTxRemote startRemoteTx(UUID nodeId, GridDhtLockRequest req, GridDhtLockResponse res) throws IgniteCheckedException, GridDistributedLockCancelledException {
    List<KeyCacheObject> keys = req.keys();
    GridDhtTxRemote tx = null;
    int size = F.size(keys);
    for (int i = 0; i < size; i++) {
        KeyCacheObject key = keys.get(i);
        if (key == null)
            continue;
        IgniteTxKey txKey = ctx.txKey(key);
        if (log.isDebugEnabled())
            log.debug("Unmarshalled key: " + key);
        GridDistributedCacheEntry entry = null;
        while (true) {
            try {
                int part = ctx.affinity().partition(key);
                GridDhtLocalPartition locPart = ctx.topology().localPartition(part, req.topologyVersion(), false);
                if (locPart == null || !locPart.reserve()) {
                    if (log.isDebugEnabled())
                        log.debug("Local partition for given key is already evicted (will add to invalid " + "partition list) [key=" + key + ", part=" + part + ", locPart=" + locPart + ']');
                    res.addInvalidPartition(part);
                    // Invalidate key in near cache, if any.
                    if (isNearEnabled(cacheCfg))
                        obsoleteNearEntry(key);
                    break;
                }
                try {
                    // Handle implicit locks for pessimistic transactions.
                    if (req.inTx()) {
                        if (tx == null)
                            tx = ctx.tm().tx(req.version());
                        if (tx == null) {
                            tx = new GridDhtTxRemote(ctx.shared(), req.nodeId(), req.futureId(), nodeId, req.nearXidVersion(), req.topologyVersion(), req.version(), /*commitVer*/
                            null, ctx.systemTx(), ctx.ioPolicy(), PESSIMISTIC, req.isolation(), req.isInvalidate(), req.timeout(), req.txSize(), securitySubjectId(ctx), req.taskNameHash(), !req.skipStore() && req.storeUsed(), req.txLabel());
                            tx = ctx.tm().onCreated(null, tx);
                            if (tx == null || !ctx.tm().onStarted(tx))
                                throw new IgniteTxRollbackCheckedException("Failed to acquire lock (transaction " + "has been completed) [ver=" + req.version() + ", tx=" + tx + ']');
                        }
                        tx.addWrite(ctx, NOOP, txKey, null, null, req.accessTtl(), req.skipStore(), req.keepBinary());
                    }
                    entry = entryExx(key, req.topologyVersion());
                    // Add remote candidate before reordering.
                    entry.addRemote(req.nodeId(), nodeId, req.threadId(), req.version(), tx != null, tx != null && tx.implicitSingle(), null);
                    // Invalidate key in near cache, if any.
                    if (isNearEnabled(cacheCfg) && req.invalidateNearEntry(i))
                        invalidateNearEntry(key, req.version());
                    // Get entry info after candidate is added.
                    if (req.needPreloadKey(i)) {
                        entry.unswap();
                        GridCacheEntryInfo info = entry.info();
                        if (info != null && !info.isNew() && !info.isDeleted())
                            res.addPreloadEntry(info);
                    }
                    // Double-check in case if sender node left the grid.
                    if (ctx.discovery().node(req.nodeId()) == null) {
                        if (log.isDebugEnabled())
                            log.debug("Node requesting lock left grid (lock request will be ignored): " + req);
                        entry.removeLock(req.version());
                        if (tx != null) {
                            tx.clearEntry(txKey);
                            // COMMITTING state, but this lock is never acquired.
                            if (tx.state() == COMMITTING)
                                tx.forceCommit();
                            else
                                tx.rollbackRemoteTx();
                        }
                        return null;
                    }
                    // Entry is legit.
                    break;
                } finally {
                    locPart.release();
                }
            } catch (GridDhtInvalidPartitionException e) {
                if (log.isDebugEnabled())
                    log.debug("Received invalid partition exception [e=" + e + ", req=" + req + ']');
                res.addInvalidPartition(e.partition());
                // Invalidate key in near cache, if any.
                if (isNearEnabled(cacheCfg))
                    obsoleteNearEntry(key);
                if (tx != null) {
                    tx.clearEntry(txKey);
                    if (log.isDebugEnabled())
                        log.debug("Cleared invalid entry from remote transaction (will skip) [entry=" + entry + ", tx=" + tx + ']');
                }
                break;
            } catch (GridCacheEntryRemovedException ignored) {
                assert entry.obsoleteVersion() != null : "Obsolete flag not set on removed entry: " + entry;
                if (log.isDebugEnabled())
                    log.debug("Received entry removed exception (will retry on renewed entry): " + entry);
                if (tx != null) {
                    tx.clearEntry(txKey);
                    if (log.isDebugEnabled())
                        log.debug("Cleared removed entry from remote transaction (will retry) [entry=" + entry + ", tx=" + tx + ']');
                }
            }
        }
    }
    if (tx != null && tx.empty()) {
        if (log.isDebugEnabled())
            log.debug("Rolling back remote DHT transaction because it is empty [req=" + req + ", res=" + res + ']');
        tx.rollbackRemoteTx();
        tx = null;
    }
    return tx;
}
Also used : GridCacheEntryInfo(org.apache.ignite.internal.processors.cache.GridCacheEntryInfo) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException) GridDistributedCacheEntry(org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) IgniteTxKey(org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition) IgniteTxRollbackCheckedException(org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) Nullable(org.jetbrains.annotations.Nullable)

Example 48 with GridDhtLocalPartition

use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.

the class IdleVerifyUtility method getUpdateCountersSnapshot.

/**
 * Gather updateCounters info.
 * Holds {@link org.apache.ignite.internal.processors.cache.PartitionUpdateCounter#copy} of update counters.
 *
 * @param ign Ignite instance.
 * @param grpIds Group Id`s.
 * @return Current groups distribution with update counters per partitions.
 */
public static Map<Integer, Map<Integer, PartitionUpdateCounter>> getUpdateCountersSnapshot(IgniteEx ign, Set<Integer> grpIds) {
    Map<Integer, Map<Integer, PartitionUpdateCounter>> partsWithCountersPerGrp = new HashMap<>();
    for (Integer grpId : grpIds) {
        CacheGroupContext grpCtx = ign.context().cache().cacheGroup(grpId);
        if (grpCtx == null)
            throw new GridNotIdleException("Group not found: " + grpId + "." + " Possible reasons: rebalance in progress or concurrent cache destroy.");
        GridDhtPartitionTopology top = grpCtx.topology();
        Map<Integer, PartitionUpdateCounter> partsWithCounters = partsWithCountersPerGrp.computeIfAbsent(grpId, k -> new HashMap<>());
        for (GridDhtLocalPartition part : top.currentLocalPartitions()) {
            if (part.state() != GridDhtPartitionState.OWNING)
                continue;
            @Nullable PartitionUpdateCounter updCntr = part.dataStore().partUpdateCounter();
            partsWithCounters.put(part.id(), updCntr == null ? null : updCntr.copy());
        }
    }
    return partsWithCountersPerGrp;
}
Also used : HashMap(java.util.HashMap) GridDhtPartitionTopology(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology) PartitionUpdateCounter(org.apache.ignite.internal.processors.cache.PartitionUpdateCounter) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition) CacheGroupContext(org.apache.ignite.internal.processors.cache.CacheGroupContext) HashMap(java.util.HashMap) Map(java.util.Map) Nullable(org.jetbrains.annotations.Nullable)

Example 49 with GridDhtLocalPartition

use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.

the class IgniteCacheOffheapManagerImpl method evictionSafeIterator.

/**
 * @param cacheId Cache ID.
 * @param dataIt Data store iterator.
 * @return Rows iterator
 */
private GridCloseableIterator<CacheDataRow> evictionSafeIterator(int cacheId, Iterator<CacheDataStore> dataIt) {
    return new GridCloseableIteratorAdapter<CacheDataRow>() {

        /**
         */
        private GridCursor<? extends CacheDataRow> cur;

        /**
         */
        private GridDhtLocalPartition curPart;

        /**
         */
        private CacheDataRow next;

        @Override
        protected CacheDataRow onNext() {
            CacheDataRow res = next;
            next = null;
            return res;
        }

        @Override
        protected boolean onHasNext() throws IgniteCheckedException {
            if (next != null)
                return true;
            while (true) {
                if (cur == null) {
                    if (dataIt.hasNext()) {
                        CacheDataStore ds = dataIt.next();
                        if (!reservePartition(ds.partId()))
                            continue;
                        cur = cacheId == CU.UNDEFINED_CACHE_ID ? ds.cursor() : ds.cursor(cacheId);
                    } else
                        break;
                }
                if (cur.next()) {
                    next = cur.get();
                    next.key().partition(curPart.id());
                    break;
                } else {
                    cur = null;
                    releaseCurrentPartition();
                }
            }
            return next != null;
        }

        /**
         */
        private void releaseCurrentPartition() {
            GridDhtLocalPartition p = curPart;
            assert p != null;
            curPart = null;
            p.release();
        }

        /**
         * @param partId Partition number.
         * @return {@code True} if partition was reserved.
         */
        private boolean reservePartition(int partId) {
            GridDhtLocalPartition p = grp.topology().localPartition(partId);
            if (p != null && p.reserve()) {
                curPart = p;
                return true;
            }
            return false;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected void onClose() throws IgniteCheckedException {
            if (curPart != null)
                releaseCurrentPartition();
        }
    };
}
Also used : CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) GridCursor(org.apache.ignite.internal.util.lang.GridCursor) GridCloseableIteratorAdapter(org.apache.ignite.internal.util.GridCloseableIteratorAdapter) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition)

Example 50 with GridDhtLocalPartition

use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.

the class IgniteCacheOffheapManagerImpl method reservedIterator.

/**
 * {@inheritDoc}
 */
@Override
public GridCloseableIterator<CacheDataRow> reservedIterator(int part, AffinityTopologyVersion topVer) {
    GridDhtLocalPartition loc = grp.topology().localPartition(part, topVer, false);
    if (loc == null || !loc.reserve())
        return null;
    // It is necessary to check state after reservation to avoid race conditions.
    if (loc.state() != OWNING) {
        loc.release();
        return null;
    }
    CacheDataStore data = dataStore(loc);
    return new GridCloseableIteratorAdapter<CacheDataRow>() {

        /**
         */
        private CacheDataRow next;

        /**
         */
        private GridCursor<? extends CacheDataRow> cur;

        @Override
        protected CacheDataRow onNext() {
            CacheDataRow res = next;
            next = null;
            return res;
        }

        @Override
        protected boolean onHasNext() throws IgniteCheckedException {
            if (cur == null)
                cur = data.cursor(CacheDataRowAdapter.RowData.FULL_WITH_HINTS);
            if (next != null)
                return true;
            if (cur.next())
                next = cur.get();
            boolean hasNext = next != null;
            if (!hasNext)
                cur = null;
            return hasNext;
        }

        @Override
        protected void onClose() throws IgniteCheckedException {
            assert loc != null && loc.state() == OWNING && loc.reservations() > 0 : "Partition should be in OWNING state and has at least 1 reservation: " + loc;
            loc.release();
            cur = null;
        }
    };
}
Also used : CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) GridCursor(org.apache.ignite.internal.util.lang.GridCursor) GridCloseableIteratorAdapter(org.apache.ignite.internal.util.GridCloseableIteratorAdapter) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition)

Aggregations

GridDhtLocalPartition (org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition)95 GridDhtPartitionTopology (org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology)21 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)19 IgniteEx (org.apache.ignite.internal.IgniteEx)19 CacheGroupContext (org.apache.ignite.internal.processors.cache.CacheGroupContext)19 ArrayList (java.util.ArrayList)18 Map (java.util.Map)18 Test (org.junit.Test)18 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)16 GridCommonAbstractTest (org.apache.ignite.testframework.junits.common.GridCommonAbstractTest)16 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)15 ClusterNode (org.apache.ignite.cluster.ClusterNode)15 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)15 HashMap (java.util.HashMap)14 HashSet (java.util.HashSet)13 AtomicLong (java.util.concurrent.atomic.AtomicLong)13 CacheDataRow (org.apache.ignite.internal.processors.cache.persistence.CacheDataRow)13 Ignite (org.apache.ignite.Ignite)12 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)12 IgniteException (org.apache.ignite.IgniteException)11