Search in sources :

Example 1 with DiskAccessException

use of org.apache.geode.cache.DiskAccessException in project geode by apache.

the class Bug39079DUnitTest method testGIIDiskAccessException.

/**
   * If the node experiences disk access exception during GII, it should get destroyed & not attempt
   * to recover from the disk
   */
@Test
public void testGIIDiskAccessException() throws Exception {
    vm0.invoke(createCacheForVM0());
    vm1.invoke(createCacheForVM1());
    // Create DiskRegion locally in controller VM also
    getSystem();
    assertTrue(getCache() != null);
    AttributesFactory factory = new AttributesFactory();
    factory.setScope(Scope.DISTRIBUTED_ACK);
    factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
    factory.setDiskSynchronous(false);
    factory.setDiskStoreName(getCache().createDiskStoreFactory().setDiskDirs(getDiskDirs()).create(getClass().getSimpleName()).getName());
    RegionAttributes attr = factory.create();
    Region region = getCache().createRegion(REGION_NAME_testGIIDiskAccessException, attr);
    // Now put entries in the disk region
    for (int i = 0; i < 100; ++i) {
        region.put(new Integer(i), new Integer(i));
    }
    // Now close the region in the controller VM
    region.close();
    // Now recreate the region but set the factory such that disk region entry object
    // used is customized by us to throw exception while writing to disk
    DistributedRegion distRegion = new DistributedRegion(REGION_NAME_testGIIDiskAccessException, attr, null, (GemFireCacheImpl) getCache(), new InternalRegionArguments().setDestroyLockFlag(true).setRecreateFlag(false).setSnapshotInputStream(null).setImageTarget(null));
    distRegion.entries.setEntryFactory(TestAbstractDiskRegionEntry.getEntryFactory());
    region = null;
    try {
        region = ((GemFireCacheImpl) getCache()).createVMRegion(REGION_NAME_testGIIDiskAccessException, attr, new InternalRegionArguments().setInternalMetaRegion(distRegion).setDestroyLockFlag(true).setSnapshotInputStream(null).setImageTarget(null));
        fail("Expected DiskAccessException");
    } catch (DiskAccessException expected) {
    }
    // TODO: why is this an OR instead of
    assertTrue(region == null || region.isDestroyed());
// deterministic?
}
Also used : AttributesFactory(org.apache.geode.cache.AttributesFactory) RegionAttributes(org.apache.geode.cache.RegionAttributes) DiskAccessException(org.apache.geode.cache.DiskAccessException) Region(org.apache.geode.cache.Region) Test(org.junit.Test) DistributedTest(org.apache.geode.test.junit.categories.DistributedTest)

Example 2 with DiskAccessException

use of org.apache.geode.cache.DiskAccessException in project geode by apache.

the class DiskRegionJUnitTest method testCompactorClose.

@Test
public void testCompactorClose() throws Exception {
    // "true");
    try {
        // Create a region with rolling enabled.
        DiskRegionProperties props = new DiskRegionProperties();
        props.setRegionName("testCompactorClose");
        props.setRolling(true);
        props.setCompactionThreshold(100);
        props.setDiskDirs(dirs);
        props.setMaxOplogSize(100);
        props.setPersistBackup(true);
        region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, props, Scope.LOCAL);
        final boolean[] foundException = new boolean[] { false };
        final boolean[] regionDestroyed = new boolean[] { false };
        final boolean[] allowCompactorThread = new boolean[] { false };
        LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = true;
        final Object anotherLock = new Object();
        // cause a switch
        CacheObserver old = CacheObserverHolder.setInstance(new CacheObserverAdapter() {

            final AtomicBoolean compactorSignalled = new AtomicBoolean();

            public void beforeGoingToCompact() {
                // wait for operations to get over
                synchronized (anotherLock) {
                    try {
                        if (!allowCompactorThread[0]) {
                            anotherLock.wait();
                        }
                    } catch (Exception e) {
                        foundException[0] = true;
                        e.printStackTrace();
                    }
                }
                this.compactorSignalled.set(false);
            }

            @Override
            public void beforeDeletingCompactedOplog(Oplog oplog) {
                // attempt to destroy the region.
                throw new DiskAccessException("IGNORE_EXCEPTION_testCompactorClose GeneratedException", region);
            }

            @Override
            public void afterStoppingCompactor() {
                synchronized (region) {
                    regionDestroyed[0] = true;
                    region.notify();
                }
            }
        });
        // create some string entries
        for (int i = 0; i < 10; ++i) {
            region.put("" + i, new byte[10]);
        }
        synchronized (anotherLock) {
            anotherLock.notify();
            allowCompactorThread[0] = true;
        }
        synchronized (region) {
            if (!regionDestroyed[0]) {
                region.wait(10000);
                assertTrue(regionDestroyed[0]);
            }
        }
        assertFalse(foundException[0]);
    } finally {
        LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = false;
        CacheObserverHolder.setInstance(new CacheObserverAdapter());
    // System.getProperties().setProperty(DiskStoreImpl.COMPLETE_COMPACTION_BEFORE_TERMINATION_PROPERTY_NAME,
    // "");
    }
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) DiskAccessException(org.apache.geode.cache.DiskAccessException) EntryNotFoundException(org.apache.geode.cache.EntryNotFoundException) DiskAccessException(org.apache.geode.cache.DiskAccessException) Test(org.junit.Test) IntegrationTest(org.apache.geode.test.junit.categories.IntegrationTest)

