You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by nk...@apache.org on 2020/01/30 20:55:15 UTC
[zookeeper] branch branch-3.5 updated: ZOOKEEPER-3701: Split brain
on log disk full (3.5)
This is an automated email from the ASF dual-hosted git repository.
nkalmar pushed a commit to branch branch-3.5
in repository https://gitbox.apache.org/repos/asf/zookeeper.git
The following commit(s) were added to refs/heads/branch-3.5 by this push:
new 7dd25bb ZOOKEEPER-3701: Split brain on log disk full (3.5)
7dd25bb is described below
commit 7dd25bb8bf3925c3da1eb452b8916a6b2becfe61
Author: Andor Molnar <an...@apache.org>
AuthorDate: Thu Jan 30 21:55:08 2020 +0100
ZOOKEEPER-3701: Split brain on log disk full (3.5)
Backport of #1233
Unfortunately the unit test cannot be backported, because 3.5 doesn't have the abstract `requestSystemExit` feature.
Author: Andor Molnar <an...@apache.org>
Reviewers: Norbert Kalmar <nk...@apache.org>
Closes #1237 from anmolnar/ZOOKEEPER-3701_35
---
.../zookeeper/server/persistence/FileSnap.java | 2 +
.../zookeeper/server/persistence/FileTxnLog.java | 4 +-
.../server/persistence/FileTxnSnapLog.java | 49 +++++++++++++---------
.../org/apache/zookeeper/common/NetUtilsTest.java | 19 ++++++++-
.../org/apache/zookeeper/test/TruncateTest.java | 14 +++----
5 files changed, 59 insertions(+), 29 deletions(-)
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileSnap.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileSnap.java
index f6f2ac5..6bce62d 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileSnap.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileSnap.java
@@ -230,6 +230,8 @@ public class FileSnap implements SnapShot {
oa.writeString("/", "path");
sessOS.flush();
}
+ } else {
+ throw new IOException("FileSnap has already been closed");
}
}
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java
index a3c8702..c30de50 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java
@@ -19,6 +19,7 @@ package org.apache.zookeeper.server.persistence;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
+import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
@@ -89,7 +90,8 @@ import org.slf4j.LoggerFactory;
* 0 padded to EOF (filled during preallocation stage)
* </pre></blockquote>
*/
-public class FileTxnLog implements TxnLog {
+public class FileTxnLog implements TxnLog, Closeable {
+
private static final Logger LOG;
public final static int TXNLOG_MAGIC =
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
index 47f025d..8508413 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
@@ -414,23 +414,28 @@ public class FileTxnSnapLog {
* @return true if able to truncate the log, false if not
* @throws IOException
*/
- public boolean truncateLog(long zxid) throws IOException {
- // close the existing txnLog and snapLog
- close();
-
- // truncate it
- FileTxnLog truncLog = new FileTxnLog(dataDir);
- boolean truncated = truncLog.truncate(zxid);
- truncLog.close();
-
- // re-open the txnLog and snapLog
- // I'd rather just close/reopen this object itself, however that
- // would have a big impact outside ZKDatabase as there are other
- // objects holding a reference to this object.
- txnLog = new FileTxnLog(dataDir);
- snapLog = new FileSnap(snapDir);
-
- return truncated;
+ public boolean truncateLog(long zxid) {
+ try {
+ // close the existing txnLog and snapLog
+ close();
+
+ // truncate it
+ try (FileTxnLog truncLog = new FileTxnLog(dataDir)) {
+ boolean truncated = truncLog.truncate(zxid);
+
+ // re-open the txnLog and snapLog
+ // I'd rather just close/reopen this object itself, however that
+ // would have a big impact outside ZKDatabase as there are other
+ // objects holding a reference to this object.
+ txnLog = new FileTxnLog(dataDir);
+ snapLog = new FileSnap(snapDir);
+
+ return truncated;
+ }
+ } catch (IOException e) {
+ LOG.error("Unable to truncate Txn log", e);
+ return false;
+ }
}
/**
@@ -509,8 +514,14 @@ public class FileTxnSnapLog {
* @throws IOException
*/
public void close() throws IOException {
- txnLog.close();
- snapLog.close();
+ if (txnLog != null) {
+ txnLog.close();
+ txnLog = null;
+ }
+ if (snapLog != null) {
+ snapLog.close();
+ snapLog = null;
+ }
}
@SuppressWarnings("serial")
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/common/NetUtilsTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/common/NetUtilsTest.java
index 9887926..4f8379e 100644
--- a/zookeeper-server/src/test/java/org/apache/zookeeper/common/NetUtilsTest.java
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/common/NetUtilsTest.java
@@ -1,6 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package org.apache.zookeeper.common;
-import org.apache.zookeeper.common.NetUtils;
import org.apache.zookeeper.ZKTestCase;
import org.hamcrest.core.AnyOf;
import org.hamcrest.core.IsEqual;
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/TruncateTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/TruncateTest.java
index cae2d9f..6be1d36 100644
--- a/zookeeper-server/src/test/java/org/apache/zookeeper/test/TruncateTest.java
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/TruncateTest.java
@@ -18,6 +18,9 @@
package org.apache.zookeeper.test;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
@@ -122,14 +125,9 @@ public class TruncateTest extends ZKTestCase {
Assert.assertTrue("Failed to delete log file: " + logs[i].getName(), logs[i].delete());
}
try {
- zkdb.truncateLog(1);
- Assert.assertTrue("Should not get here", false);
- }
- catch(IOException e) {
- Assert.assertTrue("Should have received an IOException", true);
- }
- catch(NullPointerException npe) {
- Assert.fail("This should not throw NPE!");
+ assertThat("truncateLog() should return false if truncation fails instead of throwing exception", zkdb.truncateLog(1), is(false));
+ } catch (NullPointerException npe) {
+ fail("This should not throw NPE!");
}
ClientBase.recursiveDelete(tmpdir);