use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.
the class IgniteTxHandler method startRemoteTx.
/**
* @param nodeId Node ID.
* @param req Request.
* @param res Response.
* @return Remote transaction.
* @throws IgniteCheckedException If failed.
*/
@Nullable
GridDhtTxRemote startRemoteTx(UUID nodeId, GridDhtTxPrepareRequest req, GridDhtTxPrepareResponse res) throws IgniteCheckedException {
if (req.queryUpdate() || !F.isEmpty(req.writes())) {
GridDhtTxRemote tx = ctx.tm().tx(req.version());
if (tx == null) {
boolean single = req.last() && req.writes().size() == 1;
tx = new GridDhtTxRemote(ctx, req.nearNodeId(), req.futureId(), nodeId, req.topologyVersion(), req.version(), null, req.system(), req.policy(), req.concurrency(), req.isolation(), req.isInvalidate(), req.timeout(), req.writes() != null ? Math.max(req.writes().size(), req.txSize()) : req.txSize(), req.nearXidVersion(), req.transactionNodes(), securitySubjectId(ctx), req.taskNameHash(), single, req.storeWriteThrough(), req.txLabel());
tx.onePhaseCommit(req.onePhaseCommit());
tx.writeVersion(req.writeVersion());
tx = ctx.tm().onCreated(null, tx);
if (tx == null || !ctx.tm().onStarted(tx)) {
if (log.isDebugEnabled())
log.debug("Attempt to start a completed transaction (will ignore): " + tx);
applyPartitionsUpdatesCounters(req.updateCounters(), true, false);
return null;
}
if (ctx.discovery().node(nodeId) == null) {
tx.state(ROLLING_BACK);
tx.state(ROLLED_BACK);
ctx.tm().uncommitTx(tx);
applyPartitionsUpdatesCounters(req.updateCounters(), true, false);
return null;
}
ctx.versions().onReceived(nodeId, req.writeVersion());
} else {
tx.writeVersion(req.writeVersion());
tx.transactionNodes(req.transactionNodes());
}
TxCounters txCounters = null;
if (req.updateCounters() != null) {
txCounters = tx.txCounters(true);
txCounters.updateCounters(req.updateCounters());
}
Set<GridDhtLocalPartition> reservedParts = new HashSet<>();
try {
if (!tx.isSystemInvalidate()) {
int idx = 0;
for (IgniteTxEntry entry : req.writes()) {
GridCacheContext cacheCtx = entry.context();
int part = cacheCtx.affinity().partition(entry.key());
try {
GridDhtLocalPartition locPart = cacheCtx.topology().localPartition(part, req.topologyVersion(), false);
// Avoid enlisting to invalid partition.
boolean reserved = locPart != null && reservedParts.contains(locPart);
if (!reserved) {
if ((reserved = locPart != null && locPart.reserve()))
reservedParts.add(locPart);
}
if (reserved) {
tx.addWrite(entry, ctx.deploy().globalLoader());
if (txCounters != null) {
Long cntr = txCounters.generateNextCounter(entry.cacheId(), part);
if (// Counter is null if entry is no-op.
cntr != null)
entry.updateCounter(cntr);
}
if (isNearEnabled(cacheCtx) && req.invalidateNearEntry(idx))
invalidateNearEntry(cacheCtx, entry.key(), req.version());
if (req.needPreloadKey(idx)) {
GridCacheEntryEx cached = entry.cached();
if (cached == null)
cached = cacheCtx.cache().entryEx(entry.key(), req.topologyVersion());
GridCacheEntryInfo info = cached.info();
if (info != null && !info.isNew() && !info.isDeleted())
res.addPreloadEntry(info);
}
if (cacheCtx.readThroughConfigured() && !entry.skipStore() && entry.op() == TRANSFORM && entry.oldValueOnPrimary() && !entry.hasValue()) {
while (true) {
try {
GridCacheEntryEx cached = entry.cached();
if (cached == null) {
cached = cacheCtx.cache().entryEx(entry.key(), req.topologyVersion());
entry.cached(cached);
}
CacheObject val = cached.innerGet(/*ver*/
null, tx, /*readThrough*/
false, /*updateMetrics*/
false, /*evt*/
false, /*transformClo*/
null, tx.resolveTaskName(), /*expiryPlc*/
null, /*keepBinary*/
true);
if (val == null)
val = cacheCtx.toCacheObject(cacheCtx.store().load(null, entry.key()));
if (val != null)
entry.readValue(val);
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Got entry removed exception, will retry: " + entry.txKey());
entry.cached(cacheCtx.cache().entryEx(entry.key(), req.topologyVersion()));
}
}
}
} else
tx.addInvalidPartition(cacheCtx.cacheId(), part);
} catch (GridDhtInvalidPartitionException e) {
tx.addInvalidPartition(cacheCtx.cacheId(), part);
}
idx++;
}
}
// Prepare prior to reordering, so the pending locks added
// in prepare phase will get properly ordered as well.
tx.prepareRemoteTx();
} finally {
reservedParts.forEach(GridDhtLocalPartition::release);
}
if (req.last()) {
assert !F.isEmpty(req.transactionNodes()) : "Received last prepare request with empty transaction nodes: " + req;
tx.state(PREPARED);
}
res.invalidPartitionsByCacheId(tx.invalidPartitions());
if (!req.queryUpdate() && tx.empty() && req.last()) {
tx.skipCompletedVersions(req.skipCompletedVersion());
tx.rollbackRemoteTx();
return null;
}
return tx;
}
return null;
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.
the class CacheGroupMetricsImpl method getPartitionIds.
/**
*/
public List<Integer> getPartitionIds() {
List<GridDhtLocalPartition> parts = ctx.topology().localPartitions();
List<Integer> partsRes = new ArrayList<>(parts.size());
for (GridDhtLocalPartition part : parts) partsRes.add(part.id());
return partsRes;
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.
the class GridDhtPartitionsExchangeFuture method assignPartitionSizes.
/**
* @param top Topology.
*/
private void assignPartitionSizes(GridDhtPartitionTopology top) {
Map<Integer, Long> partSizes = new HashMap<>();
for (Map.Entry<UUID, GridDhtPartitionsSingleMessage> e : msgs.entrySet()) {
GridDhtPartitionsSingleMessage singleMsg = e.getValue();
GridDhtPartitionMap partMap = singleMsg.partitions().get(top.groupId());
if (partMap == null)
continue;
for (Map.Entry<Integer, GridDhtPartitionState> e0 : partMap.entrySet()) {
int p = e0.getKey();
GridDhtPartitionState state = e0.getValue();
if (state == GridDhtPartitionState.OWNING)
partSizes.put(p, singleMsg.partitionSizes(top.groupId()).get(p));
}
}
for (GridDhtLocalPartition locPart : top.currentLocalPartitions()) {
if (locPart.state() == GridDhtPartitionState.OWNING)
partSizes.put(locPart.id(), locPart.fullSize());
}
top.globalPartSizes(partSizes);
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.
the class GridDhtForceKeysFuture method map.
/**
* @param key Key.
* @param exc Exclude nodes.
* @param mappings Mappings.
* @return Mappings.
*/
private Map<ClusterNode, Set<KeyCacheObject>> map(KeyCacheObject key, @Nullable Map<ClusterNode, Set<KeyCacheObject>> mappings, Collection<ClusterNode> exc) {
ClusterNode loc = cctx.localNode();
GridCacheEntryEx e = cctx.dht().peekEx(key);
try {
if (e != null && !e.isNewLocked()) {
if (log.isTraceEnabled()) {
int part = cctx.affinity().partition(key);
log.trace("Will not rebalance key (entry is not new) [cacheName=" + cctx.name() + ", key=" + key + ", part=" + part + ", locId=" + cctx.nodeId() + ']');
}
// Key has been rebalanced or retrieved already.
return mappings;
}
} catch (GridCacheEntryRemovedException ignore) {
if (log.isTraceEnabled())
log.trace("Received removed DHT entry for force keys request [entry=" + e + ", locId=" + cctx.nodeId() + ']');
}
int part = cctx.affinity().partition(key);
List<ClusterNode> owners = F.isEmpty(exc) ? top.owners(part, topVer) : new ArrayList<>(F.view(top.owners(part, topVer), F.notIn(exc)));
if (owners.isEmpty() || (owners.contains(loc) && cctx.rebalanceEnabled())) {
if (log.isTraceEnabled())
log.trace("Will not rebalance key (local node is owner) [key=" + key + ", part=" + part + "topVer=" + topVer + ", locId=" + cctx.nodeId() + ']');
// Key is already rebalanced.
return mappings;
}
// Create partition.
GridDhtLocalPartition locPart = top.localPartition(part, topVer, false);
if (log.isTraceEnabled())
log.trace("Mapping local partition [loc=" + cctx.localNodeId() + ", topVer" + topVer + ", part=" + locPart + ", owners=" + owners + ", allOwners=" + U.toShortString(top.owners(part)) + ']');
if (locPart == null)
invalidParts.add(part);
else if (!cctx.rebalanceEnabled() || locPart.state() == MOVING) {
Collections.sort(owners, CU.nodeComparator(false));
// Load from youngest owner.
ClusterNode pick = F.first(owners);
assert pick != null;
if (!cctx.rebalanceEnabled() && loc.id().equals(pick.id()))
pick = F.first(F.view(owners, F.remoteNodes(loc.id())));
if (pick == null) {
if (log.isTraceEnabled())
log.trace("Will not rebalance key (no nodes to request from with rebalancing disabled) [key=" + key + ", part=" + part + ", locId=" + cctx.nodeId() + ']');
return mappings;
}
if (mappings == null)
mappings = U.newHashMap(keys.size());
Collection<KeyCacheObject> mappedKeys = F.addIfAbsent(mappings, pick, F.<KeyCacheObject>newSet());
assert mappedKeys != null;
mappedKeys.add(key);
if (log.isTraceEnabled())
log.trace("Will rebalance key from node [cacheName=" + cctx.name() + ", key=" + key + ", part=" + part + ", node=" + pick.id() + ", locId=" + cctx.nodeId() + ']');
} else if (locPart.state() != OWNING)
invalidParts.add(part);
else {
if (log.isTraceEnabled())
log.trace("Will not rebalance key (local partition is not MOVING) [cacheName=" + cctx.name() + ", key=" + key + ", part=" + locPart + ", locId=" + cctx.nodeId() + ']');
}
return mappings;
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition in project ignite by apache.
the class GridDhtPreloader method generateAssignments.
/**
* {@inheritDoc}
*/
@Override
public GridDhtPreloaderAssignments generateAssignments(GridDhtPartitionExchangeId exchId, GridDhtPartitionsExchangeFuture exchFut) {
assert exchFut == null || exchFut.isDone();
// No assignments for disabled preloader.
GridDhtPartitionTopology top = grp.topology();
if (!grp.rebalanceEnabled())
return new GridDhtPreloaderAssignments(exchId, top.readyTopologyVersion(), false);
int partitions = grp.affinity().partitions();
AffinityTopologyVersion topVer = top.readyTopologyVersion();
assert exchFut == null || exchFut.context().events().topologyVersion().equals(top.readyTopologyVersion()) || exchFut.context().events().topologyVersion().equals(ctx.exchange().lastAffinityChangedTopologyVersion(top.readyTopologyVersion())) : "Topology version mismatch [exchId=" + exchId + ", grp=" + grp.name() + ", topVer=" + top.readyTopologyVersion() + ']';
GridDhtPreloaderAssignments assignments = new GridDhtPreloaderAssignments(exchId, topVer, exchFut != null && exchFut.affinityReassign());
AffinityAssignment aff = grp.affinity().cachedAffinity(topVer);
CachePartitionFullCountersMap countersMap = grp.topology().fullUpdateCounters();
for (int p = 0; p < partitions; p++) {
if (ctx.exchange().hasPendingServerExchange()) {
if (log.isDebugEnabled())
log.debug("Skipping assignments creation, exchange worker has pending assignments: " + exchId);
assignments.cancelled(true);
return assignments;
}
// If partition belongs to local node.
if (aff.get(p).contains(ctx.localNode())) {
GridDhtLocalPartition part = top.localPartition(p);
assert part != null;
assert part.id() == p;
// Do not rebalance OWNING or LOST partitions.
if (part.state() == OWNING || part.state() == LOST)
continue;
// State should be switched to MOVING during PME.
if (part.state() != MOVING) {
throw new AssertionError("Partition has invalid state for rebalance " + aff.topologyVersion() + " " + part);
}
ClusterNode histSupplier = null;
if (grp.persistenceEnabled() && exchFut != null) {
List<UUID> nodeIds = exchFut.partitionHistorySupplier(grp.groupId(), p, part.initialUpdateCounter());
if (!F.isEmpty(nodeIds))
histSupplier = ctx.discovery().node(nodeIds.get(p % nodeIds.size()));
}
if (histSupplier != null && !exchFut.isClearingPartition(grp, p)) {
assert grp.persistenceEnabled();
assert remoteOwners(p, topVer).contains(histSupplier) : remoteOwners(p, topVer);
GridDhtPartitionDemandMessage msg = assignments.get(histSupplier);
if (msg == null) {
assignments.put(histSupplier, msg = new GridDhtPartitionDemandMessage(top.updateSequence(), assignments.topologyVersion(), grp.groupId()));
}
// TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11790
msg.partitions().addHistorical(p, part.initialUpdateCounter(), countersMap.updateCounter(p), partitions);
} else {
int partId = p;
List<ClusterNode> picked = remoteOwners(p, topVer, (node, owners) -> {
if (owners.size() == 1)
return true;
return exchFut == null || exchFut.isNodeApplicableForFullRebalance(node.id(), grp.groupId(), partId);
});
if (!picked.isEmpty()) {
ClusterNode n = picked.get(p % picked.size());
GridDhtPartitionDemandMessage msg = assignments.get(n);
if (msg == null) {
assignments.put(n, msg = new GridDhtPartitionDemandMessage(top.updateSequence(), assignments.topologyVersion(), grp.groupId()));
}
msg.partitions().addFull(p);
}
}
}
}
if (!assignments.isEmpty()) {
if (exchFut != null && exchFut.rebalanced()) {
GridDhtPartitionDemandMessage first = assignments.values().iterator().next();
GridDhtLocalPartition locPart = grp.topology().localPartition(first.partitions().all().iterator().next());
SB buf = new SB(1024);
buf.a("Unexpected rebalance on rebalanced cluster: assignments=");
buf.a(assignments);
buf.a(", locPart=");
if (locPart != null)
locPart.dumpDebugInfo(buf);
else
buf.a("NA");
throw new AssertionError(buf.toString());
}
ctx.database().lastCheckpointInapplicableForWalRebalance(grp.groupId());
}
return assignments;
}
Aggregations