Ensure we only rollback IW once (#1764)

Ensure we only rollback IW once

Today we might rollback IW more than once if we hit an exception during
the rollback code when we shutdown. This change moves the rollback code outside
the try block to ensure we always roll back but never roll back twice.
This commit is contained in:
Simon Willnauer 2020-08-20 08:40:25 +02:00 committed by GitHub
parent 8caf57d50b
commit 5fcb859ece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 1 deletions

View File

@ -1097,7 +1097,6 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable,
flush(true, true); flush(true, true);
waitForMerges(); waitForMerges();
commitInternal(config.getMergePolicy()); commitInternal(config.getMergePolicy());
rollbackInternal(); // ie close, since we just committed
} catch (Throwable t) { } catch (Throwable t) {
// Be certain to close the index on any exception // Be certain to close the index on any exception
try { try {
@ -1107,6 +1106,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable,
} }
throw t; throw t;
} }
rollbackInternal(); // if we got that far lets rollback and close
} }
} }

View File

@ -2023,4 +2023,44 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
dir.close(); dir.close();
} }
public void testOnlyRollbackOnceOnException() throws IOException {
AtomicBoolean once = new AtomicBoolean(false);
InfoStream stream = new InfoStream() {
@Override
public void message(String component, String message) {
if ("TP".equals(component) && "rollback before checkpoint".equals(message)) {
if (once.compareAndSet(false, true)) {
throw new RuntimeException("boom");
} else {
throw new AssertionError("has been rolled back twice");
}
}
}
@Override
public boolean isEnabled(String component) {
return "TP".equals(component);
}
@Override
public void close() {
}
};
try (Directory dir = newDirectory()) {
try (IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig().setInfoStream(stream)){
@Override
protected boolean isEnableTestPoints() {
return true;
}
}) {
}
} catch (RuntimeException e) {
assertEquals("boom", e.getMessage());
assertEquals("has suppressed exceptions: " + Arrays.toString(e.getSuppressed()), 0, e.getSuppressed().length);
assertNull(e.getCause());
}
}
} }