diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 663fffd..af1f11b 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 b66e088..7527e8c 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 0005340..4d26414 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();