Example 3 with DiskAccessException

use of org.apache.geode.cache.DiskAccessException in project geode by apache.

the class DiskRegionJUnitTest method entryUpdateInSynchPersistTypeForIOExceptionCase.

/**
   * If IOException occurs while updating an entry in a persist only synch mode, DiskAccessException
   * should occur & region should be destroyed
   * 
   * @throws Exception
   */
private void entryUpdateInSynchPersistTypeForIOExceptionCase(Region region) throws Exception {
    region.create("key1", "value1");
    // Get the oplog handle & hence the underlying file & close it
    UninterruptibleFileChannel oplogFileChannel = ((LocalRegion) region).getDiskRegion().testHook_getChild().getFileChannel();
    oplogFileChannel.close();
    try {
        region.put("key1", "value2");
        fail("Should have encountered DiskAccessException");
    } catch (DiskAccessException dae) {
    // OK
    }
    ((LocalRegion) region).getDiskStore().waitForClose();
    assertTrue(cache.isClosed());
    region = null;
}
Also used : UninterruptibleFileChannel(org.apache.geode.internal.cache.persistence.UninterruptibleFileChannel) DiskAccessException(org.apache.geode.cache.DiskAccessException)

Example 4 with DiskAccessException

use of org.apache.geode.cache.DiskAccessException in project geode by apache.

the class ProxyBucketRegion method recoverFromDisk.

public void recoverFromDisk() {
    final boolean isDebugEnabled = logger.isDebugEnabled();
    RuntimeException exception = null;
    if (isDebugEnabled) {
        logger.debug("{} coming to recover from disk. wasHosting {}", getFullPath(), persistenceAdvisor.wasHosting());
    }
    try {
        if (persistenceAdvisor.wasHosting()) {
            if (isDebugEnabled) {
                logger.debug("{} used to host data. Attempting to recover.", getFullPath());
            }
            CreateBucketResult result;
            if (hasPersistentChildRegion()) {
                // If this is a parent PR, create the bucket, possibly going over
                // redundancy. We need to do this so that we can create the child
                // region in this member. This member may have the latest data for the
                // child region.
                result = partitionedRegion.getDataStore().grabBucket(bid, getDistributionManager().getDistributionManagerId(), true, true, false, null, true);
            } else {
                if (this.partitionedRegion.isShadowPR() && this.partitionedRegion.getColocatedWith() != null) {
                    PartitionedRegion colocatedRegion = ColocationHelper.getColocatedRegion(this.partitionedRegion);
                    if (this.partitionedRegion.getDataPolicy().withPersistence() && !colocatedRegion.getDataPolicy().withPersistence()) {
                        result = colocatedRegion.getDataStore().grabBucket(bid, getDistributionManager().getDistributionManagerId(), true, true, false, null, true);
                        if (result.nowExists()) {
                            result = partitionedRegion.getDataStore().grabBucket(bid, null, true, false, false, null, true);
                        }
                    } else {
                        result = partitionedRegion.getDataStore().grabBucket(bid, null, true, false, false, null, true);
                    }
                } else {
                    result = partitionedRegion.getDataStore().grabBucket(bid, null, true, false, false, null, true);
                }
            }
            if (result.nowExists()) {
                return;
            } else if (result != CreateBucketResult.REDUNDANCY_ALREADY_SATISFIED) {
                // TODO prpersist - check cache closure, create new error message
                this.partitionedRegion.checkReadiness();
                throw new InternalGemFireError("Unable to restore the persistent bucket " + this.getName());
            }
            if (isDebugEnabled) {
                logger.debug("{} redundancy is already satisfied, so discarding persisted data. Current hosts {}", getFullPath(), advisor.adviseReplicates());
            }
            // Destroy the data if we can't create the bucket, or if the redundancy is already satisfied
            destroyOfflineData();
        }
        if (isDebugEnabled) {
            logger.debug("{} initializing membership view from peers", getFullPath());
        }
        persistenceAdvisor.initializeMembershipView();
    } catch (DiskAccessException dae) {
        this.partitionedRegion.handleDiskAccessException(dae);
        throw dae;
    } catch (RuntimeException e) {
        exception = e;
        throw e;
    } finally {
        persistenceAdvisor.recoveryDone(exception);
    }
}
Also used : CreateBucketResult(org.apache.geode.internal.cache.PartitionedRegionDataStore.CreateBucketResult) DiskAccessException(org.apache.geode.cache.DiskAccessException) InternalGemFireError(org.apache.geode.InternalGemFireError)

