From 6d568668c55812dd0f032e12541e44f71619b460 Mon Sep 17 00:00:00 2001 From: Yi WU Date: Sun, 24 Apr 2022 15:56:10 +0800 Subject: [PATCH 1/2] rename ImageSeq to LatestImageSeq in Storage --- .../org/apache/doris/catalog/Catalog.java | 4 +- .../doris/httpv2/controller/HaController.java | 2 +- .../apache/doris/httpv2/meta/MetaService.java | 2 +- .../apache/doris/httpv2/rest/ShowAction.java | 2 +- .../org/apache/doris/master/Checkpoint.java | 2 +- .../org/apache/doris/persist/MetaCleaner.java | 2 +- .../org/apache/doris/persist/Storage.java | 48 +++++++++---------- .../org/apache/doris/persist/StorageTest.java | 8 ++-- 8 files changed, 34 insertions(+), 36 deletions(-) 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..07716a8629c389 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 @@ -1531,7 +1531,7 @@ private boolean getVersionFileFromHelper(Pair helperNode) throw private void getNewImage(Pair helperNode) throws IOException { long localImageVersion = 0; Storage storage = new Storage(this.imageDir); - localImageVersion = storage.getImageSeq(); + localImageVersion = storage.getLatestImageSeq(); try { URL infoUrl = new URL("http://" + helperNode.first + ":" + Config.http_port + "/info"); @@ -1617,7 +1617,7 @@ public void loadImage(String imageDir) throws IOException, DdlException { LOG.info("image does not exist: {}", curFile.getAbsolutePath()); return; } - replayedJournalId.set(storage.getImageSeq()); + replayedJournalId.set(storage.getLatestImageSeq()); MetaReader.read(curFile, this); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/controller/HaController.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/controller/HaController.java index cc983ad6e88418..515c933e86c966 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/controller/HaController.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/controller/HaController.java @@ -134,7 +134,7 @@ private void appendImageInfo(Map result) { Map checkPoint = new HashMap<>(); Storage storage = new Storage(Config.meta_dir + "/image"); checkPoint.put("Name", "Version"); - checkPoint.put("Value", storage.getImageSeq()); + checkPoint.put("Value", storage.getLatestImageSeq()); list.add(checkPoint); long lastCheckpointTime = storage.getCurrentImageFile().lastModified(); Date date = new Date(lastCheckpointTime); diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/meta/MetaService.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/meta/MetaService.java index 22796efb42c71a..48d0e4720fd6ff 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/meta/MetaService.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/meta/MetaService.java @@ -111,7 +111,7 @@ public Object info(HttpServletRequest request, HttpServletResponse response) thr try { Storage currentStorageInfo = new Storage(imageDir.getAbsolutePath()); StorageInfo storageInfo = new StorageInfo(currentStorageInfo.getClusterID(), - currentStorageInfo.getImageSeq(), currentStorageInfo.getEditsSeq()); + currentStorageInfo.getLatestImageSeq(), currentStorageInfo.getEditsSeq()); return ResponseEntityBuilder.ok(storageInfo); } catch (IOException e) { return ResponseEntityBuilder.internalError(e.getMessage()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/ShowAction.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/ShowAction.java index e08ebe5fd75d23..e3543db69325b9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/ShowAction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/ShowAction.java @@ -242,7 +242,7 @@ private Map getHaInfo() throws IOException { feInfo.put("is_ready", String.valueOf(Catalog.getCurrentCatalog().isReady())); Storage storage = new Storage(Config.meta_dir + "/image"); - feInfo.put("last_checkpoint_version", String.valueOf(storage.getImageSeq())); + feInfo.put("last_checkpoint_version", String.valueOf(storage.getLatestImageSeq())); long lastCheckpointTime = storage.getCurrentImageFile().lastModified(); feInfo.put("last_checkpoint_time", String.valueOf(lastCheckpointTime)); diff --git a/fe/fe-core/src/main/java/org/apache/doris/master/Checkpoint.java b/fe/fe-core/src/main/java/org/apache/doris/master/Checkpoint.java index 69efd618f85f99..9f93fd610aa02b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/master/Checkpoint.java +++ b/fe/fe-core/src/main/java/org/apache/doris/master/Checkpoint.java @@ -83,7 +83,7 @@ public synchronized void doCheckpoint() { try { storage = new Storage(imageDir); // get max image version - imageVersion = storage.getImageSeq(); + imageVersion = storage.getLatestImageSeq(); // get max finalized journal id checkPointVersion = editLog.getFinalizedJournalId(); LOG.info("last checkpoint journal id: {}, current finalized journal id: {}", imageVersion, checkPointVersion); diff --git a/fe/fe-core/src/main/java/org/apache/doris/persist/MetaCleaner.java b/fe/fe-core/src/main/java/org/apache/doris/persist/MetaCleaner.java index 2c2b17a9410c13..81af578e8e93ff 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/persist/MetaCleaner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/persist/MetaCleaner.java @@ -34,7 +34,7 @@ public MetaCleaner(String imageDir) { public void clean() throws IOException { Storage storage = new Storage(imageDir); - long currentVersion = storage.getImageSeq(); + long currentVersion = storage.getLatestImageSeq(); long imageDeleteVersion = currentVersion - 1; File currentImage = storage.getImageFile(currentVersion); diff --git a/fe/fe-core/src/main/java/org/apache/doris/persist/Storage.java b/fe/fe-core/src/main/java/org/apache/doris/persist/Storage.java index 999687cdcfb60b..bfd99a4ce74fe0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/persist/Storage.java +++ b/fe/fe-core/src/main/java/org/apache/doris/persist/Storage.java @@ -60,7 +60,7 @@ public class Storage { private FrontendNodeType role = FrontendNodeType.UNKNOWN; private String nodeName; private long editsSeq; - private long imageSeq; + private long latestImageSeq; private String metaDir; private List editsFileSequenceNumbers; @@ -70,11 +70,11 @@ public Storage(int clusterID, String token, String metaDir) { this.metaDir = metaDir; } - public Storage(int clusterID, String token, long imageSeq, long editsSeq, String metaDir) { + public Storage(int clusterID, String token, long latestImageSeq, long editsSeq, String metaDir) { this.clusterID = clusterID; this.token = token; this.editsSeq = editsSeq; - this.imageSeq = imageSeq; + this.latestImageSeq = latestImageSeq; this.metaDir = metaDir; } @@ -114,31 +114,29 @@ public void reload() throws IOException { nodeName = prop.getProperty(NODE_NAME, null); } - // Find the latest image + // Find the latest two images File dir = new File(metaDir); File[] children = dir.listFiles(); if (children == null) { return; - } else { - for (File child : children) { - String name = child.getName(); - try { - if (!name.equals(EDITS) && !name.equals(IMAGE_NEW) - && !name.endsWith(".part") && name.contains(".")) { - if (name.startsWith(IMAGE)) { - imageSeq = Math.max(Long.parseLong(name.substring(name.lastIndexOf('.') + 1)), imageSeq); - } else if (name.startsWith(EDITS)) { - // Just record the sequence part of the file name - editsFileSequenceNumbers.add(Long.parseLong(name.substring(name.lastIndexOf('.') + 1))); - editsSeq = Math.max(Long.parseLong(name.substring(name.lastIndexOf('.') + 1)), editsSeq); - } + } + for (File child : children) { + String name = child.getName(); + try { + if (!name.equals(EDITS) && !name.equals(IMAGE_NEW) + && !name.endsWith(".part") && name.contains(".")) { + if (name.startsWith(IMAGE)) { + latestImageSeq = Math.max(Long.parseLong(name.substring(name.lastIndexOf('.') + 1)), latestImageSeq); + } else if (name.startsWith(EDITS)) { + // Just record the sequence part of the file name + editsFileSequenceNumbers.add(Long.parseLong(name.substring(name.lastIndexOf('.') + 1))); + editsSeq = Math.max(Long.parseLong(name.substring(name.lastIndexOf('.') + 1)), editsSeq); } - } catch (Exception e) { - LOG.warn(name + " is not a validate meta file, ignore it"); } + } catch (Exception e) { + LOG.warn(name + " is not a validate meta file, ignore it"); } } - } public int getClusterID() { @@ -173,12 +171,12 @@ public void setMetaDir(String metaDir) { this.metaDir = metaDir; } - public long getImageSeq() { - return imageSeq; + public long getLatestImageSeq() { + return latestImageSeq; } - public void setImageSeq(long imageSeq) { - this.imageSeq = imageSeq; + public void setLatestImageSeq(long latestImageSeq) { + this.latestImageSeq = latestImageSeq; } public void setEditsSeq(long editsSeq) { @@ -272,7 +270,7 @@ public static void rename(File from, File to) throws IOException { } public File getCurrentImageFile() { - return getImageFile(imageSeq); + return getImageFile(latestImageSeq); } public File getImageFile(long version) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/persist/StorageTest.java b/fe/fe-core/src/test/java/org/apache/doris/persist/StorageTest.java index 1c2237a794a253..ca17a0006c449c 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/persist/StorageTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/persist/StorageTest.java @@ -102,7 +102,7 @@ public void testConstruct() { Storage storage2 = new Storage(1, "token", 2, 3, "test"); Assert.assertEquals(1, storage2.getClusterID()); - Assert.assertEquals(2, storage2.getImageSeq()); + Assert.assertEquals(2, storage2.getLatestImageSeq()); Assert.assertEquals(3, storage2.getEditsSeq()); Assert.assertEquals("test", storage2.getMetaDir()); } @@ -116,7 +116,7 @@ public void testStorage() throws Exception { Assert.assertEquals(966271669, storage.getClusterID()); storage.setClusterID(1234); Assert.assertEquals(1234, storage.getClusterID()); - Assert.assertEquals(0, storage.getImageSeq()); + Assert.assertEquals(0, storage.getLatestImageSeq()); Assert.assertEquals(10, Storage.getMetaSeq(new File("storageTestDir/edits.10"))); Assert.assertTrue(Storage.getCurrentEditsFile(new File("storageTestDir")) .equals(new File("storageTestDir/edits"))); @@ -133,8 +133,8 @@ public void testStorage() throws Exception { Assert.assertTrue(storage.getVersionFile().equals(new File("storageTestDir/VERSION"))); - storage.setImageSeq(100); - Assert.assertEquals(100, storage.getImageSeq()); + storage.setLatestImageSeq(100); + Assert.assertEquals(100, storage.getLatestImageSeq()); storage.setEditsSeq(100); Assert.assertEquals(100, storage.getEditsSeq()); From b4a6428a5d0c9acdacd6926be762984eae80d15e Mon Sep 17 00:00:00 2001 From: Yi WU Date: Sun, 24 Apr 2022 16:24:59 +0800 Subject: [PATCH 2/2] keep at least one validated image file --- .../main/java/org/apache/doris/master/Checkpoint.java | 6 ++++-- .../java/org/apache/doris/persist/MetaCleaner.java | 2 +- .../main/java/org/apache/doris/persist/Storage.java | 11 ++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/master/Checkpoint.java b/fe/fe-core/src/main/java/org/apache/doris/master/Checkpoint.java index 9f93fd610aa02b..7865817a824c45 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/master/Checkpoint.java +++ b/fe/fe-core/src/main/java/org/apache/doris/master/Checkpoint.java @@ -184,7 +184,9 @@ public synchronized void doCheckpoint() { if (successPushed == otherNodesCount) { try { long minOtherNodesJournalId = Long.MAX_VALUE; - long deleteVersion = checkPointVersion; + // Actually, storage.getLatestValidatedImageSeq returns number before this + // checkpoint. + long deleteVersion = storage.getLatestValidatedImageSeq(); if (successPushed > 0) { for (Frontend fe : allFrontends) { String host = fe.getHost(); @@ -220,7 +222,7 @@ public synchronized void doCheckpoint() { } } } - deleteVersion = Math.min(minOtherNodesJournalId, checkPointVersion); + deleteVersion = Math.min(minOtherNodesJournalId, deleteVersion); } editLog.deleteJournals(deleteVersion + 1); diff --git a/fe/fe-core/src/main/java/org/apache/doris/persist/MetaCleaner.java b/fe/fe-core/src/main/java/org/apache/doris/persist/MetaCleaner.java index 81af578e8e93ff..2a7acd1f09fb87 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/persist/MetaCleaner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/persist/MetaCleaner.java @@ -34,7 +34,7 @@ public MetaCleaner(String imageDir) { public void clean() throws IOException { Storage storage = new Storage(imageDir); - long currentVersion = storage.getLatestImageSeq(); + long currentVersion = storage.getLatestValidatedImageSeq(); long imageDeleteVersion = currentVersion - 1; File currentImage = storage.getImageFile(currentVersion); diff --git a/fe/fe-core/src/main/java/org/apache/doris/persist/Storage.java b/fe/fe-core/src/main/java/org/apache/doris/persist/Storage.java index bfd99a4ce74fe0..8eb0336d716b82 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/persist/Storage.java +++ b/fe/fe-core/src/main/java/org/apache/doris/persist/Storage.java @@ -61,6 +61,7 @@ public class Storage { private String nodeName; private long editsSeq; private long latestImageSeq; + private long latestValidatedImageSeq; private String metaDir; private List editsFileSequenceNumbers; @@ -126,7 +127,11 @@ public void reload() throws IOException { if (!name.equals(EDITS) && !name.equals(IMAGE_NEW) && !name.endsWith(".part") && name.contains(".")) { if (name.startsWith(IMAGE)) { - latestImageSeq = Math.max(Long.parseLong(name.substring(name.lastIndexOf('.') + 1)), latestImageSeq); + long fileSeq = Long.parseLong(name.substring(name.lastIndexOf('.') + 1)); + if (latestImageSeq < fileSeq) { + latestValidatedImageSeq = latestImageSeq; + latestImageSeq = fileSeq; + } } else if (name.startsWith(EDITS)) { // Just record the sequence part of the file name editsFileSequenceNumbers.add(Long.parseLong(name.substring(name.lastIndexOf('.') + 1))); @@ -175,6 +180,10 @@ public long getLatestImageSeq() { return latestImageSeq; } + public long getLatestValidatedImageSeq() { + return latestValidatedImageSeq; + } + public void setLatestImageSeq(long latestImageSeq) { this.latestImageSeq = latestImageSeq; }