You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by si...@apache.org on 2023/02/21 16:40:44 UTC
[ozone] branch master updated: HDDS-7906. [Snapshot] Wait for checkpoint creation if snapshot in cache and not committed to DB. (#4249)
This is an automated email from the ASF dual-hosted git repository.
siyao 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 4d09962a65 HDDS-7906. [Snapshot] Wait for checkpoint creation if snapshot in cache and not committed to DB. (#4249)
4d09962a65 is described below
commit 4d09962a659a2b39a2580215975180e5491b1b00
Author: Sadanand Shenoy <sa...@gmail.com>
AuthorDate: Tue Feb 21 22:10:38 2023 +0530
HDDS-7906. [Snapshot] Wait for checkpoint creation if snapshot in cache and not committed to DB. (#4249)
---
.../hadoop/hdds/utils/db/RDBCheckpointManager.java | 3 +-
.../hadoop/fs/ozone/TestRootedOzoneFileSystem.java | 39 ++++++++++++++++++++++
.../hadoop/ozone/om/OmMetadataManagerImpl.java | 33 ++++++++----------
.../apache/hadoop/ozone/om/OmSnapshotManager.java | 13 ++++++--
.../ozone/om/ratis/OzoneManagerDoubleBuffer.java | 7 ++--
.../om/ratis/TestOzoneManagerDoubleBuffer.java | 12 ++++---
6 files changed, 74 insertions(+), 33 deletions(-)
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/RDBCheckpointManager.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/RDBCheckpointManager.java
index 7bb4694093..ee5408b13b 100644
--- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/RDBCheckpointManager.java
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/RDBCheckpointManager.java
@@ -113,7 +113,8 @@ public class RDBCheckpointManager implements Closeable {
* Wait for checkpoint directory to be created for 5 secs with 100 millis
* poll interval.
*/
- private void waitForCheckpointDirectoryExist(File file) throws IOException {
+ public static void waitForCheckpointDirectoryExist(File file)
+ throws IOException {
Instant start = Instant.now();
try {
with().atMost(POLL_MAX_DURATION)
diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystem.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystem.java
index 482eb1d47c..c319dd3fd3 100644
--- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystem.java
+++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystem.java
@@ -2213,4 +2213,43 @@ public class TestRootedOzoneFileSystem {
OzoneVolume ozoneVolume = objectStore.getVolume(linkVolume);
ozoneVolume.createBucket(linkBucket, builder.build());
}
+
+ @Test
+ public void testSnapshotRead() throws Exception {
+ // Init data
+ OzoneBucket bucket1 =
+ TestDataUtil.createVolumeAndBucket(cluster, bucketLayout);
+ Path volume1Path = new Path(OZONE_URI_DELIMITER, bucket1.getVolumeName());
+ Path bucket1Path = new Path(volume1Path, bucket1.getName());
+ Path file1 = new Path(bucket1Path, "key1");
+ Path file2 = new Path(bucket1Path, "key2");
+
+ ContractTestUtils.touch(fs, file1);
+ ContractTestUtils.touch(fs, file2);
+
+ OzoneBucket bucket2 =
+ TestDataUtil.createVolumeAndBucket(cluster, bucketLayout);
+ Path volume2Path = new Path(OZONE_URI_DELIMITER, bucket2.getVolumeName());
+ Path bucket2Path = new Path(volume2Path, bucket2.getName());
+
+ fs.mkdirs(bucket2Path);
+ Path snapPath1 = fs.createSnapshot(bucket1Path, "snap1");
+ Path snapPath2 = fs.createSnapshot(bucket2Path, "snap1");
+
+ Path file3 = new Path(bucket1Path, "key3");
+ ContractTestUtils.touch(fs, file3);
+
+ Path snapPath3 = fs.createSnapshot(bucket1Path, "snap2");
+
+ try {
+ FileStatus[] f1 = fs.listStatus(snapPath1);
+ FileStatus[] f2 = fs.listStatus(snapPath2);
+ FileStatus[] f3 = fs.listStatus(snapPath3);
+ Assert.assertEquals(2, f1.length);
+ Assert.assertEquals(0, f2.length);
+ Assert.assertEquals(3, f3.length);
+ } catch (Exception e) {
+ Assert.fail("Failed to read/list on snapshotPath, exception: " + e);
+ }
+ }
}
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
index f079030e64..180e5b5e6c 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
@@ -40,6 +40,7 @@ import org.apache.hadoop.hdds.utils.db.DBStore;
import org.apache.hadoop.hdds.utils.db.DBStoreBuilder;
import org.apache.hadoop.hdds.utils.db.RocksDBConfiguration;
import org.apache.hadoop.hdds.utils.db.Table;
+import org.apache.hadoop.hdds.utils.db.RDBCheckpointManager;
import org.apache.hadoop.hdds.utils.db.Table.KeyValue;
import org.apache.hadoop.hdds.utils.db.TableIterator;
import org.apache.hadoop.hdds.utils.db.TypedTable;
@@ -305,32 +306,25 @@ public class OmMetadataManagerImpl implements OMMetadataManager,
}
// metadata constructor for snapshots
- private OmMetadataManagerImpl(OzoneConfiguration conf, String snapshotDirName)
- throws IOException {
+ OmMetadataManagerImpl(OzoneConfiguration conf, String snapshotDirName,
+ boolean isSnapshotInCache) throws IOException {
lock = new OmReadOnlyLock();
omEpoch = 0;
String snapshotDir = OMStorage.getOmDbDir(conf) +
OM_KEY_PREFIX + OM_SNAPSHOT_DIR;
- setStore(loadDB(conf, new File(snapshotDir),
- OM_DB_NAME + snapshotDirName, true));
+ File metaDir = new File(snapshotDir);
+ String dbName = OM_DB_NAME + snapshotDirName;
+ // The check is only to prevent every snapshot read to perform a disk IO
+ // and check if a checkpoint dir exists. If entry is present in cache,
+ // it is most likely DB entries will get flushed in this wait time.
+ if (isSnapshotInCache) {
+ File checkpoint = Paths.get(metaDir.toPath().toString(), dbName).toFile();
+ RDBCheckpointManager.waitForCheckpointDirectoryExist(checkpoint);
+ }
+ setStore(loadDB(conf, metaDir, dbName, true));
initializeOmTables(false);
}
- /**
- * Factory method for creating snapshot metadata manager.
- *
- * @param conf - ozone configuration
- * @param snapshotDirName - the UUID that identifies the snapshot
- * @return the metadata manager representing the snapshot
- * @throws IOException
- */
- public static OmMetadataManagerImpl createSnapshotMetadataManager(
- OzoneConfiguration conf, String snapshotDirName) throws IOException {
- OmMetadataManagerImpl smm = new OmMetadataManagerImpl(conf,
- snapshotDirName);
- return smm;
- }
-
@Override
public Table<String, PersistedUserVolumeInfo> getUserTable() {
return userTable;
@@ -913,7 +907,6 @@ public class OmMetadataManagerImpl implements OMMetadataManager,
}
return false;
}
-
/**
* Checks if a key starts with the given prefix is present in the table.
*
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 8164b0a3f9..a218414acc 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
@@ -32,6 +32,7 @@ import org.apache.hadoop.hdds.utils.db.DBCheckpoint;
import org.apache.hadoop.hdds.utils.db.RDBStore;
import org.apache.hadoop.hdds.utils.db.managed.ManagedOptions;
import org.apache.hadoop.hdds.utils.db.managed.ManagedRocksDB;
+import org.apache.hadoop.hdds.utils.db.cache.CacheKey;
import org.apache.hadoop.ozone.OzoneConfigKeys;
import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
@@ -94,6 +95,10 @@ public final class OmSnapshotManager implements AutoCloseable {
// see if the snapshot exists
snapshotInfo = getSnapshotInfo(snapshotTableKey);
+ boolean isSnapshotInCache =
+ ozoneManager.getMetadataManager().getSnapshotInfoTable()
+ .getCacheValue(new CacheKey<>(snapshotTableKey)) != null;
+
// read in the snapshot
OzoneConfiguration conf = ozoneManager.getConfiguration();
OMMetadataManager snapshotMetadataManager;
@@ -102,9 +107,8 @@ public final class OmSnapshotManager implements AutoCloseable {
// RocksDB instance, creating an OmMetadataManagerImpl instance based on
// that
try {
- snapshotMetadataManager = OmMetadataManagerImpl
- .createSnapshotMetadataManager(
- conf, snapshotInfo.getCheckpointDirName());
+ snapshotMetadataManager = new OmMetadataManagerImpl(conf,
+ snapshotInfo.getCheckpointDirName(), isSnapshotInCache);
} catch (IOException e) {
LOG.error("Failed to retrieve snapshot: {}, {}", snapshotTableKey, e);
throw e;
@@ -156,6 +160,9 @@ public final class OmSnapshotManager implements AutoCloseable {
final DBCheckpoint dbCheckpoint = store.getSnapshot(
snapshotInfo.getCheckpointDirName());
+ LOG.info("Created checkpoint : {} for snapshot {}",
+ dbCheckpoint.getCheckpointLocation(), snapshotInfo.getName());
+
final RocksDBCheckpointDiffer dbCpDiffer =
store.getRocksDBCheckpointDiffer();
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerDoubleBuffer.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerDoubleBuffer.java
index 9e03e10f52..6c8048a5bb 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerDoubleBuffer.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerDoubleBuffer.java
@@ -440,10 +440,9 @@ public final class OzoneManagerDoubleBuffer {
// 1. It is first element in the response,
// 2. Current request is createSnapshot request.
// 3. Previous request was createSnapshot request.
- if (response.isEmpty() ||
- omResponse.getCreateSnapshotResponse() != null ||
- (previousOmResponse != null &&
- previousOmResponse.getCreateSnapshotResponse() != null)) {
+ if (response.isEmpty() || omResponse.hasCreateSnapshotResponse()
+ || (previousOmResponse != null &&
+ previousOmResponse.hasCreateSnapshotResponse())) {
response.add(new LinkedList<>());
}
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/ratis/TestOzoneManagerDoubleBuffer.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/ratis/TestOzoneManagerDoubleBuffer.java
index cb977f46db..57dbf47e3e 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/ratis/TestOzoneManagerDoubleBuffer.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/ratis/TestOzoneManagerDoubleBuffer.java
@@ -33,6 +33,7 @@ import org.apache.hadoop.ozone.om.ratis.metrics.OzoneManagerDoubleBufferMetrics;
import org.apache.hadoop.ozone.om.response.OMClientResponse;
import org.apache.hadoop.ozone.om.response.bucket.OMBucketCreateResponse;
import org.apache.hadoop.ozone.om.response.key.OMKeyCreateResponse;
+import org.apache.hadoop.ozone.om.response.snapshot.OMSnapshotCreateResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateSnapshotResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
import org.junit.jupiter.api.AfterEach;
@@ -68,9 +69,9 @@ class TestOzoneManagerDoubleBuffer {
private static OMClientResponse omBucketCreateResponse =
mock(OMBucketCreateResponse.class);
private static OMClientResponse omSnapshotCreateResponse1 =
- mock(OMBucketCreateResponse.class);
+ mock(OMSnapshotCreateResponse.class);
private static OMClientResponse omSnapshotCreateResponse2 =
- mock(OMBucketCreateResponse.class);
+ mock(OMSnapshotCreateResponse.class);
@TempDir
private File tempDir;
@@ -109,9 +110,10 @@ class TestOzoneManagerDoubleBuffer {
when(omBucketResponse.getTraceID()).thenReturn("bucketTraceId");
when(omSnapshotResponse1.getTraceID()).thenReturn("snapshotTraceId-1");
when(omSnapshotResponse2.getTraceID()).thenReturn("snapshotTraceId-2");
-
- when(omKeyResponse.getCreateSnapshotResponse()).thenReturn(null);
- when(omBucketResponse.getCreateSnapshotResponse()).thenReturn(null);
+ when(omSnapshotResponse1.hasCreateSnapshotResponse())
+ .thenReturn(true);
+ when(omSnapshotResponse2.hasCreateSnapshotResponse())
+ .thenReturn(true);
when(omSnapshotResponse1.getCreateSnapshotResponse())
.thenReturn(snapshotResponse1);
when(omSnapshotResponse2.getCreateSnapshotResponse())
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org