This is an automated email from the ASF dual-hosted git repository.
swamirishi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 47473dc5a28 HDDS-13452. Prevent snapshot defrag from happening before
upgrade finalization (#9240)
47473dc5a28 is described below
commit 47473dc5a28c0c5a51498ca52bb072bbc974cfc6
Author: Swaminathan Balachandran <[email protected]>
AuthorDate: Thu Nov 13 11:27:09 2025 -0500
HDDS-13452. Prevent snapshot defrag from happening before upgrade
finalization (#9240)
---
.../hadoop/hdds/utils/MapBackedTableIterator.java | 6 +-
.../hadoop/hdds/utils/db/InMemoryTestTable.java | 13 +-
.../hdds/utils/db/StringInMemoryTestTable.java | 31 +++++
.../apache/hadoop/ozone/om/OmSnapshotManager.java | 41 +++---
.../hadoop/ozone/om/SnapshotDefragService.java | 4 +-
.../om/snapshot/OmSnapshotLocalDataManager.java | 54 +++++++-
.../hadoop/ozone/om/upgrade/OMLayoutFeature.java | 3 +-
.../snapshot/TestOmSnapshotLocalDataManager.java | 140 ++++++++++++++++-----
8 files changed, 224 insertions(+), 68 deletions(-)
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/MapBackedTableIterator.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/MapBackedTableIterator.java
index 5af0e671d51..5ce574509da 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/MapBackedTableIterator.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/MapBackedTableIterator.java
@@ -19,7 +19,7 @@
import java.util.Iterator;
import java.util.Map;
-import java.util.TreeMap;
+import java.util.NavigableMap;
import org.apache.hadoop.hdds.utils.db.Table;
/**
@@ -29,9 +29,9 @@ public class MapBackedTableIterator<V> implements
Table.KeyValueIterator<String,
private Iterator<Table.KeyValue<String, V>> itr;
private final String prefix;
- private final TreeMap<String, V> values;
+ private final NavigableMap<String, V> values;
- public MapBackedTableIterator(TreeMap<String, V> values, String prefix) {
+ public MapBackedTableIterator(NavigableMap<String, V> values, String prefix)
{
this.prefix = prefix;
this.values = values;
this.seekToFirst();
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/InMemoryTestTable.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/InMemoryTestTable.java
index 51baeb45177..34d23a039e8 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/InMemoryTestTable.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/InMemoryTestTable.java
@@ -21,21 +21,22 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.NavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
import org.apache.hadoop.hdds.utils.MetadataKeyFilters.KeyPrefixFilter;
/**
* InMemory Table implementation for tests.
*/
-public final class InMemoryTestTable<KEY, VALUE> implements Table<KEY, VALUE> {
- private final Map<KEY, VALUE> map;
+public class InMemoryTestTable<KEY, VALUE> implements Table<KEY, VALUE> {
+ private final NavigableMap<KEY, VALUE> map;
public InMemoryTestTable() {
this(Collections.emptyMap());
}
public InMemoryTestTable(Map<KEY, VALUE> map) {
- this.map = new ConcurrentHashMap<>();
+ this.map = new ConcurrentSkipListMap<>(map);
this.map.putAll(map);
}
@@ -124,4 +125,8 @@ public void dumpToFileWithPrefix(File externalFile, KEY
prefix) {
public void loadFromFile(File externalFile) {
throw new UnsupportedOperationException();
}
+
+ NavigableMap<KEY, VALUE> getMap() {
+ return map;
+ }
}
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/StringInMemoryTestTable.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/StringInMemoryTestTable.java
new file mode 100644
index 00000000000..572a5ab69ea
--- /dev/null
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/StringInMemoryTestTable.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hdds.utils.db;
+
+import org.apache.hadoop.hdds.utils.MapBackedTableIterator;
+
+/**
+ * In memory test table for String keys.
+ * @param <V> Value type.
+ */
+public class StringInMemoryTestTable<V> extends InMemoryTestTable<String, V> {
+ @Override
+ public KeyValueIterator<String, V> iterator(String prefix,
KeyValueIterator.Type type) {
+ return new MapBackedTableIterator<>(getMap(), prefix);
+ }
+}
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
index 453eb3b3b07..db5ac4d6340 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
@@ -46,9 +46,6 @@
import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_SNAPSHOT_DIFF_REPORT_MAX_PAGE_SIZE_DEFAULT;
import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_SNAPSHOT_CHECKPOINT_DIR_CREATION_POLL_TIMEOUT;
import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_SNAPSHOT_CHECKPOINT_DIR_CREATION_POLL_TIMEOUT_DEFAULT;
-import static org.apache.hadoop.ozone.om.codec.OMDBDefinition.DIRECTORY_TABLE;
-import static org.apache.hadoop.ozone.om.codec.OMDBDefinition.FILE_TABLE;
-import static org.apache.hadoop.ozone.om.codec.OMDBDefinition.KEY_TABLE;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.FILE_NOT_FOUND;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_KEY_NAME;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TIMEOUT;
@@ -62,7 +59,6 @@
import com.google.common.cache.CacheLoader;
import com.google.common.cache.RemovalListener;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
import jakarta.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
@@ -111,10 +107,10 @@
import org.apache.hadoop.ozone.snapshot.SnapshotDiffReportOzone;
import org.apache.hadoop.ozone.snapshot.SnapshotDiffResponse;
import org.apache.ozone.rocksdiff.RocksDBCheckpointDiffer;
+import org.apache.ratis.util.function.CheckedFunction;
import org.apache.ratis.util.function.UncheckedAutoCloseableSupplier;
import org.rocksdb.ColumnFamilyDescriptor;
import org.rocksdb.ColumnFamilyHandle;
-import org.rocksdb.LiveFileMetaData;
import org.rocksdb.RocksDBException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -177,7 +173,7 @@ public final class OmSnapshotManager implements
AutoCloseable {
* families before compaction.
*/
public static final Set<String> COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT =
- ImmutableSet.of(KEY_TABLE, DIRECTORY_TABLE, FILE_TABLE);
+ RocksDBCheckpointDiffer.COLUMN_FAMILIES_TO_TRACK_IN_DAG;
private final long diffCleanupServiceInterval;
private final int maxOpenSstFilesInSnapshotDb;
@@ -198,12 +194,9 @@ public final class OmSnapshotManager implements
AutoCloseable {
public OmSnapshotManager(OzoneManager ozoneManager) throws IOException {
OmMetadataManagerImpl omMetadataManager = (OmMetadataManagerImpl)
ozoneManager.getMetadataManager();
- this.snapshotLocalDataManager = new
OmSnapshotLocalDataManager(ozoneManager.getMetadataManager(),
- omMetadataManager.getSnapshotChainManager(),
ozoneManager.getConfiguration());
boolean isFilesystemSnapshotEnabled =
ozoneManager.isFilesystemSnapshotEnabled();
LOG.info("Ozone filesystem snapshot feature is {}.",
isFilesystemSnapshotEnabled ? "enabled" : "disabled");
-
// Confirm that snapshot feature can be safely disabled.
// Throw unchecked exception if that is not the case.
if (!isFilesystemSnapshotEnabled &&
@@ -216,7 +209,6 @@ public OmSnapshotManager(OzoneManager ozoneManager) throws
IOException {
"Please set config ozone.filesystem.snapshot.enabled to true and " +
"try to start this Ozone Manager again.");
}
-
this.options = new ManagedDBOptions();
this.options.setCreateIfMissing(true);
this.columnFamilyOptions = new ManagedColumnFamilyOptions();
@@ -231,6 +223,12 @@ public OmSnapshotManager(OzoneManager ozoneManager) throws
IOException {
OZONE_OM_SNAPSHOT_DB_MAX_OPEN_FILES,
OZONE_OM_SNAPSHOT_DB_MAX_OPEN_FILES_DEFAULT
);
+ CheckedFunction<SnapshotInfo, OmMetadataManagerImpl, IOException>
defaultSnapDBProvider = snapshotInfo ->
+ getSnapshotOmMetadataManager(snapshotInfo, 0,
maxOpenSstFilesInSnapshotDb,
+ ozoneManager.getConfiguration());
+ this.snapshotLocalDataManager = new
OmSnapshotLocalDataManager(ozoneManager.getMetadataManager(),
+ omMetadataManager.getSnapshotChainManager(),
ozoneManager.getVersionManager(), defaultSnapDBProvider,
+ ozoneManager.getConfiguration());
Preconditions.checkArgument(this.maxOpenSstFilesInSnapshotDb >= -1,
OZONE_OM_SNAPSHOT_DB_MAX_OPEN_FILES + " value should be larger than or
equal to -1.");
@@ -238,7 +236,6 @@ public OmSnapshotManager(OzoneManager ozoneManager) throws
IOException {
ColumnFamilyHandle snapDiffReportCf;
ColumnFamilyHandle snapDiffPurgedJobCf;
String dbPath = getDbPath(ozoneManager.getConfiguration());
-
try {
// Add default CF
columnFamilyDescriptors.add(new ColumnFamilyDescriptor(
@@ -377,6 +374,12 @@ public boolean canDisableFsSnapshot(OMMetadataManager
ommm) {
return isSnapshotInfoTableEmpty;
}
+ private static OmMetadataManagerImpl
getSnapshotOmMetadataManager(SnapshotInfo snapshotInfo, int version,
+ int maxOpenSstFilesInSnapshotDb, OzoneConfiguration conf) throws
IOException {
+ return new OmMetadataManagerImpl(conf,
snapshotInfo.getCheckpointDirName(version),
+ maxOpenSstFilesInSnapshotDb);
+ }
+
private CacheLoader<UUID, OmSnapshot> createCacheLoader() {
return new CacheLoader<UUID, OmSnapshot>() {
@@ -429,9 +432,8 @@ public OmSnapshot load(@Nonnull UUID snapshotId) throws
IOException {
}
try
(OmSnapshotLocalDataManager.ReadableOmSnapshotLocalDataMetaProvider
snapshotLocalDataProvider =
snapshotLocalDataManager.getOmSnapshotLocalDataMeta(snapshotInfo)) {
- snapshotMetadataManager = new OmMetadataManagerImpl(conf,
-
snapshotInfo.getCheckpointDirName(snapshotLocalDataProvider.getMeta().getVersion()),
- maxOpenSstFilesInSnapshotDb);
+ snapshotMetadataManager =
getSnapshotOmMetadataManager(snapshotInfo,
+ snapshotLocalDataProvider.getMeta().getVersion(),
maxOpenSstFilesInSnapshotDb, conf);
}
} catch (IOException e) {
LOG.error("Failed to retrieve snapshot: {}", snapshotTableKey, e);
@@ -596,17 +598,6 @@ public SnapshotDiffCleanupService
getSnapshotDiffCleanupService() {
return snapshotDiffCleanupService;
}
- /**
- * Captures the list of SST files for keyTable, fileTable and directoryTable
in the DB.
- * @param store AOS or snapshot DB for not defragged or defragged snapshot
respectively.
- * @return a Map of (table, set of SST files corresponding to the table)
- */
- public static List<LiveFileMetaData> getSnapshotSSTFileList(RDBStore store)
throws IOException {
- return store.getDb().getLiveFilesMetaData().stream()
- .filter(lfm ->
COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT.contains(StringUtils.bytes2String(lfm.columnFamilyName())))
- .collect(Collectors.toList());
- }
-
// Get OmSnapshot if the keyName has ".snapshot" key indicator
@SuppressWarnings("unchecked")
public UncheckedAutoCloseableSupplier<IOmMetadataReader>
getActiveFsMetadataOrSnapshot(
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotDefragService.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotDefragService.java
index 3eb1bfadf25..e72a91a2775 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotDefragService.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotDefragService.java
@@ -45,6 +45,7 @@
import org.apache.hadoop.ozone.om.lock.IOzoneManagerLock;
import org.apache.hadoop.ozone.om.snapshot.MultiSnapshotLocks;
import org.apache.hadoop.ozone.om.snapshot.OmSnapshotLocalDataManager;
+import org.apache.hadoop.ozone.om.upgrade.OMLayoutFeature;
import org.apache.ratis.util.function.UncheckedAutoCloseableSupplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -347,7 +348,8 @@ private boolean shouldRun() {
return false;
}
// The service only runs if current OM node is ready
- return running.get() && ozoneManager.isRunning();
+ return running.get() && ozoneManager.isRunning() &&
+
ozoneManager.getVersionManager().isAllowed(OMLayoutFeature.SNAPSHOT_DEFRAG);
}
public AtomicLong getSnapshotsDefraggedCount() {
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java
index 0e665167283..10e296a2c85 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java
@@ -20,6 +20,10 @@
import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_SNAPSHOT_LOCAL_DATA_MANAGER_SERVICE_INTERVAL;
import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_SNAPSHOT_LOCAL_DATA_MANAGER_SERVICE_INTERVAL_DEFAULT;
import static
org.apache.hadoop.ozone.om.OmSnapshotLocalDataYaml.YAML_FILE_EXTENSION;
+import static
org.apache.hadoop.ozone.om.OmSnapshotManager.COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT;
+import static
org.apache.hadoop.ozone.om.helpers.SnapshotInfo.SnapshotStatus.SNAPSHOT_ACTIVE;
+import static
org.apache.hadoop.ozone.om.upgrade.OMLayoutFeature.SNAPSHOT_DEFRAG;
+import static org.apache.ozone.rocksdb.util.RdbUtil.getLiveSSTFilesForCFs;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.graph.GraphBuilder;
@@ -52,7 +56,10 @@
import org.apache.hadoop.hdds.utils.Scheduler;
import org.apache.hadoop.hdds.utils.TransactionInfo;
import org.apache.hadoop.hdds.utils.db.RDBStore;
+import org.apache.hadoop.hdds.utils.db.Table;
+import org.apache.hadoop.hdds.utils.db.managed.ManagedRocksDB;
import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
import org.apache.hadoop.ozone.om.OmSnapshotLocalData;
import org.apache.hadoop.ozone.om.OmSnapshotLocalData.VersionMeta;
import org.apache.hadoop.ozone.om.OmSnapshotLocalDataYaml;
@@ -63,8 +70,10 @@
import org.apache.hadoop.ozone.om.lock.HierarchicalResourceLockManager;
import
org.apache.hadoop.ozone.om.lock.HierarchicalResourceLockManager.HierarchicalResourceLock;
import org.apache.hadoop.ozone.om.lock.OMLockDetails;
+import org.apache.hadoop.ozone.om.upgrade.OMLayoutVersionManager;
import org.apache.hadoop.ozone.util.ObjectSerializer;
import org.apache.hadoop.ozone.util.YamlSerializer;
+import org.apache.ratis.util.function.CheckedFunction;
import org.apache.ratis.util.function.CheckedSupplier;
import org.apache.ratis.util.function.UncheckedAutoCloseableSupplier;
import org.rocksdb.LiveFileMetaData;
@@ -113,7 +122,8 @@ public class OmSnapshotLocalDataManager implements
AutoCloseable {
private volatile boolean closed;
public OmSnapshotLocalDataManager(OMMetadataManager omMetadataManager,
- SnapshotChainManager snapshotChainManager,
+ SnapshotChainManager snapshotChainManager, OMLayoutVersionManager
omLayoutVersionManager,
+ CheckedFunction<SnapshotInfo, OmMetadataManagerImpl, IOException>
defaultSnapProvider,
OzoneConfiguration configuration) throws IOException {
this.localDataGraph = GraphBuilder.directed().build();
this.omMetadataManager = omMetadataManager;
@@ -128,7 +138,7 @@ public void computeAndSetChecksum(Yaml yaml,
OmSnapshotLocalData data) throws IO
this.versionNodeMap = new ConcurrentHashMap<>();
this.fullLock = new ReentrantReadWriteLock();
this.internalLock = new ReentrantReadWriteLock();
- init(configuration, snapshotChainManager);
+ init(configuration, snapshotChainManager, omLayoutVersionManager,
defaultSnapProvider);
}
@VisibleForTesting
@@ -172,7 +182,8 @@ public void createNewOmSnapshotLocalDataFile(RDBStore
snapshotStore, SnapshotInf
try (WritableOmSnapshotLocalDataProvider snapshotLocalData =
new
WritableOmSnapshotLocalDataProvider(snapshotInfo.getSnapshotId(),
() -> Pair.of(new
OmSnapshotLocalData(snapshotInfo.getSnapshotId(),
-
OmSnapshotManager.getSnapshotSSTFileList(snapshotStore),
+
getLiveSSTFilesForCFs(snapshotStore.getDb().getManagedRocksDb(),
+ COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT),
snapshotInfo.getPathPreviousSnapshotId(), null),
null))) {
snapshotLocalData.commit();
@@ -242,6 +253,32 @@ private void addSnapshotVersionMeta(UUID snapshotId,
SnapshotVersionsMeta snapsh
}
}
+ private void addMissingSnapshotYamlFiles(
+ CheckedFunction<SnapshotInfo, OmMetadataManagerImpl, IOException>
defaultSnapProvider) throws IOException {
+ try (Table.KeyValueIterator<String, SnapshotInfo> itr =
omMetadataManager.getSnapshotInfoTable().iterator()) {
+ while (itr.hasNext()) {
+ SnapshotInfo snapshotInfo = itr.next().getValue();
+ UUID snapshotId = snapshotInfo.getSnapshotId();
+ File snapshotLocalDataFile = new
File(getSnapshotLocalPropertyYamlPath(snapshotId));
+ // Create a yaml file for snapshots which are missing
+ if (!snapshotLocalDataFile.exists()) {
+ List<LiveFileMetaData> sstList = Collections.emptyList();
+ if (snapshotInfo.getSnapshotStatus() == SNAPSHOT_ACTIVE) {
+ try (OmMetadataManagerImpl snapshotMetadataManager =
defaultSnapProvider.apply(snapshotInfo)) {
+ ManagedRocksDB snapDB =
((RDBStore)snapshotMetadataManager.getStore()).getDb().getManagedRocksDb();
+ sstList = getLiveSSTFilesForCFs(snapDB,
COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT);
+ } catch (Exception e) {
+ throw new IOException(e);
+ }
+ }
+ OmSnapshotLocalData snapshotLocalData = new
OmSnapshotLocalData(snapshotId, sstList,
+ snapshotInfo.getPathPreviousSnapshotId(), null);
+ snapshotLocalDataSerializer.save(snapshotLocalDataFile,
snapshotLocalData);
+ }
+ }
+ }
+ }
+
void addVersionNodeWithDependents(OmSnapshotLocalData snapshotLocalData)
throws IOException {
if (versionNodeMap.containsKey(snapshotLocalData.getSnapshotId())) {
return;
@@ -297,12 +334,18 @@ Map<UUID, Integer> getSnapshotToBeCheckedForOrphans() {
return snapshotToBeCheckedForOrphans;
}
- private void init(OzoneConfiguration configuration, SnapshotChainManager
chainManager) throws IOException {
+ private void init(OzoneConfiguration configuration, SnapshotChainManager
chainManager,
+ OMLayoutVersionManager layoutVersionManager,
+ CheckedFunction<SnapshotInfo, OmMetadataManagerImpl, IOException>
defaultSnapProvider) throws IOException {
this.locks = omMetadataManager.getHierarchicalLockManager();
this.snapshotToBeCheckedForOrphans = new ConcurrentHashMap<>();
RDBStore store = (RDBStore) omMetadataManager.getStore();
String checkpointPrefix = store.getDbLocation().getName();
File snapshotDir = new File(store.getSnapshotsParentDir());
+ boolean upgradeNeeded = !layoutVersionManager.isAllowed(SNAPSHOT_DEFRAG);
+ if (upgradeNeeded) {
+ addMissingSnapshotYamlFiles(defaultSnapProvider);
+ }
File[] localDataFiles = snapshotDir.listFiles(
(dir, name) -> name.startsWith(checkpointPrefix) &&
name.endsWith(YAML_FILE_EXTENSION));
if (localDataFiles == null) {
@@ -826,7 +869,8 @@ private SnapshotVersionsMeta
validateModification(OmSnapshotLocalData snapshotLo
}
public void addSnapshotVersion(RDBStore snapshotStore) throws IOException {
- List<LiveFileMetaData> sstFiles =
OmSnapshotManager.getSnapshotSSTFileList(snapshotStore);
+ List<LiveFileMetaData> sstFiles =
getLiveSSTFilesForCFs(snapshotStore.getDb().getManagedRocksDb(),
+ COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT);
OmSnapshotLocalData previousSnapshotLocalData =
getPreviousSnapshotLocalData();
this.getSnapshotLocalData().addVersionSSTFileInfos(sstFiles,
previousSnapshotLocalData == null ? 0 :
previousSnapshotLocalData.getVersion());
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMLayoutFeature.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMLayoutFeature.java
index 7deeef51161..057484c673e 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMLayoutFeature.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMLayoutFeature.java
@@ -45,7 +45,8 @@ public enum OMLayoutFeature implements LayoutFeature {
QUOTA(6, "Ozone quota re-calculate"),
HBASE_SUPPORT(7, "Full support of hsync, lease recovery and listOpenFiles
APIs for HBase"),
- DELEGATION_TOKEN_SYMMETRIC_SIGN(8, "Delegation token signed by symmetric
key");
+ DELEGATION_TOKEN_SYMMETRIC_SIGN(8, "Delegation token signed by symmetric
key"),
+ SNAPSHOT_DEFRAG(9, "Supporting defragmentation of snapshot");
/////////////////////////////// /////////////////////////////
// Example OM Layout Feature with Actions
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java
index e3b5d343b36..fff40480364 100644
---
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java
@@ -24,6 +24,8 @@
import static org.apache.hadoop.ozone.om.codec.OMDBDefinition.DIRECTORY_TABLE;
import static org.apache.hadoop.ozone.om.codec.OMDBDefinition.FILE_TABLE;
import static org.apache.hadoop.ozone.om.codec.OMDBDefinition.KEY_TABLE;
+import static
org.apache.hadoop.ozone.om.helpers.SnapshotInfo.SnapshotStatus.SNAPSHOT_ACTIVE;
+import static
org.apache.hadoop.ozone.om.helpers.SnapshotInfo.SnapshotStatus.SNAPSHOT_DELETED;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -32,6 +34,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
@@ -40,6 +43,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@@ -70,7 +74,11 @@
import org.apache.hadoop.hdds.utils.db.RDBStore;
import org.apache.hadoop.hdds.utils.db.RocksDatabase;
import org.apache.hadoop.hdds.utils.db.RocksDatabaseException;
+import org.apache.hadoop.hdds.utils.db.StringInMemoryTestTable;
+import org.apache.hadoop.hdds.utils.db.Table;
+import org.apache.hadoop.hdds.utils.db.managed.ManagedRocksDB;
import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
import org.apache.hadoop.ozone.om.OmSnapshotLocalData;
import org.apache.hadoop.ozone.om.OmSnapshotLocalDataYaml;
import org.apache.hadoop.ozone.om.OmSnapshotManager;
@@ -80,8 +88,12 @@
import
org.apache.hadoop.ozone.om.lock.HierarchicalResourceLockManager.HierarchicalResourceLock;
import
org.apache.hadoop.ozone.om.snapshot.OmSnapshotLocalDataManager.ReadableOmSnapshotLocalDataProvider;
import
org.apache.hadoop.ozone.om.snapshot.OmSnapshotLocalDataManager.WritableOmSnapshotLocalDataProvider;
+import org.apache.hadoop.ozone.om.upgrade.OMLayoutFeature;
+import org.apache.hadoop.ozone.om.upgrade.OMLayoutVersionManager;
+import org.apache.hadoop.ozone.upgrade.LayoutFeature;
import org.apache.hadoop.ozone.util.YamlSerializer;
import org.apache.ozone.rocksdb.util.SstFileInfo;
+import org.apache.ratis.util.function.CheckedFunction;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
@@ -96,6 +108,7 @@
import org.mockito.MockedStatic;
import org.mockito.MockitoAnnotations;
import org.rocksdb.LiveFileMetaData;
+import org.rocksdb.RocksDB;
import org.yaml.snakeyaml.Yaml;
/**
@@ -124,6 +137,9 @@ public class TestOmSnapshotLocalDataManager {
@TempDir
private Path tempDir;
+ @Mock
+ private OMLayoutVersionManager layoutVersionManager;
+
private OmSnapshotLocalDataManager localDataManager;
private AutoCloseable mocks;
@@ -177,6 +193,7 @@ public void setUp() throws IOException {
purgedSnapshotIdMap.clear();
snapshotUtilMock.when(() -> OmSnapshotManager.isSnapshotPurged(any(),
any(), any(), any()))
.thenAnswer(i -> purgedSnapshotIdMap.getOrDefault(i.getArgument(2),
false));
+
when(layoutVersionManager.isAllowed(any(LayoutFeature.class))).thenReturn(true);
conf.setInt(OZONE_OM_SNAPSHOT_LOCAL_DATA_MANAGER_SERVICE_INTERVAL, -1);
}
@@ -242,6 +259,15 @@ private void mockLockManager() throws IOException {
});
}
+ private OmSnapshotLocalDataManager getNewOmSnapshotLocalDataManager(
+ CheckedFunction<SnapshotInfo, OmMetadataManagerImpl, IOException>
provider) throws IOException {
+ return new OmSnapshotLocalDataManager(omMetadataManager, null,
layoutVersionManager, provider, conf);
+ }
+
+ private OmSnapshotLocalDataManager getNewOmSnapshotLocalDataManager() throws
IOException {
+ return getNewOmSnapshotLocalDataManager(null);
+ }
+
private List<UUID> createSnapshotLocalData(OmSnapshotLocalDataManager
snapshotLocalDataManager,
int numberOfSnapshots) throws IOException {
SnapshotInfo previousSnapshotInfo = null;
@@ -277,11 +303,14 @@ private void mockSnapshotStore(UUID snapshotId,
List<LiveFileMetaData> sstFiles)
// Setup snapshot store mock
File snapshotDbLocation =
OmSnapshotManager.getSnapshotPath(omMetadataManager, snapshotId, 0).toFile();
assertTrue(snapshotDbLocation.exists() || snapshotDbLocation.mkdirs());
-
when(snapshotStore.getDbLocation()).thenReturn(snapshotDbLocation);
RocksDatabase rocksDatabase = mock(RocksDatabase.class);
when(snapshotStore.getDb()).thenReturn(rocksDatabase);
- when(rocksDatabase.getLiveFilesMetaData()).thenReturn(sstFiles);
+ ManagedRocksDB db = mock(ManagedRocksDB.class);
+ when(rocksDatabase.getManagedRocksDb()).thenReturn(db);
+ RocksDB rdb = mock(RocksDB.class);
+ when(db.get()).thenReturn(rdb);
+ when(rdb.getLiveFilesMetaData()).thenReturn(sstFiles);
}
/**
@@ -295,7 +324,7 @@ private void mockSnapshotStore(UUID snapshotId,
List<LiveFileMetaData> sstFiles)
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void testLockOrderingAgainstAnotherSnapshot(boolean read) throws
IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = new ArrayList<>();
snapshotIds.add(null);
snapshotIds.addAll(createSnapshotLocalData(localDataManager, 20));
@@ -347,7 +376,7 @@ public void testLockOrderingAgainstAnotherSnapshot(boolean
read) throws IOExcept
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void testVersionLockResolution(boolean read) throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 5);
for (int snapIdx = 0; snapIdx < snapshotIds.size(); snapIdx++) {
UUID snapId = snapshotIds.get(snapIdx);
@@ -385,7 +414,7 @@ public void testVersionLockResolution(boolean read) throws
IOException {
@Test
public void
testWriteVersionAdditionValidationWithoutPreviousSnapshotVersionExisting()
throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 2);
UUID snapId = snapshotIds.get(1);
try (WritableOmSnapshotLocalDataProvider omSnapshotLocalDataProvider =
@@ -401,7 +430,7 @@ public void
testWriteVersionAdditionValidationWithoutPreviousSnapshotVersionExis
@Test
public void testUpdateTransactionInfo() throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
TransactionInfo transactionInfo =
TransactionInfo.valueOf(ThreadLocalRandom.current().nextLong(),
ThreadLocalRandom.current().nextLong());
UUID snapshotId = createSnapshotLocalData(localDataManager, 1).get(0);
@@ -420,7 +449,7 @@ public void testUpdateTransactionInfo() throws IOException {
@Test
public void testAddVersionFromRDB() throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 2);
addVersionsToLocalData(localDataManager, snapshotIds.get(0),
ImmutableMap.of(4, 5, 6, 8));
UUID snapId = snapshotIds.get(1);
@@ -457,7 +486,7 @@ private void validateVersions(OmSnapshotLocalDataManager
snapshotLocalDataManage
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void testOrphanVersionDeletionWithVersionDeletion(boolean
purgeSnapshot) throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 3);
UUID firstSnapId = snapshotIds.get(0);
UUID secondSnapId = snapshotIds.get(1);
@@ -489,7 +518,7 @@ public void
testOrphanVersionDeletionWithVersionDeletion(boolean purgeSnapshot)
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void testOrphanVersionDeletionWithChainUpdate(boolean purgeSnapshot)
throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 3);
UUID firstSnapId = snapshotIds.get(0);
UUID secondSnapId = snapshotIds.get(1);
@@ -526,7 +555,7 @@ public void
testOrphanVersionDeletionWithChainUpdate(boolean purgeSnapshot) thro
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void testWriteWithChainUpdate(boolean previousSnapshotExisting)
throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 3 +
(previousSnapshotExisting ? 1 : 0));
int snapshotIdx = 1 + (previousSnapshotExisting ? 1 : 0);
for (UUID snapshotId : snapshotIds) {
@@ -578,7 +607,7 @@ public void testWriteWithChainUpdate(boolean
previousSnapshotExisting) throws IO
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void testWriteVersionValidation(boolean nextVersionExisting) throws
IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 3);
UUID prevSnapId = snapshotIds.get(0);
UUID snapId = snapshotIds.get(1);
@@ -652,7 +681,7 @@ private void
addVersionsToLocalData(OmSnapshotLocalDataManager snapshotLocalData
@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
public void testNeedsDefrag(int previousVersion) throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 2);
for (UUID snapshotId : snapshotIds) {
try (ReadableOmSnapshotLocalDataProvider snap =
localDataManager.getOmSnapshotLocalData(snapshotId)) {
@@ -672,7 +701,7 @@ public void testNeedsDefrag(int previousVersion) throws
IOException {
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void testVersionResolution(boolean read) throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 5);
List<Map<Integer, Integer>> versionMaps = Arrays.asList(
ImmutableMap.of(4, 1, 6, 3, 8, 9, 11, 15),
@@ -725,7 +754,7 @@ public void testVersionResolution(boolean read) throws
IOException {
@Test
public void testConstructor() throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
assertNotNull(localDataManager);
}
@@ -734,7 +763,7 @@ public void
testGetSnapshotLocalPropertyYamlPathWithSnapshotInfo() throws IOExce
UUID snapshotId = UUID.randomUUID();
SnapshotInfo snapshotInfo = createMockSnapshotInfo(snapshotId, null);
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
File yamlPath = new
File(localDataManager.getSnapshotLocalPropertyYamlPath(snapshotInfo));
assertNotNull(yamlPath);
@@ -772,7 +801,7 @@ public void testCreateNewSnapshotLocalYaml() throws
IOException {
mockedLiveFiles.add(createMockLiveFileMetaData("ot2.sst", "otherTable",
"k1", "k2"));
mockSnapshotStore(snapshotId, mockedLiveFiles);
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
Path snapshotYaml =
Paths.get(localDataManager.getSnapshotLocalPropertyYamlPath(snapshotInfo));
// Create an existing YAML file for the snapshot
assertTrue(snapshotYaml.toFile().createNewFile());
@@ -813,7 +842,7 @@ public void testCreateNewOmSnapshotLocalDataFile() throws
IOException {
bytes2String(lfm.largestKey()),
bytes2String(lfm.columnFamilyName()))).collect(Collectors.toList());
mockSnapshotStore(snapshotId, sstFiles);
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
localDataManager.createNewOmSnapshotLocalDataFile(snapshotStore,
snapshotInfo);
@@ -838,7 +867,7 @@ public void testGetOmSnapshotLocalDataWithSnapshotInfo()
throws IOException {
// Create and write snapshot local data file
OmSnapshotLocalData localData = createMockLocalData(snapshotId, null);
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
// Write the file manually for testing
Path yamlPath =
Paths.get(localDataManager.getSnapshotLocalPropertyYamlPath(snapshotInfo.getSnapshotId()));
@@ -859,7 +888,7 @@ public void
testGetOmSnapshotLocalDataWithMismatchedSnapshotId() throws IOExcept
// Create local data with wrong snapshot ID
OmSnapshotLocalData localData = createMockLocalData(wrongSnapshotId, null);
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
Path yamlPath =
Paths.get(localDataManager.getSnapshotLocalPropertyYamlPath(snapshotId));
writeLocalDataToFile(localData, yamlPath);
@@ -875,7 +904,7 @@ public void testGetOmSnapshotLocalDataWithFile() throws
IOException {
OmSnapshotLocalData localData = createMockLocalData(snapshotId, null);
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
Path yamlPath = tempDir.resolve("test-snapshot.yaml");
writeLocalDataToFile(localData, yamlPath);
@@ -893,7 +922,7 @@ public void testAddVersionNodeWithDependents() throws
IOException {
.sorted(Comparator.comparing(String::valueOf)).collect(Collectors.toList());
UUID snapshotId = versionIds.get(0);
UUID previousSnapshotId = versionIds.get(1);
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
// Create snapshot directory structure and files
createSnapshotLocalDataFile(snapshotId, previousSnapshotId);
createSnapshotLocalDataFile(previousSnapshotId, null);
@@ -909,7 +938,7 @@ public void testAddVersionNodeWithDependentsAlreadyExists()
throws IOException {
createSnapshotLocalDataFile(snapshotId, null);
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
OmSnapshotLocalData localData = createMockLocalData(snapshotId, null);
@@ -931,7 +960,7 @@ public void testInitWithExistingYamlFiles() throws
IOException {
createSnapshotLocalDataFile(snapshotId, previousSnapshotId);
// Initialize - should load existing files
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
assertNotNull(localDataManager);
Map<UUID, OmSnapshotLocalDataManager.SnapshotVersionsMeta> versionMap =
@@ -940,6 +969,56 @@ public void testInitWithExistingYamlFiles() throws
IOException {
assertEquals(versionMap.keySet(), new HashSet<>(versionIds));
}
+ @ParameterizedTest
+ @ValueSource(booleans = {true, false})
+ public void testInitWithMissingYamlFiles(boolean needsUpgrade) throws
IOException {
+ Table<String, SnapshotInfo> table = new StringInMemoryTestTable<>();
+ when(omMetadataManager.getSnapshotInfoTable()).thenReturn(table);
+ UUID snap3 = UUID.randomUUID();
+ UUID snap2 = UUID.randomUUID();
+ UUID snap1 = UUID.randomUUID();
+ CheckedFunction<SnapshotInfo, OmMetadataManagerImpl, IOException>
mockedProvider = (snapshotInfo) -> {
+ if (snapshotInfo.getSnapshotId().equals(snap2)) {
+ throw new IOException("SnapshotId should not be " + snap2 + " since it
is deleted");
+ }
+ mockSnapshotStore(snapshotInfo.getSnapshotId(),
ImmutableList.of(createMockLiveFileMetaData(
+ snapshotInfo.getSnapshotId() + ".sst", KEY_TABLE,
snapshotInfo.getSnapshotId() + "k1",
+ snapshotInfo.getSnapshotId() + "k2")));
+ OmMetadataManagerImpl snapshotMetadataManager =
mock(OmMetadataManagerImpl.class);
+ when(snapshotMetadataManager.getStore()).thenReturn(snapshotStore);
+ return snapshotMetadataManager;
+ };
+ table.put("snap3", createMockSnapshotInfo(snap3, null, SNAPSHOT_ACTIVE));
+ table.put("snap2", createMockSnapshotInfo(snap2, snap3, SNAPSHOT_DELETED));
+ table.put("snap1", createMockSnapshotInfo(snap1, snap2, SNAPSHOT_ACTIVE));
+
when(layoutVersionManager.isAllowed(eq(OMLayoutFeature.SNAPSHOT_DEFRAG))).thenReturn(!needsUpgrade);
+ localDataManager = getNewOmSnapshotLocalDataManager(mockedProvider);
+ if (needsUpgrade) {
+ assertEquals(ImmutableSet.of(snap1, snap2, snap3),
localDataManager.getVersionNodeMap().keySet());
+ Map<UUID, UUID> previousMap = ImmutableMap.of(snap2, snap3, snap1,
snap2);
+ Map<UUID, Map<Integer, OmSnapshotLocalData.VersionMeta>> expectedSstFile
= ImmutableMap.of(
+ snap3, ImmutableMap.of(0,
+ new OmSnapshotLocalData.VersionMeta(0, ImmutableList.of(
+ new SstFileInfo(snap3.toString(), snap3 + "k1", snap3 +
"k2", KEY_TABLE)))),
+ snap1, ImmutableMap.of(0,
+ new OmSnapshotLocalData.VersionMeta(0, ImmutableList.of(
+ new SstFileInfo(snap1.toString(), snap1 + "k1", snap1 +
"k2", KEY_TABLE)))),
+ snap2, ImmutableMap.of(0,
+ new OmSnapshotLocalData.VersionMeta(0, ImmutableList.of())));
+ for (UUID snapshotId : localDataManager.getVersionNodeMap().keySet()) {
+ try (ReadableOmSnapshotLocalDataProvider
readableOmSnapshotLocalDataProvider =
+ localDataManager.getOmSnapshotLocalData(snapshotId)) {
+ OmSnapshotLocalData snapshotLocalData =
readableOmSnapshotLocalDataProvider.getSnapshotLocalData();
+ assertEquals(snapshotId, snapshotLocalData.getSnapshotId());
+ assertEquals(previousMap.get(snapshotId),
snapshotLocalData.getPreviousSnapshotId());
+ assertEquals(expectedSstFile.get(snapshotId),
snapshotLocalData.getVersionSstFileInfos());
+ }
+ }
+ } else {
+ assertEquals(ImmutableSet.of(),
localDataManager.getVersionNodeMap().keySet());
+ }
+ }
+
@Test
public void testInitWithInvalidPathThrowsException() throws IOException {
UUID snapshotId = UUID.randomUUID();
@@ -950,14 +1029,12 @@ public void testInitWithInvalidPathThrowsException()
throws IOException {
writeLocalDataToFile(localData, wrongPath);
// Should throw IOException during init
- assertThrows(IOException.class, () -> {
- new OmSnapshotLocalDataManager(omMetadataManager, null, conf);
- });
+ assertThrows(IOException.class, this::getNewOmSnapshotLocalDataManager);
}
@Test
public void testClose() throws IOException {
- localDataManager = new OmSnapshotLocalDataManager(omMetadataManager, null,
conf);
+ localDataManager = getNewOmSnapshotLocalDataManager();
// Should not throw exception
localDataManager.close();
}
@@ -965,14 +1042,19 @@ public void testClose() throws IOException {
// Helper methods
private SnapshotInfo createMockSnapshotInfo(UUID snapshotId, UUID
previousSnapshotId) {
+ return createMockSnapshotInfo(snapshotId, previousSnapshotId, null);
+ }
+
+ private SnapshotInfo createMockSnapshotInfo(UUID snapshotId, UUID
previousSnapshotId,
+ SnapshotInfo.SnapshotStatus snapshotStatus) {
SnapshotInfo.Builder builder = SnapshotInfo.newBuilder()
.setSnapshotId(snapshotId)
.setName("snapshot-" + snapshotId);
-
+ builder.setSnapshotStatus(snapshotStatus == null ? SNAPSHOT_ACTIVE :
snapshotStatus);
if (previousSnapshotId != null) {
builder.setPathPreviousSnapshotId(previousSnapshotId);
}
-
+
return builder.build();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]