Search in sources :

Example 1 with GridDhtPartitionsReservation

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

the class PartitionReservationManager method reservePartitions.

/**
 * @param cacheIds Cache IDs.
 * @param reqTopVer Topology version from request.
 * @param explicitParts Explicit partitions list.
 * @param nodeId Node ID.
 * @param reqId Request ID.
 * @return String which is null in case of success or with causeMessage if failed
 * @throws IgniteCheckedException If failed.
 */
public PartitionReservation reservePartitions(@Nullable List<Integer> cacheIds, AffinityTopologyVersion reqTopVer, final int[] explicitParts, UUID nodeId, long reqId) throws IgniteCheckedException {
    try (TraceSurroundings ignored = MTC.support(ctx.tracing().create(SQL_PARTITIONS_RESERVE, MTC.span()))) {
        assert reqTopVer != null;
        AffinityTopologyVersion topVer = ctx.cache().context().exchange().lastAffinityChangedTopologyVersion(reqTopVer);
        if (F.isEmpty(cacheIds))
            return new PartitionReservation(Collections.emptyList());
        Collection<Integer> partIds;
        if (explicitParts == null)
            partIds = null;
        else if (explicitParts.length == 0)
            partIds = Collections.emptyList();
        else {
            partIds = new ArrayList<>(explicitParts.length);
            for (int explicitPart : explicitParts) partIds.add(explicitPart);
        }
        List<GridReservable> reserved = new ArrayList<>();
        for (int i = 0; i < cacheIds.size(); i++) {
            GridCacheContext<?, ?> cctx = ctx.cache().context().cacheContext(cacheIds.get(i));
            // Cache was not found, probably was not deployed yet.
            if (cctx == null) {
                return new PartitionReservation(reserved, String.format("Failed to reserve partitions for query (cache is not " + "found on local node) [localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s]", ctx.localNodeId(), nodeId, reqId, topVer, cacheIds.get(i)));
            }
            if (cctx.isLocal() || !cctx.rebalanceEnabled())
                continue;
            // For replicated cache topology version does not make sense.
            final PartitionReservationKey grpKey = new PartitionReservationKey(cctx.name(), cctx.isReplicated() ? null : topVer);
            GridReservable r = reservations.get(grpKey);
            if (explicitParts == null && r != null) {
                // Try to reserve group partition if any and no explicits.
                if (r != REPLICATED_RESERVABLE) {
                    if (!r.reserve())
                        return new PartitionReservation(reserved, String.format("Failed to reserve partitions for query (group " + "reservation failed) [localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s, " + "cacheName=%s]", ctx.localNodeId(), nodeId, reqId, topVer, cacheIds.get(i), cctx.name()));
                    reserved.add(r);
                    MTC.span().addLog(() -> "Cache partitions were reserved " + r);
                }
            } else {
                // Try to reserve partitions one by one.
                int partsCnt = cctx.affinity().partitions();
                if (cctx.isReplicated()) {
                    // Check all the partitions are in owning state for replicated cache.
                    if (r == null) {
                        // Check only once.
                        for (int p = 0; p < partsCnt; p++) {
                            GridDhtLocalPartition part = partition(cctx, p);
                            // We don't need to reserve partitions because they will not be evicted in replicated caches.
                            GridDhtPartitionState partState = part != null ? part.state() : null;
                            if (partState != OWNING)
                                return new PartitionReservation(reserved, String.format("Failed to reserve partitions for " + "query (partition of REPLICATED cache is not in OWNING state) [" + "localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s, " + "cacheName=%s, part=%s, partFound=%s, partState=%s]", ctx.localNodeId(), nodeId, reqId, topVer, cacheIds.get(i), cctx.name(), p, (part != null), partState));
                        }
                        // Mark that we checked this replicated cache.
                        reservations.putIfAbsent(grpKey, REPLICATED_RESERVABLE);
                        MTC.span().addLog(() -> "Cache partitions were reserved [cache=" + cctx.name() + ", partitions=[0.." + partsCnt + ']');
                    }
                } else {
                    // Reserve primary partitions for partitioned cache (if no explicit given).
                    if (explicitParts == null)
                        partIds = cctx.affinity().primaryPartitions(ctx.localNodeId(), topVer);
                    int reservedCnt = 0;
                    for (int partId : partIds) {
                        GridDhtLocalPartition part = partition(cctx, partId);
                        GridDhtPartitionState partState = part != null ? part.state() : null;
                        if (partState != OWNING) {
                            if (partState == LOST)
                                failQueryOnLostData(cctx, part);
                            else {
                                return new PartitionReservation(reserved, String.format("Failed to reserve partitions " + "for query (partition of PARTITIONED cache is not found or not in OWNING " + "state) [localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s, " + "cacheName=%s, part=%s, partFound=%s, partState=%s]", ctx.localNodeId(), nodeId, reqId, topVer, cacheIds.get(i), cctx.name(), partId, (part != null), partState));
                            }
                        }
                        if (!part.reserve()) {
                            return new PartitionReservation(reserved, String.format("Failed to reserve partitions for query " + "(partition of PARTITIONED cache cannot be reserved) [" + "localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s, " + "cacheName=%s, part=%s, partFound=%s, partState=%s]", ctx.localNodeId(), nodeId, reqId, topVer, cacheIds.get(i), cctx.name(), partId, true, partState));
                        }
                        reserved.add(part);
                        reservedCnt++;
                        // Double check that we are still in owning state and partition contents are not cleared.
                        partState = part.state();
                        if (partState != OWNING) {
                            if (partState == LOST)
                                failQueryOnLostData(cctx, part);
                            else {
                                return new PartitionReservation(reserved, String.format("Failed to reserve partitions for " + "query (partition of PARTITIONED cache is not in OWNING state after " + "reservation) [localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, " + "cacheId=%s, cacheName=%s, part=%s, partState=%s]", ctx.localNodeId(), nodeId, reqId, topVer, cacheIds.get(i), cctx.name(), partId, partState));
                            }
                        }
                    }
                    final Collection<Integer> finalPartIds = partIds;
                    MTC.span().addLog(() -> "Cache partitions were reserved [cache=" + cctx.name() + ", partitions=" + finalPartIds + ", topology=" + topVer + ']');
                    if (explicitParts == null && reservedCnt > 0) {
                        // We reserved all the primary partitions for cache, attempt to add group reservation.
                        GridDhtPartitionsReservation grp = new GridDhtPartitionsReservation(topVer, cctx, "SQL");
                        if (grp.register(reserved.subList(reserved.size() - reservedCnt, reserved.size()))) {
                            if (reservations.putIfAbsent(grpKey, grp) != null)
                                throw new IllegalStateException("Reservation already exists.");
                            grp.onPublish(new CI1<GridDhtPartitionsReservation>() {

                                @Override
                                public void apply(GridDhtPartitionsReservation r) {
                                    reservations.remove(grpKey, r);
                                }
                            });
                        }
                    }
                }
            }
        }
        return new PartitionReservation(reserved);
    }
}
Also used : GridDhtPartitionsReservation(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionsReservation) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) ArrayList(java.util.ArrayList) GridReservable(org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable) TraceSurroundings(org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings) GridDhtPartitionState(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState) GridDhtLocalPartition(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition)

Aggregations

ArrayList (java.util.ArrayList)1 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)1 GridReservable (org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable)1 GridDhtLocalPartition (org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition)1 GridDhtPartitionState (org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState)1 GridDhtPartitionsReservation (org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionsReservation)1 TraceSurroundings (org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings)1