From 177b7a9a5cee1d8fee4ffef5256c9f2789193c12 Mon Sep 17 00:00:00 2001 From: Yang Yu Date: Fri, 17 Dec 2021 17:57:41 +0800 Subject: [PATCH] use atomic move to avoid file corruption --- .../jraft/storage/snapshot/local/LocalSnapshotStorage.java | 2 +- .../alipay/sofa/jraft/rhea/storage/RocksRawKVStore.java | 7 ++++--- .../sofa/jraft/rhea/storage/zip/ParallelZipStrategy.java | 2 ++ .../main/java/com/alipay/sofa/jraft/rhea/util/ZipUtil.java | 2 ++ 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/jraft-core/src/main/java/com/alipay/sofa/jraft/storage/snapshot/local/LocalSnapshotStorage.java b/jraft-core/src/main/java/com/alipay/sofa/jraft/storage/snapshot/local/LocalSnapshotStorage.java index 627004e58..6b0cf33a3 100644 --- a/jraft-core/src/main/java/com/alipay/sofa/jraft/storage/snapshot/local/LocalSnapshotStorage.java +++ b/jraft-core/src/main/java/com/alipay/sofa/jraft/storage/snapshot/local/LocalSnapshotStorage.java @@ -229,7 +229,7 @@ void close(final LocalSnapshotWriter writer, final boolean keepDataOnError) thro break; } LOG.info("Renaming {} to {}.", tempPath, newPath); - if (!new File(tempPath).renameTo(new File(newPath))) { + if (!Utils.atomicMoveFile(new File(tempPath), new File(newPath), true)) { LOG.error("Renamed temp snapshot failed, from path {} to path {}.", tempPath, newPath); ret = RaftError.EIO.getNumber(); break; diff --git a/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/storage/RocksRawKVStore.java b/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/storage/RocksRawKVStore.java index 4fd45aee8..aea027615 100644 --- a/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/storage/RocksRawKVStore.java +++ b/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/storage/RocksRawKVStore.java @@ -84,6 +84,7 @@ import com.alipay.sofa.jraft.util.Requires; import com.alipay.sofa.jraft.util.StorageOptionsFactory; import com.alipay.sofa.jraft.util.SystemPropertyUtil; +import com.alipay.sofa.jraft.util.Utils; import com.alipay.sofa.jraft.util.concurrent.AdjustableSemaphore; import com.codahale.metrics.Timer; @@ -1475,7 +1476,7 @@ void writeSnapshot(final String snapshotPath) { checkpoint.createCheckpoint(tempPath); final File snapshotFile = new File(snapshotPath); FileUtils.deleteDirectory(snapshotFile); - if (!tempFile.renameTo(snapshotFile)) { + if (!Utils.atomicMoveFile(tempFile, snapshotFile, true)) { throw new StorageException("Fail to rename [" + tempPath + "] to [" + snapshotPath + "]."); } } catch (final StorageException e) { @@ -1502,7 +1503,7 @@ void readSnapshot(final String snapshotPath) { final String dbPath = this.opts.getDbPath(); final File dbFile = new File(dbPath); FileUtils.deleteDirectory(dbFile); - if (!snapshotFile.renameTo(dbFile)) { + if (!Utils.atomicMoveFile(snapshotFile, dbFile, true)) { throw new StorageException("Fail to rename [" + snapshotPath + "] to [" + dbPath + "]."); } // reopen the db @@ -1534,7 +1535,7 @@ CompletableFuture writeSstSnapshot(final String snapshotPath, final Region try { final File snapshotFile = new File(snapshotPath); FileUtils.deleteDirectory(snapshotFile); - if (!tempFile.renameTo(snapshotFile)) { + if (!Utils.atomicMoveFile(tempFile, snapshotFile, true)) { throw new StorageException("Fail to rename [" + tempPath + "] to [" + snapshotPath + "]."); } snapshotFuture.complete(null); diff --git a/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/storage/zip/ParallelZipStrategy.java b/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/storage/zip/ParallelZipStrategy.java index edb73bd64..de99b648b 100644 --- a/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/storage/zip/ParallelZipStrategy.java +++ b/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/storage/zip/ParallelZipStrategy.java @@ -23,6 +23,7 @@ import com.alipay.sofa.jraft.util.ExecutorServiceHelper; import com.alipay.sofa.jraft.util.Requires; import com.alipay.sofa.jraft.util.ThreadPoolUtil; +import com.alipay.sofa.jraft.util.Utils; import org.apache.commons.compress.archivers.zip.ParallelScatterZipCreator; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; @@ -108,6 +109,7 @@ public void compress(final String rootDir, final String sourceDir, final String archiveOutputStream.flush(); fos.getFD().sync(); } + Utils.fsync(zipFile); } @Override diff --git a/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/util/ZipUtil.java b/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/util/ZipUtil.java index 08e3607f3..d630f53ce 100644 --- a/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/util/ZipUtil.java +++ b/jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/util/ZipUtil.java @@ -35,6 +35,7 @@ import org.apache.commons.io.output.NullOutputStream; import com.alipay.sofa.jraft.util.Requires; +import com.alipay.sofa.jraft.util.Utils; /** * @@ -51,6 +52,7 @@ public static void compress(final String rootDir, final String sourceDir, final zos.flush(); fos.getFD().sync(); } + Utils.fsync(new File(outputFile)); } private static void compressDirectoryToZipFile(final String rootDir, final String sourceDir,