Search in sources :

Example 16 with RegionVersionVector

use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.

the class EventTracker method recordEvent.

/** record the event's threadid/sequenceid to prevent replay */
public void recordEvent(InternalCacheEvent event) {
    EventID eventID = event.getEventId();
    if (ignoreEvent(event, eventID)) {
        // not tracked
        return;
    }
    LocalRegion lr = (LocalRegion) event.getRegion();
    ThreadIdentifier membershipID = new ThreadIdentifier(eventID.getMembershipID(), eventID.getThreadID());
    VersionTag tag = null;
    if (lr.getServerProxy() == null) /* && event.hasClientOrigin() */
    {
        // clients do not need to
        // store version tags for
        // replayed events
        tag = event.getVersionTag();
        RegionVersionVector v = ((LocalRegion) event.getRegion()).getVersionVector();
        // bug #46453 - make sure ID references are canonical before storing
        if (v != null && tag != null) {
            tag.setMemberID(v.getCanonicalId(tag.getMemberID()));
            if (tag.getPreviousMemberID() != null) {
                tag.setPreviousMemberID(v.getCanonicalId(tag.getPreviousMemberID()));
            }
        }
    }
    EventSeqnoHolder newEvh = new EventSeqnoHolder(eventID.getSequenceID(), tag);
    if (logger.isTraceEnabled()) {
        logger.trace("region event tracker recording {}", event);
    }
    recordSeqno(membershipID, newEvh);
    // recordedBulkOpVersionTags
    if (lr.getConcurrencyChecksEnabled() && (event.getOperation().isPutAll() || event.getOperation().isRemoveAll()) && lr.getServerProxy() == null) {
        recordBulkOpEvent(event, membershipID);
    }
}
Also used : ThreadIdentifier(org.apache.geode.internal.cache.ha.ThreadIdentifier) VersionTag(org.apache.geode.internal.cache.versions.VersionTag) RegionVersionVector(org.apache.geode.internal.cache.versions.RegionVersionVector)

Example 17 with RegionVersionVector

use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.

the class EventTracker method recordBulkOpEvent.

/**
   * Record a version tag for a bulk operation
   */
private void recordBulkOpEvent(InternalCacheEvent event, ThreadIdentifier tid) {
    EventID eventID = event.getEventId();
    VersionTag tag = event.getVersionTag();
    if (tag == null) {
        return;
    }
    if (logger.isDebugEnabled()) {
        logger.debug("recording bulkOp event {} {} {} op={}", tid.expensiveToString(), eventID, tag, event.getOperation());
    }
    RegionVersionVector v = ((LocalRegion) event.getRegion()).getVersionVector();
    // bug #46453 - make sure ID references are canonical before storing
    if (v != null) {
        tag.setMemberID(v.getCanonicalId(tag.getMemberID()));
        if (tag.getPreviousMemberID() != null) {
            tag.setPreviousMemberID(v.getCanonicalId(tag.getPreviousMemberID()));
        }
    }
    // Loop until we can successfully update the recorded bulk operations
    // For this thread id.
    boolean retry = false;
    do {
        BulkOpHolder bulkOpTracker = recordedBulkOpVersionTags.get(tid);
        if (bulkOpTracker == null) {
            bulkOpTracker = new BulkOpHolder();
            BulkOpHolder old = recordedBulkOpVersionTags.putIfAbsent(tid, bulkOpTracker);
            if (old != null) {
                retry = true;
                continue;
            }
        }
        synchronized (bulkOpTracker) {
            if (bulkOpTracker.removed) {
                retry = true;
                continue;
            }
            // Add the version tag for bulkOp event.
            bulkOpTracker.putVersionTag(eventID, event.getVersionTag());
            retry = false;
        }
    } while (retry);
}
Also used : VersionTag(org.apache.geode.internal.cache.versions.VersionTag) RegionVersionVector(org.apache.geode.internal.cache.versions.RegionVersionVector)

Example 18 with RegionVersionVector

use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.

the class AbstractRegionEntry method initialImageInit.

