diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 663fffd2686..af1f11b7470 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -140,6 +140,10 @@ Bug Fixes IndexWriter to only delete files matching this pattern from an index directory, to reduce risk when the wrong index path is accidentally passed to IndexWriter (Robert Muir, Mike McCandless) + +* LUCENE-4277: Fix IndexWriter deadlock during rollback if flushable DWPT + instance are already checked out and queued up but not yet flushed. + (Simon Willnauer) Changes in Runtime Behavior diff --git a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java index b66e088a039..7527e8c740d 100644 --- a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java +++ b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java @@ -202,11 +202,9 @@ final class DocumentsWriter { * discarding any docs added since last flush. */ synchronized void abort() { boolean success = false; - synchronized (this) { - deleteQueue.clear(); - } try { + deleteQueue.clear(); if (infoStream.isEnabled("DW")) { infoStream.message("DW", "abort"); } @@ -230,6 +228,7 @@ final class DocumentsWriter { perThread.unlock(); } } + flushControl.abortPendingFlushes(); flushControl.waitForFlush(); success = true; } finally { diff --git a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java index 00053403588..4d264144cab 100644 --- a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java +++ b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java @@ -567,19 +567,34 @@ final class DocumentsWriterFlushControl { } synchronized void abortFullFlushes() { + try { + abortPendingFlushes(); + } finally { + fullFlush = false; + } + } + + synchronized void abortPendingFlushes() { try { for (DocumentsWriterPerThread dwpt : flushQueue) { - doAfterFlush(dwpt); - dwpt.abort(); + try { + dwpt.abort(); + doAfterFlush(dwpt); + } catch (Throwable ex) { + // ignore - keep on aborting the flush queue + } } for (BlockedFlush blockedFlush : blockedFlushes) { - flushingWriters - .put(blockedFlush.dwpt, Long.valueOf(blockedFlush.bytes)); - doAfterFlush(blockedFlush.dwpt); - blockedFlush.dwpt.abort(); + try { + flushingWriters + .put(blockedFlush.dwpt, Long.valueOf(blockedFlush.bytes)); + blockedFlush.dwpt.abort(); + doAfterFlush(blockedFlush.dwpt); + } catch (Throwable ex) { + // ignore - keep on aborting the blocked queue + } } } finally { - fullFlush = false; flushQueue.clear(); blockedFlushes.clear(); updateStallState();