diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotCache.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotCache.java index d8932c0e7e0a..01b20e6ea337 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotCache.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotCache.java @@ -186,6 +186,7 @@ public ReferenceCounted get(String key, throw new IllegalStateException(ex); } } + LOG.debug("Got snapshot {} from SnapshotCache", k); return v; }); @@ -304,30 +305,35 @@ private void cleanupInternal() { OmSnapshot omSnapshot = (OmSnapshot) rcOmSnapshot.get(); LOG.debug("Evicting OmSnapshot instance {} with table key {}", rcOmSnapshot, omSnapshot.getSnapshotTableKey()); - // Sanity check - Preconditions.checkState(rcOmSnapshot.getTotalRefCount() == 0L, - "Illegal state: OmSnapshot reference count non-zero (" - + rcOmSnapshot.getTotalRefCount() + ") but shows up in the " - + "clean up list"); final String key = omSnapshot.getSnapshotTableKey(); - final ReferenceCounted result = - dbMap.remove(key); - // Sanity check - Preconditions.checkState(rcOmSnapshot == result, - "Cache map entry removal failure. The cache is in an inconsistent " - + "state. Expected OmSnapshot instance: " + rcOmSnapshot - + ", actual: " + result + " for key: " + key); - - pendingEvictionList.remove(result); + dbMap.compute(key, (k, v) -> { + if (v == null) { + throw new IllegalStateException("Key '" + k + "' does not exist in cache. The RocksDB " + + "instance of the Snapshot may not be closed properly."); + } - // Close the instance, which also closes its DB handle. - try { - ((OmSnapshot) rcOmSnapshot.get()).close(); - } catch (IOException ex) { - throw new IllegalStateException("Error while closing snapshot DB", ex); - } + // Sanity check + Preconditions.checkState(rcOmSnapshot == v, + "Cache map entry removal failure. The cache is in an inconsistent " + + "state. Expected OmSnapshot instance: " + rcOmSnapshot + + ", actual: " + v + " for key: " + key); + + // Close the instance, which also closes its DB handle. + if (rcOmSnapshot.getTotalRefCount() == 0L) { + try { + ((OmSnapshot) rcOmSnapshot.get()).close(); + } catch (IOException ex) { + throw new IllegalStateException("Error while closing snapshot DB", ex); + } + return null; + } + LOG.warn("Snapshot {} is still being referenced ({}), skipping its clean up", + k, rcOmSnapshot.getTotalRefCount()); + return v; + }); + pendingEvictionList.remove(rcOmSnapshot); --numEntriesToEvict; }