kezhuw commented on code in PR #2141:
URL: https://github.com/apache/zookeeper/pull/2141#discussion_r1730657993


##########
zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java:
##########
@@ -701,14 +708,26 @@ public long getStorageSize() {
 
         /**
          * go to the next logfile
+         *
          * @return true if there is one and false if there is no
          * new file to be read
-         * @throws IOException
          */
         private boolean goToNextLog() throws IOException {
-            if (storedFiles.size() > 0) {
+            if (!storedFiles.isEmpty()) {
                 this.logFile = storedFiles.remove(storedFiles.size() - 1);
-                ia = createInputArchive(this.logFile);
+                try {
+                    ia = createInputArchive(this.logFile);
+                } catch (EOFException ex) {
+                    // If this file is the last log file in the database and 
is empty,
+                    // it means that the last time the file was created
+                    // before the header was written.
+                    if (storedFiles.isEmpty() && this.logFile.length() == 0) {
+                        boolean deleted = this.logFile.delete();
+                        LOG.warn("Delete empty log file at the tail to recover 
from corruption. file: {}, deleted: {}",

Review Comment:
   Also add hint to reboot ?



##########
zookeeper-server/src/test/java/org/apache/zookeeper/server/persistence/FileTxnLogTest.java:
##########
@@ -296,6 +302,73 @@ public void testLogSizeLimit(@TempDir File tmpDir) throws 
Exception {
         }
     }
 
+    private void prepareTxnLogs(File dir, int n) throws IOException {
+        FileTxnLog.setTxnLogSizeLimit(1);
+        FileTxnLog log = new FileTxnLog(dir);
+        CreateRequest record = new CreateRequest(null, new byte[NODE_SIZE],
+                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT.toFlag());
+        int zxid = 1;
+        for (int i = 0; i < n; i++) {
+            log.append(new Request(0, 0, 0, new TxnHeader(0, 0, zxid, 0, -1), 
record, zxid));
+            zxid++;
+            log.commit();
+        }
+        log.close();
+    }
+
+    public void testEmptyTxnLog(boolean clearTail) throws IOException {
+        // prepare a database with logs
+        File tmpDir = ClientBase.createTmpDir();
+        LOG.info("tmp dir: {}", tmpDir.getPath());
+        ClientBase.setupTestEnv();
+        prepareTxnLogs(tmpDir, 4);
+
+        // clear the log
+        List<File> files = Arrays.
+                stream(Objects.requireNonNull(tmpDir.listFiles((File f, String 
name) -> name.startsWith("log.")))).
+                sorted(Comparator.comparing(File::getName)).
+                collect(Collectors.toList());
+        File toClear;
+        if (clearTail) {
+            toClear = files.get(files.size() - 1);
+        } else {
+            toClear = files.get(files.size() - 2);
+        }
+        PrintWriter writer = new PrintWriter(toClear);
+        writer.close();
+        LOG.info("Txn log file {} cleared", toClear.getName());
+
+        // open txn log
+        boolean isEof = false;
+        try {
+            FileTxnLog.FileTxnIterator itr = new 
FileTxnLog.FileTxnIterator(tmpDir, 0x0, false);
+            while (itr.next()) {}
+        } catch (EOFException ex) {
+            isEof = true;
+        }
+
+        if (clearTail) {
+            FileTxnLog.FileTxnIterator itr = new 
FileTxnLog.FileTxnIterator(tmpDir, 0x0, false);
+            while (itr.next()) {}
+        } else {
+            assertTrue(isEof, "Mid txn log file empty should throw Exception");
+        }
+    }
+
+    @Test
+    public void testEmptyTailTxnLog() throws IOException {
+        long limit = FileTxnLog.getTxnLogSizeLimit();
+        testEmptyTxnLog(true);

Review Comment:
   How about repeat some code to let's easy with testing code ?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@zookeeper.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to