Example 5 with DiskAccessException

use of org.apache.geode.cache.DiskAccessException in project geode by apache.

the class AbstractRegionMap method txApplyInvalidate.

public void txApplyInvalidate(Object key, Object newValue, boolean didDestroy, TransactionId txId, TXRmtEvent txEvent, boolean localOp, EventID eventId, Object aCallbackArgument, List<EntryEventImpl> pendingCallbacks, FilterRoutingInfo filterRoutingInfo, ClientProxyMembershipID bridgeContext, TXEntryState txEntryState, VersionTag versionTag, long tailKey) {
    // boolean didInvalidate = false;
    final LocalRegion owner = _getOwner();
    @Released EntryEventImpl cbEvent = null;
    boolean forceNewEntry = !owner.isInitialized() && owner.isAllEvents();
    final boolean hasRemoteOrigin = !((TXId) txId).getMemberId().equals(owner.getMyId());
    DiskRegion dr = owner.getDiskRegion();
    // Fix for Bug #44431. We do NOT want to update the region and wait
    // later for index INIT as region.clear() can cause inconsistency if
    // happened in parallel as it also does index INIT.
    IndexManager oqlIndexManager = owner.getIndexManager();
    if (oqlIndexManager != null) {
        oqlIndexManager.waitForIndexInit();
    }
    try {
        if (forceNewEntry) {
            boolean opCompleted = false;
            RegionEntry newRe = getEntryFactory().createEntry(owner, key, Token.REMOVED_PHASE1);
            synchronized (newRe) {
                try {
                    RegionEntry oldRe = putEntryIfAbsent(key, newRe);
                    while (!opCompleted && oldRe != null) {
                        synchronized (oldRe) {
                            if (oldRe.isRemovedPhase2()) {
                                owner.getCachePerfStats().incRetries();
                                _getMap().remove(key, oldRe);
                                oldRe = putEntryIfAbsent(key, newRe);
                            } else {
                                opCompleted = true;
                                final boolean oldWasTombstone = oldRe.isTombstone();
                                final int oldSize = owner.calculateRegionEntryValueSize(oldRe);
                                // OFFHEAP eei
                                Object oldValue = oldRe.getValueInVM(owner);
                                // Create an entry event only if the calling context is
                                // a receipt of a TXCommitMessage AND there are callbacks
                                // installed
                                // for this region
                                boolean invokeCallbacks = shouldCreateCBEvent(owner, owner.isInitialized());
                                boolean cbEventInPending = false;
                                cbEvent = createCBEvent(owner, localOp ? Operation.LOCAL_INVALIDATE : Operation.INVALIDATE, key, newValue, txId, txEvent, eventId, aCallbackArgument, filterRoutingInfo, bridgeContext, txEntryState, versionTag, tailKey);
                                try {
                                    cbEvent.setRegionEntry(oldRe);
                                    cbEvent.setOldValue(oldValue);
                                    if (logger.isDebugEnabled()) {
                                        logger.debug("txApplyInvalidate cbEvent={}", cbEvent);
                                    }
                                    txRemoveOldIndexEntry(Operation.INVALIDATE, oldRe);
                                    if (didDestroy) {
                                        oldRe.txDidDestroy(owner.cacheTimeMillis());
                                    }
                                    if (txEvent != null) {
                                        txEvent.addInvalidate(owner, oldRe, oldRe.getKey(), newValue, aCallbackArgument);
                                    }
                                    oldRe.setValueResultOfSearch(false);
                                    processAndGenerateTXVersionTag(owner, cbEvent, oldRe, txEntryState);
                                    boolean clearOccured = false;
                                    try {
                                        oldRe.setValue(owner, oldRe.prepareValueForCache(owner, newValue, true));
                                        EntryLogger.logTXInvalidate(_getOwnerObject(), key);
                                        owner.updateSizeOnPut(key, oldSize, 0);
                                        if (oldWasTombstone) {
                                            owner.unscheduleTombstone(oldRe);
                                        }
                                    } catch (RegionClearedException rce) {
                                        clearOccured = true;
                                    }
                                    owner.txApplyInvalidatePart2(oldRe, oldRe.getKey(), didDestroy, true);
                                    // didInvalidate = true;
                                    if (invokeCallbacks) {
                                        switchEventOwnerAndOriginRemote(cbEvent, hasRemoteOrigin);
                                        if (pendingCallbacks == null) {
                                            owner.invokeTXCallbacks(EnumListenerEvent.AFTER_INVALIDATE, cbEvent, true);
                                        } else {
                                            pendingCallbacks.add(cbEvent);
                                            cbEventInPending = true;
                                        }
                                    }
                                    if (!clearOccured) {
                                        lruEntryUpdate(oldRe);
                                    }
                                    if (shouldPerformConcurrencyChecks(owner, cbEvent) && txEntryState != null) {
                                        txEntryState.setVersionTag(cbEvent.getVersionTag());
                                    }
                                } finally {
                                    if (!cbEventInPending)
                                        cbEvent.release();
                                }
                            }
                        }
                    }
                    if (!opCompleted) {
                        boolean invokeCallbacks = shouldCreateCBEvent(owner, owner.isInitialized());
                        boolean cbEventInPending = false;
                        cbEvent = createCBEvent(owner, localOp ? Operation.LOCAL_INVALIDATE : Operation.INVALIDATE, key, newValue, txId, txEvent, eventId, aCallbackArgument, filterRoutingInfo, bridgeContext, txEntryState, versionTag, tailKey);
                        try {
                            cbEvent.setRegionEntry(newRe);
                            txRemoveOldIndexEntry(Operation.INVALIDATE, newRe);
                            newRe.setValueResultOfSearch(false);
                            boolean clearOccured = false;
                            try {
                                processAndGenerateTXVersionTag(owner, cbEvent, newRe, txEntryState);
                                newRe.setValue(owner, newRe.prepareValueForCache(owner, newValue, true));
                                EntryLogger.logTXInvalidate(_getOwnerObject(), key);
                                // we are putting in a new invalidated
                                owner.updateSizeOnCreate(newRe.getKey(), 0);
                            // entry
                            } catch (RegionClearedException rce) {
                                clearOccured = true;
                            }
                            owner.txApplyInvalidatePart2(newRe, newRe.getKey(), didDestroy, true);
                            if (invokeCallbacks) {
                                switchEventOwnerAndOriginRemote(cbEvent, hasRemoteOrigin);
                                if (pendingCallbacks == null) {
                                    owner.invokeTXCallbacks(EnumListenerEvent.AFTER_INVALIDATE, cbEvent, true);
                                } else {
                                    pendingCallbacks.add(cbEvent);
                                    cbEventInPending = true;
                                }
                            }
                            opCompleted = true;
                            if (!clearOccured) {
                                lruEntryCreate(newRe);
                                incEntryCount(1);
                            }
                            if (shouldPerformConcurrencyChecks(owner, cbEvent) && txEntryState != null) {
                                txEntryState.setVersionTag(cbEvent.getVersionTag());
                            }
                        } finally {
                            if (!cbEventInPending)
                                cbEvent.release();
                        }
                    }
                } finally {
                    if (!opCompleted) {
                        removeEntry(key, newRe, false);
                    }
                }
            }
        } else {
            /* !forceNewEntry */
            RegionEntry re = getEntry(key);
            if (re != null) {
                synchronized (re) {
                    {
                        final int oldSize = owner.calculateRegionEntryValueSize(re);
                        boolean wasTombstone = re.isTombstone();
                        // OFFHEAP eei
                        Object oldValue = re.getValueInVM(owner);
                        // Create an entry event only if the calling context is
                        // a receipt of a TXCommitMessage AND there are callbacks
                        // installed
                        // for this region
                        boolean invokeCallbacks = shouldCreateCBEvent(owner, owner.isInitialized());
                        boolean cbEventInPending = false;
                        cbEvent = createCBEvent(owner, localOp ? Operation.LOCAL_INVALIDATE : Operation.INVALIDATE, key, newValue, txId, txEvent, eventId, aCallbackArgument, filterRoutingInfo, bridgeContext, txEntryState, versionTag, tailKey);
                        try {
                            cbEvent.setRegionEntry(re);
                            cbEvent.setOldValue(oldValue);
                            txRemoveOldIndexEntry(Operation.INVALIDATE, re);
                            if (didDestroy) {
                                re.txDidDestroy(owner.cacheTimeMillis());
                            }
                            if (txEvent != null) {
                                txEvent.addInvalidate(owner, re, re.getKey(), newValue, aCallbackArgument);
                            }
                            re.setValueResultOfSearch(false);
                            processAndGenerateTXVersionTag(owner, cbEvent, re, txEntryState);
                            boolean clearOccured = false;
                            try {
                                re.setValue(owner, re.prepareValueForCache(owner, newValue, true));
                                EntryLogger.logTXInvalidate(_getOwnerObject(), key);
                                if (wasTombstone) {
                                    owner.unscheduleTombstone(re);
                                }
                                owner.updateSizeOnPut(key, oldSize, 0);
                            } catch (RegionClearedException rce) {
                                clearOccured = true;
                            }
                            owner.txApplyInvalidatePart2(re, re.getKey(), didDestroy, true);
                            // didInvalidate = true;
                            if (invokeCallbacks) {
                                switchEventOwnerAndOriginRemote(cbEvent, hasRemoteOrigin);
                                if (pendingCallbacks == null) {
                                    owner.invokeTXCallbacks(EnumListenerEvent.AFTER_INVALIDATE, cbEvent, true);
                                } else {
                                    pendingCallbacks.add(cbEvent);
                                    cbEventInPending = true;
                                }
                            }
                            if (!clearOccured) {
                                lruEntryUpdate(re);
                            }
                            if (shouldPerformConcurrencyChecks(owner, cbEvent) && txEntryState != null) {
                                txEntryState.setVersionTag(cbEvent.getVersionTag());
                            }
                        } finally {
                            if (!cbEventInPending)
                                cbEvent.release();
                        }
                    }
                }
            } else {
                // re == null
                // Fix bug#43594
                // In cases where bucket region is re-created, it may so happen
                // that the invalidate is already applied on the Initial image
                // provider, thus causing region entry to be absent.
                // Notify clients with client events.
                boolean cbEventInPending = false;
                cbEvent = createCBEvent(owner, localOp ? Operation.LOCAL_INVALIDATE : Operation.INVALIDATE, key, newValue, txId, txEvent, eventId, aCallbackArgument, filterRoutingInfo, bridgeContext, txEntryState, versionTag, tailKey);
                try {
                    switchEventOwnerAndOriginRemote(cbEvent, hasRemoteOrigin);
                    if (pendingCallbacks == null) {
                        owner.invokeTXCallbacks(EnumListenerEvent.AFTER_INVALIDATE, cbEvent, false);
                    } else {
                        pendingCallbacks.add(cbEvent);
                        cbEventInPending = true;
                    }
                } finally {
                    if (!cbEventInPending)
                        cbEvent.release();
                }
            }
        }
    } catch (DiskAccessException dae) {
        owner.handleDiskAccessException(dae);
        throw dae;
    } finally {
        if (oqlIndexManager != null) {
            oqlIndexManager.countDownIndexUpdaters();
        }
    }
}
Also used : IndexManager(org.apache.geode.cache.query.internal.index.IndexManager) Released(org.apache.geode.internal.offheap.annotations.Released) DiskAccessException(org.apache.geode.cache.DiskAccessException) StoredObject(org.apache.geode.internal.offheap.StoredObject)

