From 5d427ff6e535ba60f0d2f3e07781de9fcdc8fd42 Mon Sep 17 00:00:00 2001 From: Maciej Sokol Date: Tue, 19 Apr 2022 10:22:55 +0200 Subject: [PATCH] Fsync TOC and Digest files after they're written Patch by Maciej Sokol; reviewed by brandonwilliams and bereng for CASSANDRA-10709 --- CHANGES.txt | 1 + .../org/apache/cassandra/io/sstable/SSTable.java | 5 ++++- .../cassandra/io/util/DataIntegrityMetadata.java | 15 +++++++++------ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index df06fa3a95..4462e22067 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.27 + * fsync TOC and digest files (CASSANDRA-10709) * Fix URISyntaxException in nodetool with updated Java (CASSANDRA-17581) * Schema mutations may not be completed on drain (CASSANDRA-17524) * Fix data corruption in AbstractCompositeType due to static boolean byte buffers (CASSANDRA-14752) diff --git a/src/java/org/apache/cassandra/io/sstable/SSTable.java b/src/java/org/apache/cassandra/io/sstable/SSTable.java index b5703fcd72..6bfb0bf83a 100644 --- a/src/java/org/apache/cassandra/io/sstable/SSTable.java +++ b/src/java/org/apache/cassandra/io/sstable/SSTable.java @@ -299,10 +299,13 @@ public abstract class SSTable protected static void appendTOC(Descriptor descriptor, Collection components) { File tocFile = new File(descriptor.filenameFor(Component.TOC)); - try (PrintWriter w = new PrintWriter(new FileWriter(tocFile, true))) + try (FileOutputStream fos = new FileOutputStream(tocFile); + PrintWriter w = new PrintWriter(fos)) { for (Component component : components) w.println(component.name); + w.flush(); + fos.getFD().sync(); } catch (IOException e) { diff --git a/src/java/org/apache/cassandra/io/util/DataIntegrityMetadata.java b/src/java/org/apache/cassandra/io/util/DataIntegrityMetadata.java index cbf5753edd..79dfe2f64a 100644 --- a/src/java/org/apache/cassandra/io/util/DataIntegrityMetadata.java +++ b/src/java/org/apache/cassandra/io/util/DataIntegrityMetadata.java @@ -17,20 +17,20 @@ */ package org.apache.cassandra.io.util; -import java.io.BufferedWriter; +import java.io.BufferedOutputStream; import java.io.Closeable; import java.io.DataOutput; +import java.io.DataOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOError; import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.file.Files; +import java.nio.charset.StandardCharsets; import java.util.zip.CRC32; import java.util.zip.CheckedInputStream; import java.util.zip.Checksum; -import com.google.common.base.Charsets; - import org.apache.cassandra.io.FSWriteError; import org.apache.cassandra.io.sstable.Component; import org.apache.cassandra.io.sstable.Descriptor; @@ -209,9 +209,12 @@ public class DataIntegrityMetadata if (descriptor.digestComponent == null) throw new NullPointerException("Null digest component for " + descriptor.ksname + '.' + descriptor.cfname + " file " + descriptor.baseFilename()); File outFile = new File(descriptor.filenameFor(descriptor.digestComponent)); - try (BufferedWriter out =Files.newBufferedWriter(outFile.toPath(), Charsets.UTF_8)) + try (FileOutputStream fos = new FileOutputStream(outFile); + DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos))) { - out.write(String.valueOf(fullChecksum.getValue())); + out.write(String.valueOf(fullChecksum.getValue()).getBytes(StandardCharsets.UTF_8)); + out.flush(); + fos.getFD().sync(); } catch (IOException e) {