sashapolo commented on a change in pull request #723: URL: https://github.com/apache/ignite-3/pull/723#discussion_r829847005
########## File path: modules/rocksdb-common/src/main/java/org/apache/ignite/internal/rocksdb/snapshot/RocksSnapshotManager.java ########## @@ -0,0 +1,212 @@ +/* + * 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.ignite.internal.rocksdb.snapshot; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import org.apache.ignite.internal.rocksdb.RocksUtils; +import org.apache.ignite.internal.util.IgniteUtils; +import org.apache.ignite.lang.IgniteInternalException; +import org.rocksdb.EnvOptions; +import org.rocksdb.IngestExternalFileOptions; +import org.rocksdb.Options; +import org.rocksdb.ReadOptions; +import org.rocksdb.RocksDB; +import org.rocksdb.RocksDBException; +import org.rocksdb.RocksIterator; +import org.rocksdb.Slice; +import org.rocksdb.Snapshot; +import org.rocksdb.SstFileWriter; + +/** + * Class for creating and restoring RocksDB snapshots. + */ +public class RocksSnapshotManager { + /** Suffix for the temporary snapshot folder. */ + private static final String TMP_SUFFIX = ".tmp"; + + private final RocksDB db; + + private final Collection<ColumnFamilyRange> ranges; + + private final Executor executor; + + /** + * Creates a new instance of the snapshot manager. + * This instance <b>does not</b> own any of the provided resources and will not close them. + * + * @param db RocksDB instance which snapshots will be managed. + * @param ranges Key ranges of Column Families that exist in the provided {@code db} instance. + * @param executor Executor which will be used for creating snapshots. + */ + public RocksSnapshotManager(RocksDB db, Collection<ColumnFamilyRange> ranges, Executor executor) { + assert !ranges.isEmpty(); + + this.db = db; + this.ranges = ranges; + this.executor = executor; + } + + /** + * Creates a snapshot of the enclosed RocksDB instance and saves it into a provided folder. + * + * @param snapshotDir Folder to save the snapshot into. + * @return Future that either completes successfully upon snapshot creation or signals a failure. + */ + public CompletableFuture<Void> createSnapshot(Path snapshotDir) { + Path tmpPath = Paths.get(snapshotDir.toString() + TMP_SUFFIX); + + return CompletableFuture.supplyAsync(db::getSnapshot, executor) + .thenComposeAsync(snapshot -> { + createTmpSnapshotDir(tmpPath); + + // Create futures for capturing SST snapshots of the column families + CompletableFuture<?>[] sstFutures = ranges.stream() + .map(cf -> createSstFileAsync(cf, snapshot, tmpPath)) + .toArray(CompletableFuture[]::new); + + return CompletableFuture.allOf(sstFutures).thenApply(v -> snapshot); + }, executor) + .whenCompleteAsync((snapshot, e) -> { + // Release the snapshot + db.releaseSnapshot(snapshot); + + // Snapshot is not actually closed here, because a Snapshot instance doesn't own a pointer, the + // database does. Calling close to maintain the AutoCloseable semantics + snapshot.close(); Review comment: nice catch! -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
