Repository: hbase Updated Branches: refs/heads/branch-1 18c54b02b -> 875a12de0 refs/heads/branch-1.3 988f6d1f8 -> 9eaafe1ee refs/heads/branch-1.4 52ea97986 -> 7e2d7edbc
HBASE-20322 CME in StoreScanner causes region server crash Signed-off-by: Andrew Purtell <apurt...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/9eaafe1e Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/9eaafe1e Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/9eaafe1e Branch: refs/heads/branch-1.3 Commit: 9eaafe1ee91bc12d8933e17ad6cab7af8251c0f5 Parents: 988f6d1 Author: Thiruvel Thirumoolan <thiru...@oath.com> Authored: Fri Mar 30 13:12:53 2018 -0700 Committer: Andrew Purtell <apurt...@apache.org> Committed: Mon Apr 2 19:36:03 2018 -0700 ---------------------------------------------------------------------- .../hadoop/hbase/regionserver/StoreScanner.java | 35 +++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/9eaafe1e/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java index c95151b..1b2361d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java @@ -443,17 +443,29 @@ public class StoreScanner extends NonReversedNonLazyKeyValueScanner @Override public void close() { - if (this.closing) return; - this.closing = true; - clearAndClose(scannersForDelayedClose); - clearAndClose(memStoreScannersAfterFlush); - // clear them at any case. In case scanner.next() was never called - // and there were some lease expiry we need to close all the scanners - // on the flushed files which are open - clearAndClose(flushedstoreFileScanners); + if (this.closing) { + return; + } + // Lets remove from observers as early as possible // Under test, we dont have a this.store - if (this.store != null) + if (this.store != null) { this.store.deleteChangedReaderObserver(this); + } + // There is a race condition between close() and updateReaders(), during region flush. So, + // even though its just close, we will still acquire the flush lock, as a + // ConcurrentModificationException will abort the regionserver. + flushLock.lock(); + try { + this.closing = true; + clearAndClose(scannersForDelayedClose); + clearAndClose(memStoreScannersAfterFlush); + // clear them at any case. In case scanner.next() was never called + // and there were some lease expiry we need to close all the scanners + // on the flushed files which are open + clearAndClose(flushedstoreFileScanners); + } finally { + flushLock.unlock(); + } if (this.heap != null) this.heap.close(); this.heap = null; // CLOSED! @@ -809,6 +821,11 @@ public class StoreScanner extends NonReversedNonLazyKeyValueScanner } flushLock.lock(); try { + if (this.closing) { + // Lets close scanners created by caller, since close() won't notice this. + clearAndClose(memStoreScanners); + return; + } flushed = true; final boolean isCompaction = false; boolean usePread = get || scanUsePread;