@Override
public boolean initialImageInit(final LocalRegion region, final long lastModified, final Object newValue, final boolean create, final boolean wasRecovered, final boolean acceptedVersionTag) throws RegionClearedException {
    // note that the caller has already write synced this RegionEntry
    boolean result = false;
    // if it has been destroyed then don't do anything
    Token vTok = getValueAsToken();
    if (acceptedVersionTag || create || (vTok != Token.DESTROYED || vTok != Token.TOMBSTONE)) {
        // OFFHEAP noop
        Object newValueToWrite = newValue;
        // OFFHEAP noop
        boolean putValue = acceptedVersionTag || create || (newValueToWrite != Token.LOCAL_INVALID && (wasRecovered || (vTok == Token.LOCAL_INVALID)));
        if (region.isUsedForPartitionedRegionAdmin() && newValueToWrite instanceof CachedDeserializable) {
            // Special case for partitioned region meta data
            // We do not need the RegionEntry on this case.
            // Because the pr meta data region will not have an LRU.
            newValueToWrite = ((CachedDeserializable) newValueToWrite).getDeserializedValue(region, null);
            if (!create && newValueToWrite instanceof Versionable) {
                // Heap value should always be deserialized at this point // OFFHEAP will not be
                // deserialized
                final Object oldValue = getValueInVM(region);
                // BUGFIX for 35029. If oldValue is null the newValue should be put.
                if (oldValue == null) {
                    putValue = true;
                } else if (oldValue instanceof Versionable) {
                    Versionable nv = (Versionable) newValueToWrite;
                    Versionable ov = (Versionable) oldValue;
                    putValue = nv.isNewerThan(ov);
                }
            }
        }
        if (putValue) {
            // and current value is recovered
            if (create || acceptedVersionTag) {
                // At this point, since we now always recover from disk first,
                // we only care about "isCreate" since "isRecovered" is impossible
                // if we had a regionInvalidate or regionClear
                ImageState imageState = region.getImageState();
                // this method is called during loadSnapshot as well as getInitialImage
                if (imageState.getRegionInvalidated()) {
                    if (newValueToWrite != Token.TOMBSTONE) {
                        newValueToWrite = Token.INVALID;
                    }
                } else if (imageState.getClearRegionFlag()) {
                    boolean entryOK = false;
                    RegionVersionVector rvv = imageState.getClearRegionVersionVector();
                    if (rvv != null) {
                        // a filtered clear
                        VersionSource id = getVersionStamp().getMemberID();
                        if (id == null) {
                            id = region.getVersionMember();
                        }
                        if (!rvv.contains(id, getVersionStamp().getRegionVersion())) {
                            entryOK = true;
                        }
                    }
                    if (!entryOK) {
                        // If the region has been issued cleared during
                        // the GII , then those entries loaded before this one would have
                        // been cleared from the Map due to clear operation & for the
                        // currententry whose key may have escaped the clearance , will be
                        // cleansed by the destroy token.
                        // TODO: never used
                        newValueToWrite = Token.DESTROYED;
                        imageState.addDestroyedEntry(this.getKey());
                        throw new RegionClearedException(LocalizedStrings.AbstractRegionEntry_DURING_THE_GII_PUT_OF_ENTRY_THE_REGION_GOT_CLEARED_SO_ABORTING_THE_OPERATION.toLocalizedString());
                    }
                }
            }
            setValue(region, this.prepareValueForCache(region, newValueToWrite, false));
            result = true;
            if (newValueToWrite != Token.TOMBSTONE) {
                if (create) {
                    region.getCachePerfStats().incCreates();
                }
                region.updateStatsForPut(this, lastModified, false);
            }
            if (logger.isTraceEnabled()) {
                if (newValueToWrite instanceof CachedDeserializable) {
                    logger.trace("ProcessChunk: region={}; put a CachedDeserializable ({},{})", region.getFullPath(), getKey(), ((CachedDeserializable) newValueToWrite).getStringForm());
                } else {
                    logger.trace("ProcessChunk: region={}; put({},{})", region.getFullPath(), getKey(), StringUtils.forceToString(newValueToWrite));
                }
            }
        }
    }
    return result;
}
Also used : Versionable(org.apache.geode.internal.util.Versionable) VersionSource(org.apache.geode.internal.cache.versions.VersionSource) StoredObject(org.apache.geode.internal.offheap.StoredObject) RegionVersionVector(org.apache.geode.internal.cache.versions.RegionVersionVector)

Example 19 with RegionVersionVector

use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.

the class DistributedRegion method getInitialImageAndRecovery.

