diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java index a670dd2aebf67b..86d6763b241d61 100755 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java @@ -1966,8 +1966,13 @@ public void saveImage() throws IOException { } public void saveImage(File curFile, long replayedJournalId) throws IOException { - if (!curFile.exists()) { - curFile.createNewFile(); + if (curFile.exists()) { + if (!curFile.delete()) { + throw new IOException(curFile.getName() + " can not be deleted."); + } + } + if (!curFile.createNewFile()) { + throw new IOException(curFile.getName() + " can not be created."); } MetaWriter.write(curFile, this); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/MetaFooter.java b/fe/fe-core/src/main/java/org/apache/doris/common/MetaFooter.java index 9df82aa9b79394..426cd7b3d8215f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/MetaFooter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/MetaFooter.java @@ -98,6 +98,7 @@ public static void write(File imageFile, List metaIndices, long check long endIndex = raf.length(); raf.writeLong(endIndex - startIndex); MetaMagicNumber.write(raf); + raf.getChannel.force(true); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/MetaHeader.java b/fe/fe-core/src/main/java/org/apache/doris/common/MetaHeader.java index 5617a854483174..ba91b04b5df8fa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/MetaHeader.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/MetaHeader.java @@ -75,10 +75,15 @@ public static MetaHeader read(File imageFile) throws IOException { } public static long write(File imageFile) throws IOException { + if (imageFile.length() != 0) { + throw new IOException("Meta header has to be written to an empty file."); + } + try (RandomAccessFile raf = new RandomAccessFile(imageFile, "rw")) { raf.seek(0); MetaMagicNumber.write(raf); MetaJsonHeader.write(raf); + raf.getChannel.force(true); return raf.getFilePointer(); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/MetaWriter.java b/fe/fe-core/src/main/java/org/apache/doris/common/MetaWriter.java index 6b9d9aa79106ea..387a50be3dd201 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/MetaWriter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/MetaWriter.java @@ -94,14 +94,15 @@ public long doWork(String name, WriteMethod method) throws IOException { public static void write(File imageFile, Catalog catalog) throws IOException { // save image does not need any lock. because only checkpoint thread will call this method. - LOG.info("start save image to {}. is ckpt: {}", imageFile.getAbsolutePath(), Catalog.isCheckpointThread()); - + LOG.info("start to save image to {}. is ckpt: {}", imageFile.getAbsolutePath(), Catalog.isCheckpointThread()); final Reference checksum = new Reference<>(0L); long saveImageStartTime = System.currentTimeMillis(); + // MetaHeader should use output stream in the future. long startPosition = MetaHeader.write(imageFile); List metaIndices = Lists.newArrayList(); + FileOutputStream imageFileOut = new FileOutputStream(imageFile, true); try (CountingDataOutputStream dos = new CountingDataOutputStream(new BufferedOutputStream( - new FileOutputStream(imageFile, true)), startPosition)) { + imageFileOut), startPosition)) { writer.setDelegate(dos, metaIndices); long replayedJournalId = catalog.getReplayedJournalId(); checksum.setRef(writer.doWork("header", () -> catalog.saveHeader(dos, replayedJournalId, checksum.getRef()))); @@ -128,6 +129,7 @@ public static void write(File imageFile, Catalog catalog) throws IOException { checksum.setRef(writer.doWork("plugins", () -> catalog.savePlugins(dos, checksum.getRef()))); checksum.setRef(writer.doWork("deleteHandler", () -> catalog.saveDeleteHandler(dos, checksum.getRef()))); checksum.setRef(writer.doWork("sqlBlockRule", () -> catalog.saveSqlBlockRule(dos, checksum.getRef()))); + imageFileOut.getChannel().force(true); } MetaFooter.write(imageFile, metaIndices, checksum.getRef());