Aggregations

DiskAccessException (org.apache.geode.cache.DiskAccessException)76 IOException (java.io.IOException)44 InterruptedIOException (java.io.InterruptedIOException)17 StoredObject (org.apache.geode.internal.offheap.StoredObject)13 HeapDataOutputStream (org.apache.geode.internal.HeapDataOutputStream)11 ByteBuffer (java.nio.ByteBuffer)9 Test (org.junit.Test)8 Version (org.apache.geode.internal.Version)6 File (java.io.File)5 RegionDestroyedException (org.apache.geode.cache.RegionDestroyedException)5 IndexManager (org.apache.geode.cache.query.internal.index.IndexManager)5 UninterruptibleFileChannel (org.apache.geode.internal.cache.persistence.UninterruptibleFileChannel)5 VersionTag (org.apache.geode.internal.cache.versions.VersionTag)5 Released (org.apache.geode.internal.offheap.annotations.Released)5 BufferedInputStream (java.io.BufferedInputStream)4 FileInputStream (java.io.FileInputStream)4 CancelException (org.apache.geode.CancelException)4 BytesAndBits (org.apache.geode.internal.cache.persistence.BytesAndBits)4 UninterruptibleRandomAccessFile (org.apache.geode.internal.cache.persistence.UninterruptibleRandomAccessFile)4 EOFException (java.io.EOFException)3