// TODO: cleanup getInitialImageAndRecovery
private void getInitialImageAndRecovery(InputStream snapshotInputStream, InternalDistributedMember imageSrc, InternalRegionArguments internalRegionArgs, boolean recoverFromDisk, PersistentMemberID persistentId) throws TimeoutException {
    logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZING_REGION_0, this.getName()));
    ImageState imgState = getImageState();
    imgState.init();
    boolean targetRecreated = internalRegionArgs.getRecreateFlag();
    Boolean isCBool = (Boolean) isConversion.get();
    boolean isForConversion = isCBool != null ? isCBool : false;
    if (recoverFromDisk && snapshotInputStream != null && !isForConversion) {
        throw new InternalGemFireError(LocalizedStrings.DistributedRegion_IF_LOADING_A_SNAPSHOT_THEN_SHOULD_NOT_BE_RECOVERING_ISRECOVERING_0_SNAPSHOTSTREAM_1.toLocalizedString(new Object[] { true, snapshotInputStream }));
    }
    ProfileExchangeProcessor targetProvider;
    if (this.dataPolicy.withPersistence()) {
        targetProvider = new CreatePersistentRegionProcessor(this, getPersistenceAdvisor(), recoverFromDisk);
    } else {
        // this will go in the advisor profile
        targetProvider = new CreateRegionProcessor(this);
    }
    imgState.setInRecovery(false);
    RegionVersionVector recovered_rvv = null;
    if (this.dataPolicy.withPersistence()) {
        recovered_rvv = this.getVersionVector() == null ? null : this.getVersionVector().getCloneForTransmission();
    }
    // initializeRegion will send out our profile
    targetProvider.initializeRegion();
    if (this.persistenceAdvisor != null) {
        this.persistenceAdvisor.initialize();
    }
    // remote members
    if (!isInternalRegion()) {
        if (!this.isDestroyed) {
            this.cache.getInternalResourceManager().addResourceListener(ResourceType.MEMORY, this);
        }
    }
    releaseBeforeGetInitialImageLatch();
    // allow GII to invoke test hooks. Do this just after releasing the
    // before-gii latch for bug #48962. See ConcurrentLeaveDuringGIIDUnitTest
    InitialImageOperation.beforeGetInitialImage(this);
    if (snapshotInputStream != null) {
        try {
            if (logger.isDebugEnabled()) {
                logger.debug("DistributedRegion.getInitialImageAndRecovery: About to load snapshot, isInitialized={}; {}", isInitialized(), getFullPath());
            }
            loadSnapshotDuringInitialization(snapshotInputStream);
        } catch (IOException e) {
            // TODO: change this exception?
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            // TODO: change this exception?
            throw new RuntimeException(e);
        }
        cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus.NO_GII);
        return;
    }
    // No snapshot provided, use the imageTarget(s)
    // if we were given a recommended imageTarget, use that first, and
    // treat it like it is a replicate (regardless of whether it actually is
    // or not)
    InitialImageOperation iiop = new InitialImageOperation(this, this.entries);
    CacheDistributionAdvisor.InitialImageAdvice advice = null;
    boolean done = false;
    while (!done && !isDestroyed()) {
        advice = targetProvider.getInitialImageAdvice(advice);
        boolean attemptGetFromOne = // we were given a specific member
        imageSrc != null || // this is a preloaded
        this.dataPolicy.withPreloaded() && !advice.preloaded.isEmpty() || // region
        (!advice.replicates.isEmpty());
        if (attemptGetFromOne) {
            if (recoverFromDisk) {
                if (LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER) {
                    CacheObserverHolder.getInstance().afterMarkingGIIStarted();
                }
            }
            {
                // Plan A: use specified imageSrc, if specified
                if (imageSrc != null) {
                    try {
                        GIIStatus ret = iiop.getFromOne(Collections.singleton(imageSrc), targetRecreated, advice, recoverFromDisk, recovered_rvv);
                        if (GIIStatus.didGII(ret)) {
                            this.giiMissingRequiredRoles = false;
                            cleanUpDestroyedTokensAndMarkGIIComplete(ret);
                            done = true;
                            return;
                        }
                    } finally {
                        imageSrc = null;
                    }
                }
                // Plan C: use a replicate, if one exists
                GIIStatus ret = iiop.getFromOne(advice.replicates, false, advice, recoverFromDisk, recovered_rvv);
                if (GIIStatus.didGII(ret)) {
                    cleanUpDestroyedTokensAndMarkGIIComplete(ret);
                    done = true;
                    return;
                }
                // Plan D: if this is a PRELOADED region, fetch from another PRELOADED
                if (this.dataPolicy.isPreloaded()) {
                    GIIStatus ret_preload = iiop.getFromOne(advice.preloaded, false, advice, recoverFromDisk, recovered_rvv);
                    if (GIIStatus.didGII(ret_preload)) {
                        cleanUpDestroyedTokensAndMarkGIIComplete(ret_preload);
                        done = true;
                        return;
                    }
                }
            // isPreloaded
            }
            // If we got to this point, we failed in the GII. Cleanup
            // any partial image we received
            cleanUpAfterFailedGII(recoverFromDisk);
        } else // attemptGetFromOne
        {
            if (!isDestroyed()) {
                if (recoverFromDisk) {
                    logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZED_FROM_DISK, new Object[] { this.getFullPath(), persistentId, getPersistentID() }));
                    if (persistentId != null) {
                        RegionLogger.logRecovery(this.getFullPath(), persistentId, getDistributionManager().getDistributionManagerId());
                    }
                } else {
                    RegionLogger.logCreate(this.getFullPath(), getDistributionManager().getDistributionManagerId());
                    if (getPersistentID() != null) {
                        RegionLogger.logPersistence(this.getFullPath(), getDistributionManager().getDistributionManagerId(), getPersistentID());
                        logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_NEW_PERSISTENT_REGION_CREATED, new Object[] { this.getFullPath(), getPersistentID() }));
                    }
                }
                cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus.NO_GII);
                done = true;
                return;
            }
            break;
        }
    }
}
Also used : RegionVersionVector(org.apache.geode.internal.cache.versions.RegionVersionVector) IOException(java.io.IOException) GIIStatus(org.apache.geode.internal.cache.InitialImageOperation.GIIStatus) CreatePersistentRegionProcessor(org.apache.geode.internal.cache.persistence.CreatePersistentRegionProcessor) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) InternalGemFireError(org.apache.geode.InternalGemFireError)

