2020package org .apache .hadoop .ozone .om .request .snapshot ;
2121
2222import org .apache .commons .lang3 .tuple .Pair ;
23- import org .apache .commons .lang3 .tuple .Triple ;
2423import org .apache .hadoop .hdds .utils .db .Table ;
25- import org .apache .hadoop .ozone .om .OMMetadataManager ;
2624import org .apache .hadoop .ozone .om .OMMetrics ;
2725import org .apache .hadoop .ozone .om .exceptions .OMException ;
2826import org .apache .hadoop .ozone .om .response .snapshot .OMSnapshotPurgeResponse .OmPurgeResponse ;
4745
4846import java .io .IOException ;
4947import java .util .ArrayList ;
50- import java .util .HashSet ;
5148import java .util .List ;
5249import java .util .NoSuchElementException ;
5350import java .util .Objects ;
54- import java .util .Set ;
5551import 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 =
0 commit comments