use of org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot in project ignite by apache.
the class GridNearTxLocal method requestSnapshot.
/**
* Requests version on coordinator.
*
* @return Future to wait for result.
*/
public IgniteInternalFuture<MvccSnapshot> requestSnapshot() {
if (isRollbackOnly())
return new GridFinishedFuture<>(rollbackException());
MvccSnapshot mvccSnapshot0 = mvccSnapshot;
if (mvccSnapshot0 != null)
return new GridFinishedFuture<>(mvccSnapshot0);
MvccProcessor prc = cctx.coordinators();
MvccCoordinator crd = prc.currentCoordinator();
synchronized (this) {
this.crdVer = crd.version();
}
if (crd.local())
mvccSnapshot0 = prc.requestWriteSnapshotLocal();
if (mvccSnapshot0 == null) {
MvccSnapshotFuture fut = new MvccTxSnapshotFuture();
prc.requestWriteSnapshotAsync(crd, fut);
return fut;
}
GridFutureAdapter<MvccSnapshot> fut = new GridFutureAdapter<>();
onResponse0(mvccSnapshot0, fut);
return fut;
}
use of org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot in project ignite by apache.
the class ValidateIndexesClosure method mvccSession.
/**
* Get session with MVCC snapshot and QueryContext.
*
* @param cctx Cache context.
* @return Session with QueryContext and MVCC snapshot.
* @throws IgniteCheckedException If failed.
*/
private Session mvccSession(GridCacheContext<?, ?> cctx) throws IgniteCheckedException {
Session session = null;
boolean mvccEnabled = cctx.mvccEnabled();
if (mvccEnabled) {
ConnectionManager connMgr = ((IgniteH2Indexing) ignite.context().query().getIndexing()).connections();
JdbcConnection connection = (JdbcConnection) connMgr.connection().connection();
session = (Session) connection.getSession();
MvccQueryTracker tracker = MvccUtils.mvccTracker(cctx, true);
MvccSnapshot mvccSnapshot = tracker.snapshot();
final QueryContext qctx = new QueryContext(0, cacheName -> null, null, mvccSnapshot, null, true);
session.setVariable(H2Utils.QCTX_VARIABLE_NAME, new H2Utils.ValueRuntimeSimpleObject<>(qctx));
}
return session;
}
use of org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot in project ignite by apache.
the class H2PkHashIndex method find.
/**
* {@inheritDoc}
*/
@Override
public Cursor find(Session ses, final SearchRow lower, final SearchRow upper) {
IndexingQueryCacheFilter filter = null;
MvccSnapshot mvccSnapshot = null;
QueryContext qctx = H2Utils.context(ses);
int seg = 0;
if (qctx != null) {
IndexingQueryFilter f = qctx.filter();
filter = f != null ? f.forCache(getTable().cacheName()) : null;
mvccSnapshot = qctx.mvccSnapshot();
seg = qctx.segment();
}
assert !cctx.mvccEnabled() || mvccSnapshot != null;
KeyCacheObject lowerObj = lower != null ? cctx.toCacheKeyObject(lower.getValue(0).getObject()) : null;
KeyCacheObject upperObj = upper != null ? cctx.toCacheKeyObject(upper.getValue(0).getObject()) : null;
try {
CacheDataRowStore.setSkipVersion(true);
Collection<GridCursor<? extends CacheDataRow>> cursors = new ArrayList<>();
for (IgniteCacheOffheapManager.CacheDataStore store : cctx.offheap().cacheDataStores()) {
int part = store.partId();
if (segmentForPartition(part) != seg)
continue;
if (filter == null || filter.applyPartition(part))
cursors.add(store.cursor(cctx.cacheId(), lowerObj, upperObj, null, mvccSnapshot));
}
return new H2PkHashIndexCursor(cursors.iterator());
} catch (IgniteCheckedException e) {
throw DbException.convert(e);
} finally {
CacheDataRowStore.setSkipVersion(false);
}
}
use of org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot in project ignite by apache.
the class GridDhtTxPrepareFuture method sendPrepareRequests.
/**
*/
private void sendPrepareRequests() {
assert !tx.txState().mvccEnabled() || !tx.onePhaseCommit() || tx.mvccSnapshot() != null;
int miniId = 0;
assert tx.transactionNodes() != null;
final long timeout = timeoutObj != null ? timeoutObj.timeout : 0;
// Do not need process active transactions on backups.
MvccSnapshot mvccSnapshot = tx.mvccSnapshot();
if (mvccSnapshot != null)
mvccSnapshot = mvccSnapshot.withoutActiveTransactions();
// Create mini futures.
for (GridDistributedTxMapping dhtMapping : tx.dhtMap().values()) {
assert !dhtMapping.empty() || dhtMapping.queryUpdate();
ClusterNode n = dhtMapping.primary();
assert !n.isLocal();
GridDistributedTxMapping nearMapping = tx.nearMap().get(n.id());
Collection<IgniteTxEntry> nearWrites = nearMapping == null ? null : nearMapping.writes();
Collection<IgniteTxEntry> dhtWrites = dhtMapping.writes();
if (!dhtMapping.queryUpdate() && F.isEmpty(dhtWrites) && F.isEmpty(nearWrites))
continue;
MiniFuture fut = new MiniFuture(n.id(), ++miniId, dhtMapping, nearMapping);
// Append new future.
add(fut);
assert req.transactionNodes() != null;
GridDhtTxPrepareRequest req = new GridDhtTxPrepareRequest(futId, fut.futureId(), tx.topologyVersion(), tx, timeout, dhtWrites, nearWrites, this.req.transactionNodes(), tx.nearXidVersion(), true, tx.onePhaseCommit(), tx.taskNameHash(), tx.activeCachesDeploymentEnabled(), tx.storeWriteThrough(), retVal, mvccSnapshot, cctx.tm().txHandler().filterUpdateCountersForBackupNode(tx, n));
req.queryUpdate(dhtMapping.queryUpdate());
int idx = 0;
for (IgniteTxEntry entry : dhtWrites) {
try {
GridDhtCacheEntry cached = (GridDhtCacheEntry) entry.cached();
GridCacheContext<?, ?> cacheCtx = cached.context();
// Do not invalidate near entry on originating transaction node.
req.invalidateNearEntry(idx, !tx.nearNodeId().equals(n.id()) && cached.readerId(n.id()) != null);
if (cached.isNewLocked()) {
List<ClusterNode> owners = cacheCtx.topology().owners(cached.partition(), tx != null ? tx.topologyVersion() : cacheCtx.affinity().affinityTopologyVersion());
// Do not preload if local node is a partition owner.
if (!owners.contains(cctx.localNode()))
req.markKeyForPreload(idx);
}
break;
} catch (GridCacheEntryRemovedException e) {
log.error("Got removed exception on entry with dht local candidate. Transaction will be " + "rolled back. Entry: " + entry + " tx: " + CU.txDump(tx), e);
// Entry was unlocked by concurrent rollback.
onError(tx.rollbackException());
}
idx++;
}
if (!F.isEmpty(nearWrites)) {
for (IgniteTxEntry entry : nearWrites) {
try {
if (entry.explicitVersion() == null) {
GridCacheMvccCandidate added = entry.cached().candidate(version());
assert added != null : "Missing candidate for cache entry:" + entry;
assert added.dhtLocal();
if (added.ownerVersion() != null)
req.owned(entry.txKey(), added.ownerVersion());
}
break;
} catch (GridCacheEntryRemovedException e) {
log.error("Got removed exception on entry with dht local candidate. Transaction will be " + "rolled back. Entry: " + entry + " tx: " + CU.txDump(tx), e);
// Entry was unlocked by concurrent rollback.
onError(tx.rollbackException());
}
}
}
assert req.transactionNodes() != null;
try {
cctx.io().send(n, req, tx.ioPolicy());
if (msgLog.isDebugEnabled()) {
msgLog.debug("DHT prepare fut, sent request dht [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + n.id() + ']');
}
} catch (ClusterTopologyCheckedException ignored) {
fut.onNodeLeft();
} catch (IgniteCheckedException e) {
if (msgLog.isDebugEnabled()) {
msgLog.debug("DHT prepare fut, failed to send request dht [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + n.id() + ']');
}
fut.onResult(e);
}
}
for (GridDistributedTxMapping nearMapping : tx.nearMap().values()) {
if (!tx.dhtMap().containsKey(nearMapping.primary().id())) {
if (tx.remainingTime() == -1)
return;
MiniFuture fut = new MiniFuture(nearMapping.primary().id(), ++miniId, null, nearMapping);
// Append new future.
add(fut);
GridDhtTxPrepareRequest req = new GridDhtTxPrepareRequest(futId, fut.futureId(), tx.topologyVersion(), tx, timeout, null, nearMapping.writes(), tx.transactionNodes(), tx.nearXidVersion(), true, tx.onePhaseCommit(), tx.taskNameHash(), tx.activeCachesDeploymentEnabled(), tx.storeWriteThrough(), retVal, mvccSnapshot, null);
for (IgniteTxEntry entry : nearMapping.entries()) {
if (CU.writes().apply(entry)) {
try {
if (entry.explicitVersion() == null) {
GridCacheMvccCandidate added = entry.cached().candidate(version());
assert added != null : "Null candidate for non-group-lock entry " + "[added=" + added + ", entry=" + entry + ']';
assert added.dhtLocal() : "Got non-dht-local candidate for prepare future" + "[added=" + added + ", entry=" + entry + ']';
if (added != null && added.ownerVersion() != null)
req.owned(entry.txKey(), added.ownerVersion());
}
break;
} catch (GridCacheEntryRemovedException e) {
log.error("Got removed exception on entry with dht local candidate. Transaction will be " + "rolled back. Entry: " + entry + " tx: " + CU.txDump(tx), e);
// Entry was unlocked by concurrent rollback.
onError(tx.rollbackException());
}
}
}
assert req.transactionNodes() != null;
try {
cctx.io().send(nearMapping.primary(), req, tx.ioPolicy());
if (msgLog.isDebugEnabled()) {
msgLog.debug("DHT prepare fut, sent request near [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + nearMapping.primary().id() + ']');
}
} catch (ClusterTopologyCheckedException ignored) {
fut.onNodeLeft();
} catch (IgniteCheckedException e) {
if (!cctx.kernalContext().isStopping()) {
if (msgLog.isDebugEnabled()) {
msgLog.debug("DHT prepare fut, failed to send request near [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + nearMapping.primary().id() + ']');
}
fut.onResult(e);
} else {
if (msgLog.isDebugEnabled()) {
msgLog.debug("DHT prepare fut, failed to send request near, ignore [txId=" + tx.nearXidVersion() + ", dhtTxId=" + tx.xidVersion() + ", node=" + nearMapping.primary().id() + ", err=" + e + ']');
}
}
}
}
}
}
use of org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot in project ignite by apache.
the class GridPartitionedGetFuture method map.
/**
* @param keys Keys.
* @param mapped Mappings to check for duplicates.
* @param topVer Topology version on which keys should be mapped.
*/
@Override
protected void map(Collection<KeyCacheObject> keys, Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mapped, AffinityTopologyVersion topVer) {
GridDhtPartitionsExchangeFuture fut = cctx.shared().exchange().lastTopologyFuture();
// Finished DHT future is required for topology validation.
if (!fut.isDone()) {
if (fut.initialVersion().after(topVer) || (fut.exchangeActions() != null && fut.exchangeActions().hasStop()))
fut = cctx.shared().exchange().lastFinishedFuture();
else {
fut.listen(new IgniteInClosure<IgniteInternalFuture<AffinityTopologyVersion>>() {
@Override
public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
if (fut.error() != null)
onDone(fut.error());
else {
cctx.closures().runLocalSafe(new GridPlainRunnable() {
@Override
public void run() {
map(keys, mapped, topVer);
}
}, true);
}
}
});
return;
}
}
Collection<ClusterNode> cacheNodes = CU.affinityNodes(cctx, topVer);
validate(cacheNodes, fut);
// Future can be already done with some exception.
if (isDone())
return;
Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings = U.newHashMap(cacheNodes.size());
int keysSize = keys.size();
// Map for local (key,value) pairs.
Map<K, V> locVals = U.newHashMap(keysSize);
// True if we have remote nodes after key mapping complete.
boolean hasRmtNodes = false;
// Assign keys to nodes.
for (KeyCacheObject key : keys) hasRmtNodes |= map(key, topVer, mappings, mapped, locVals);
// Future can be alredy done with some exception.
if (isDone())
return;
// Add local read (key,value) in result.
if (!locVals.isEmpty())
add(new GridFinishedFuture<>(locVals));
// If we have remote nodes in mapping we should registrate future in mvcc manager.
if (hasRmtNodes)
registrateFutureInMvccManager(this);
// Create mini futures after mapping to remote nodes.
for (Map.Entry<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> entry : mappings.entrySet()) {
// Node for request.
ClusterNode n = entry.getKey();
// Keys for request.
LinkedHashMap<KeyCacheObject, Boolean> mappedKeys = entry.getValue();
assert !mappedKeys.isEmpty();
// If this is the primary or backup node for the keys.
if (n.isLocal()) {
GridDhtFuture<Collection<GridCacheEntryInfo>> fut0 = cache().getDhtAsync(n.id(), -1, mappedKeys, false, readThrough, topVer, taskName == null ? 0 : taskName.hashCode(), expiryPlc, skipVals, recovery, txLbl, mvccSnapshot());
Collection<Integer> invalidParts = fut0.invalidPartitions();
if (!F.isEmpty(invalidParts)) {
Collection<KeyCacheObject> remapKeys = new ArrayList<>(keysSize);
for (KeyCacheObject key : keys) {
int part = cctx.affinity().partition(key);
if (key != null && invalidParts.contains(part)) {
addNodeAsInvalid(n, part, topVer);
remapKeys.add(key);
}
}
AffinityTopologyVersion updTopVer = cctx.shared().exchange().readyAffinityVersion();
// Remap recursively.
map(remapKeys, mappings, updTopVer);
}
// Add new future.
add(fut0.chain(f -> {
try {
return createResultMap(f.get());
} catch (Exception e) {
U.error(log, "Failed to get values from dht cache [fut=" + fut0 + "]", e);
onDone(e);
return Collections.emptyMap();
}
}));
} else {
MiniFuture miniFut = new MiniFuture(n, mappedKeys, topVer);
GridCacheMessage req = miniFut.createGetRequest(futId);
// Append new future.
add(miniFut);
try {
cctx.io().send(n, req, cctx.ioPolicy());
} catch (IgniteCheckedException e) {
// Fail the whole thing.
if (e instanceof ClusterTopologyCheckedException)
miniFut.onNodeLeft((ClusterTopologyCheckedException) e);
else
miniFut.onResult(e);
}
}
}
markInitialized();
}
Aggregations