Example 20 with RegionVersionVector

use of org.apache.geode.internal.cache.versions.RegionVersionVector in project geode by apache.

the class DistributedRegion method cleanUpDestroyedTokensAndMarkGIIComplete.

// called by InitialImageOperation to clean up destroyed tokens
// release afterGetInitialImageInitializationLatch before unlocking
// cleanUpLock
@SuppressWarnings("UL_UNRELEASED_LOCK")
protected void cleanUpDestroyedTokensAndMarkGIIComplete(GIIStatus giiStatus) {
    // We need to clean up the disk before we release the after get initial image latch
    DiskRegion dskRgn = getDiskRegion();
    if (dskRgn != null && dskRgn.isBackup()) {
        dskRgn.finishInitializeOwner(this, giiStatus);
    }
    ImageState is = getImageState();
    is.lockGII();
    // clear the version tag and left-members sets
    is.getVersionTags();
    is.getLeftMembers();
    // remove DESTROYED tokens
    RegionVersionVector rvv = is.getClearRegionVersionVector();
    try {
        Iterator /* <Object> */
        keysIt = getImageState().getDestroyedEntries();
        while (keysIt.hasNext()) {
            this.entries.removeIfDestroyed(keysIt.next());
        }
        if (rvv != null) {
            // clear any entries received in the GII that are older than the RVV versions.
            // this can happen if entry chunks were received prior to the clear() being
            // processed
            clearEntries(rvv);
        }
        // need to do this before we release the afterGetInitialImageLatch
        if (this.persistenceAdvisor != null) {
            this.persistenceAdvisor.setOnline(GIIStatus.didGII(giiStatus), false, getPersistentID());
        }
    } finally {
        // when they get the cleanUp lock.
        try {
            releaseAfterGetInitialImageLatch();
        } finally {
            // make sure unlockGII is done for bug 40001
            is.unlockGII();
        }
    }
    if (LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER) {
        CacheObserverHolder.getInstance().afterMarkingGIICompleted();
    }
    // "Initializing region {0}" which is not acompanied by a completed message. Users think thread
    // is stuck in some operation. Hence adding this log
    logger.info(LocalizedMessage.create(LocalizedStrings.DistributedRegion_INITIALIZING_REGION_COMPLETED_0, this.getName()));
}
Also used : Iterator(java.util.Iterator) RegionVersionVector(org.apache.geode.internal.cache.versions.RegionVersionVector)

Aggregations

RegionVersionVector (org.apache.geode.internal.cache.versions.RegionVersionVector)52 DiskStoreID (org.apache.geode.internal.cache.persistence.DiskStoreID)19 DistributedTest (org.apache.geode.test.junit.categories.DistributedTest)17 Test (org.junit.Test)17 FlakyTest (org.apache.geode.test.junit.categories.FlakyTest)16 VersionTag (org.apache.geode.internal.cache.versions.VersionTag)15 HeapDataOutputStream (org.apache.geode.internal.HeapDataOutputStream)7 ByteArrayInputStream (java.io.ByteArrayInputStream)6 DataInputStream (java.io.DataInputStream)6 VersionSource (org.apache.geode.internal.cache.versions.VersionSource)6 Cache (org.apache.geode.cache.Cache)5 LocalRegion (org.apache.geode.internal.cache.LocalRegion)5 Host (org.apache.geode.test.dunit.Host)4 VM (org.apache.geode.test.dunit.VM)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 CacheClosedException (org.apache.geode.cache.CacheClosedException)3 RegionDestroyedException (org.apache.geode.cache.RegionDestroyedException)3 IOException (java.io.IOException)2