Skip to content

Commit e85485d

Browse files
committed
HDDS-11137. Removed locks from SnapshotPurge and SnapshotSetProperty APIs
1 parent 24b6849 commit e85485d

2 files changed

Lines changed: 30 additions & 113 deletions

File tree

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotPurgeRequest.java

Lines changed: 29 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020
package org.apache.hadoop.ozone.om.request.snapshot;
2121

2222
import org.apache.commons.lang3.tuple.Pair;
23-
import org.apache.commons.lang3.tuple.Triple;
2423
import org.apache.hadoop.hdds.utils.db.Table;
25-
import org.apache.hadoop.ozone.om.OMMetadataManager;
2624
import org.apache.hadoop.ozone.om.OMMetrics;
2725
import org.apache.hadoop.ozone.om.exceptions.OMException;
2826
import org.apache.hadoop.ozone.om.response.snapshot.OMSnapshotPurgeResponse.OmPurgeResponse;
@@ -47,15 +45,11 @@
4745

4846
import java.io.IOException;
4947
import java.util.ArrayList;
50-
import java.util.HashSet;
5148
import java.util.List;
5249
import java.util.NoSuchElementException;
5350
import java.util.Objects;
54-
import java.util.Set;
5551
import java.util.UUID;
5652

57-
import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.SNAPSHOT_LOCK;
58-
5953
/**
6054
* Handles OMSnapshotPurge Request.
6155
* This is an OM internal request. Does not need @RequireSnapshotFeatureState.
@@ -118,19 +112,9 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, TermIn
118112
// 2. Update the deep clean flag for the next active snapshot (So that it can be
119113
// deep cleaned by the KeyDeletingService in the next run),
120114
// 3. Finally, purge the snapshot.
121-
// All of these steps have to be performed only when it acquires all the necessary
122-
// locks (lock on the snapshot to be purged, lock on the next active snapshot, and
123-
// lock on the next path and global previous snapshots). Ideally, there is no need
124-
// for locks for snapshot purge and can rely on OMStateMachine because OMStateMachine
125-
// is going to process each request sequentially.
126-
//
127-
// But there is a problem with that. After filtering unnecessary SST files for a snapshot,
128-
// SstFilteringService updates that snapshot's SstFilter flag. SstFilteringService cannot
129-
// use SetSnapshotProperty API because it runs on each OM independently and One OM does
130-
// not know if the snapshot has been filtered on the other OM in HA environment.
131115
//
132-
// If locks are not taken snapshot purge and SstFilteringService will cause a race condition
133-
// and override one's update with another.
116+
// There is no need to take lock for snapshot purge as of now. We can simply rely on OMStateMachine
117+
// because it executes transaction sequentially.
134118
private OmPurgeResponse purgeSnapshot(String snapshotKey,
135119
OzoneManager ozoneManager,
136120
long trxnLogIndex) throws IOException {
@@ -139,97 +123,58 @@ private OmPurgeResponse purgeSnapshot(String snapshotKey,
139123
OmMetadataManagerImpl omMetadataManager = (OmMetadataManagerImpl) ozoneManager.getMetadataManager();
140124
SnapshotChainManager snapshotChainManager = omMetadataManager.getSnapshotChainManager();
141125

142-
if (omMetadataManager.getSnapshotInfoTable().get(snapshotKey) == null) {
126+
SnapshotInfo fromSnapshot = omMetadataManager.getSnapshotInfoTable().get(snapshotKey);
127+
if (fromSnapshot == null) {
143128
// Snapshot may have been purged in the previous iteration of SnapshotDeletingService.
144129
throw new OMException("Snapshot: '" + snapshotKey + "}' is no longer exist " +
145130
"in snapshot table. Might be removed in previous run.", OMException.ResultCodes.FILE_NOT_FOUND);
146131
}
147132

148-
// To acquire all the locks, a set is maintained which is keyed by a triple of volumeName, bucketName and
149-
// snapshotName. SnapshotInfoTable key (which is /volumeName/bucketName/snapshotName) is not directly
150-
// because volumeName, bucketName and snapshotName can't be obtained after purging snapshot from cache.
151-
// Once all the necessary locks are acquired, the three steps mentioned above are performed and
152-
// locks are release after that.
153-
Set<Triple<String, String, String>> lockSet = new HashSet<>(4, 1);
154-
155-
try {
156-
acquireLock(lockSet, snapshotKey, omMetadataManager);
157-
158-
SnapshotInfo fromSnapshot = omMetadataManager.getSnapshotInfoTable().get(snapshotKey);
159-
SnapshotInfo nextSnapshot =
160-
SnapshotUtils.getNextActiveSnapshot(fromSnapshot, snapshotChainManager, omSnapshotManager);
133+
SnapshotInfo nextSnapshot =
134+
SnapshotUtils.getNextActiveSnapshot(fromSnapshot, snapshotChainManager, omSnapshotManager);
161135

162-
if (nextSnapshot != null) {
163-
acquireLock(lockSet, nextSnapshot.getTableKey(), omMetadataManager);
164-
}
165-
166-
// Step 1: Update the snapshot chain.
167-
Pair<SnapshotInfo, SnapshotInfo> pathToGlobalSnapshotInto =
168-
updateSnapshotChainAndCache(lockSet, omMetadataManager, fromSnapshot, trxnLogIndex);
169-
SnapshotInfo nextPathSnapshotInfo = null;
170-
SnapshotInfo nextGlobalSnapshotInfo = null;
171-
172-
if (pathToGlobalSnapshotInto != null) {
173-
nextPathSnapshotInfo = pathToGlobalSnapshotInto.getLeft();
174-
nextGlobalSnapshotInfo = pathToGlobalSnapshotInto.getRight();
175-
}
136+
// Step 1: Update the snapshot chain.
137+
Pair<SnapshotInfo, SnapshotInfo> pathToGlobalSnapshotInto =
138+
updateSnapshotChainAndCache(omMetadataManager, fromSnapshot, trxnLogIndex);
139+
SnapshotInfo nextPathSnapshotInfo = null;
140+
SnapshotInfo nextGlobalSnapshotInfo = null;
176141

177-
// Step 2: Update the deep clean flag for the next active snapshot
178-
SnapshotInfo nextActiveSnapshotInfo = updateSnapshotInfoAndCache(nextSnapshot, omMetadataManager, trxnLogIndex);
142+
if (pathToGlobalSnapshotInto != null) {
143+
nextPathSnapshotInfo = pathToGlobalSnapshotInto.getLeft();
144+
nextGlobalSnapshotInfo = pathToGlobalSnapshotInto.getRight();
145+
}
179146

180-
// Remove and close snapshot's RocksDB instance from SnapshotCache.
181-
ozoneManager.getOmSnapshotManager().invalidateCacheEntry(fromSnapshot.getSnapshotId());
147+
// Step 2: Update the deep clean flag for the next active snapshot
148+
SnapshotInfo nextActiveSnapshotInfo = updateSnapshotInfoAndCache(nextSnapshot, omMetadataManager, trxnLogIndex);
182149

183-
// Step 3: Purge the snapshot from SnapshotInfoTable cache.
184-
ozoneManager.getMetadataManager().getSnapshotInfoTable()
185-
.addCacheEntry(new CacheKey<>(fromSnapshot.getTableKey()), CacheValue.get(trxnLogIndex));
150+
// Remove and close snapshot's RocksDB instance from SnapshotCache.
151+
ozoneManager.getOmSnapshotManager().invalidateCacheEntry(fromSnapshot.getSnapshotId());
186152

187-
return new OmPurgeResponse(snapshotKey, nextPathSnapshotInfo, nextGlobalSnapshotInfo,
188-
nextActiveSnapshotInfo);
189-
} finally {
190-
lockSet.forEach(lockKey -> omMetadataManager.getLock()
191-
.releaseWriteLock(SNAPSHOT_LOCK, lockKey.getLeft(), lockKey.getMiddle(), lockKey.getRight()));
192-
}
193-
}
153+
// Step 3: Purge the snapshot from SnapshotInfoTable cache.
154+
ozoneManager.getMetadataManager().getSnapshotInfoTable()
155+
.addCacheEntry(new CacheKey<>(fromSnapshot.getTableKey()), CacheValue.get(trxnLogIndex));
194156

195-
private void acquireLock(Set<Triple<String, String, String>> lockSet, String snapshotTableKey,
196-
OMMetadataManager omMetadataManager) throws IOException {
197-
SnapshotInfo snapshotInfo = omMetadataManager.getSnapshotInfoTable().get(snapshotTableKey);
157+
return new OmPurgeResponse(snapshotKey, nextPathSnapshotInfo, nextGlobalSnapshotInfo,
158+
nextActiveSnapshotInfo);
198159

199-
// It should not be the case that lock is required for non-existing snapshot.
200-
if (snapshotInfo == null) {
201-
LOG.error("Snapshot: '{}' doesn't not exist in snapshot table.", snapshotTableKey);
202-
throw new OMException("Snapshot: '{" + snapshotTableKey + "}' doesn't not exist in snapshot table.",
203-
OMException.ResultCodes.FILE_NOT_FOUND);
204-
}
205-
Triple<String, String, String> lockKey = Triple.of(snapshotInfo.getVolumeName(), snapshotInfo.getBucketName(),
206-
snapshotInfo.getName());
207-
if (!lockSet.contains(lockKey)) {
208-
mergeOmLockDetails(omMetadataManager.getLock()
209-
.acquireWriteLock(SNAPSHOT_LOCK, lockKey.getLeft(), lockKey.getMiddle(), lockKey.getRight()));
210-
lockSet.add(lockKey);
211-
}
212160
}
213161

214162
private SnapshotInfo updateSnapshotInfoAndCache(SnapshotInfo snapInfo, OmMetadataManagerImpl omMetadataManager,
215-
long trxnLogIndex) throws IOException {
163+
long trxnLogIndex) {
216164
if (snapInfo == null) {
217165
return null;
218166
}
219167

220-
// Fetch the latest value again after acquiring lock.
221-
SnapshotInfo updatedSnapshotInfo = omMetadataManager.getSnapshotInfoTable().get(snapInfo.getTableKey());
222-
223168
// Setting next snapshot deep clean to false, Since the
224169
// current snapshot is deleted. We can potentially
225170
// reclaim more keys in the next snapshot.
226-
updatedSnapshotInfo.setDeepClean(false);
171+
snapInfo.setDeepClean(false);
227172

228173
// Update table cache first
229174
omMetadataManager.getSnapshotInfoTable()
230-
.addCacheEntry(new CacheKey<>(updatedSnapshotInfo.getTableKey()),
231-
CacheValue.get(trxnLogIndex, updatedSnapshotInfo));
232-
return updatedSnapshotInfo;
175+
.addCacheEntry(new CacheKey<>(snapInfo.getTableKey()),
176+
CacheValue.get(trxnLogIndex, snapInfo));
177+
return snapInfo;
233178
}
234179

235180
/**
@@ -239,7 +184,6 @@ private SnapshotInfo updateSnapshotInfoAndCache(SnapshotInfo snapInfo, OmMetadat
239184
* update in DB.
240185
*/
241186
private Pair<SnapshotInfo, SnapshotInfo> updateSnapshotChainAndCache(
242-
Set<Triple<String, String, String>> lockSet,
243187
OmMetadataManagerImpl metadataManager,
244188
SnapshotInfo snapInfo,
245189
long trxnLogIndex
@@ -267,18 +211,12 @@ private Pair<SnapshotInfo, SnapshotInfo> updateSnapshotChainAndCache(
267211
UUID nextPathSnapshotId = snapshotChainManager.nextPathSnapshot(
268212
snapInfo.getSnapshotPath(), snapInfo.getSnapshotId());
269213
nextPathSnapshotKey = snapshotChainManager.getTableKey(nextPathSnapshotId);
270-
271-
// Acquire lock from the snapshot
272-
acquireLock(lockSet, nextPathSnapshotKey, metadataManager);
273214
}
274215

275216
String nextGlobalSnapshotKey = null;
276217
if (hasNextGlobalSnapshot) {
277218
UUID nextGlobalSnapshotId = snapshotChainManager.nextGlobalSnapshot(snapInfo.getSnapshotId());
278219
nextGlobalSnapshotKey = snapshotChainManager.getTableKey(nextGlobalSnapshotId);
279-
280-
// Acquire lock from the snapshot
281-
acquireLock(lockSet, nextGlobalSnapshotKey, metadataManager);
282220
}
283221

284222
SnapshotInfo nextPathSnapInfo =

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotSetPropertyRequest.java

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import java.io.IOException;
3939

4040
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.FILE_NOT_FOUND;
41-
import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.SNAPSHOT_LOCK;
4241

4342
/**
4443
* Updates the exclusive size of the snapshot.
@@ -63,13 +62,8 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, TermIn
6362
OzoneManagerProtocolProtos.SetSnapshotPropertyRequest
6463
setSnapshotPropertyRequest = getOmRequest()
6564
.getSetSnapshotPropertyRequest();
66-
SnapshotInfo updatedSnapInfo = null;
6765

6866
String snapshotKey = setSnapshotPropertyRequest.getSnapshotKey();
69-
boolean acquiredSnapshotLock = false;
70-
String volumeName = null;
71-
String bucketName = null;
72-
String snapshotName = null;
7367

7468
try {
7569
SnapshotInfo snapshotInfo = metadataManager.getSnapshotInfoTable().get(snapshotKey);
@@ -78,18 +72,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, TermIn
7872
throw new OMException("Snapshot: '{" + snapshotKey + "}' doesn't not exist in snapshot table.", FILE_NOT_FOUND);
7973
}
8074

81-
volumeName = snapshotInfo.getVolumeName();
82-
bucketName = snapshotInfo.getBucketName();
83-
snapshotName = snapshotInfo.getName();
84-
85-
mergeOmLockDetails(metadataManager.getLock()
86-
.acquireWriteLock(SNAPSHOT_LOCK, volumeName, bucketName, snapshotName));
87-
88-
acquiredSnapshotLock = getOmLockDetails().isLockAcquired();
89-
90-
updatedSnapInfo = metadataManager.getSnapshotInfoTable()
91-
.get(snapshotKey);
92-
75+
SnapshotInfo updatedSnapInfo = metadataManager.getSnapshotInfoTable().get(snapshotKey);
9376

9477
if (setSnapshotPropertyRequest.hasDeepCleanedDeletedDir()) {
9578
updatedSnapInfo.setDeepCleanedDeletedDir(setSnapshotPropertyRequest
@@ -127,10 +110,6 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, TermIn
127110
omMetrics.incNumSnapshotSetPropertyFails();
128111
LOG.error("Failed to execute snapshotSetPropertyRequest: {{}}.", setSnapshotPropertyRequest, ex);
129112
} finally {
130-
if (acquiredSnapshotLock) {
131-
mergeOmLockDetails(metadataManager.getLock()
132-
.releaseWriteLock(SNAPSHOT_LOCK, volumeName, bucketName, snapshotName));
133-
}
134113
if (omClientResponse != null) {
135114
omClientResponse.setOmLockDetails(getOmLockDetails());
136115
}

0 commit comments

Comments
 (0)