From 78e161ad53a7e3482ebfbb56571ec1d9a219a022 Mon Sep 17 00:00:00 2001 From: Maksim Timonin Date: Tue, 21 Nov 2023 13:47:28 +0300 Subject: [PATCH] IGNITE-20572 BinaryMeta file atomic creation (#11055) --- .../cache/binary/BinaryMetadataFileStore.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java index db43a7a0c113a..408e6f1ffc8eb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java @@ -46,6 +46,8 @@ import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.thread.IgniteThread; +import static java.nio.file.StandardCopyOption.ATOMIC_MOVE; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.TMP_SUFFIX; /** @@ -150,16 +152,23 @@ void writeMetadata(BinaryMetadata binMeta) { try { File file = new File(metadataDir, BinaryUtils.binaryMetaFileName(binMeta.typeId())); + File tmpFile = new File(file.getAbsolutePath() + TMP_SUFFIX); + + // TODO: delete it on Ignite start. https://issues.apache.org/jira/browse/IGNITE-20897 + if (tmpFile.exists()) + U.delete(tmpFile); byte[] marshalled = U.marshal(ctx, binMeta); - try (final FileIO out = fileIOFactory.create(file)) { + try (final FileIO out = fileIOFactory.create(tmpFile)) { int left = marshalled.length; while ((left -= out.writeFully(marshalled, 0, Math.min(marshalled.length, left))) > 0) ; out.force(); } + + Files.move(tmpFile.toPath(), file.toPath(), ATOMIC_MOVE, REPLACE_EXISTING); } catch (Exception e) { final String msg = "Failed to save metadata for typeId: " + binMeta.typeId() + @@ -208,7 +217,7 @@ void restoreMetadata() { if (!enabled) return; - for (File file : metadataDir.listFiles()) + for (File file : metadataDir.listFiles(BinaryUtils::notTmpFile)) restoreMetadata(file); }