From f60e26e77178a34e87c8e5c6d907f70a18207801 Mon Sep 17 00:00:00 2001 From: Jean-Daniel Cryans Date: Fri, 2 Apr 2010 00:55:03 +0000 Subject: [PATCH] HBASE-2087 The wait on compaction because "Too many store files" holds up all flushing git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@930143 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 2 ++ .../hbase/regionserver/MemStoreFlusher.java | 29 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index f73fb1aed32..2b7c5db2925 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -479,6 +479,8 @@ Release 0.21.0 - Unreleased HBASE-2388 Give a very explicit message when we figure a big GC pause HBASE-2270 Improve how we handle recursive calls in ExplicitColumnTracker and WildcardColumnTracker + HBASE-2087 The wait on compaction because "Too many store files" + holds up all flushing NEW FEATURES HBASE-1961 HBase EC2 scripts diff --git a/core/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java b/core/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java index abc763f7566..7578446237e 100644 --- a/core/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java +++ b/core/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreFlusher.java @@ -215,7 +215,25 @@ class MemStoreFlusher extends Thread implements FlushRequester { * not flushed. */ private boolean flushRegion(HRegion region, boolean removeFromQueue) { - checkStoreFileCount(region); + // if removeFromQueue, then we come from flushSomeRegions and we need + // to block if there's too many store files. Else, we don't want to hang + // the main flushing thread so we'll just the region at the end of the + // queue if there's too many files. + if (removeFromQueue) { + checkStoreFileCount(region); + } else if (isTooManyStoreFiles(region)) { + LOG.warn("Region " + region.getRegionNameAsString() + " has too many " + + "store files, putting it back at the end of the flush queue."); + server.compactSplitThread.compactionRequested(region, getName()); + // If there's only this item in the queue or they are all in this + // situation, we will loop at lot. Sleep a bit. + try { + Thread.sleep(1000); + } catch (InterruptedException e) { } // just continue + flushQueue.add(region); + // Tell a lie, it's not flushed but it's ok + return true; + } synchronized (regionsInQueue) { // See comment above for removeFromQueue on why we do not // take the region out of the set. If removeFromQueue is true, remove it @@ -303,6 +321,15 @@ class MemStoreFlusher extends Thread implements FlushRequester { } } + private boolean isTooManyStoreFiles(HRegion region) { + for (Store hstore: region.stores.values()) { + if (hstore.getStorefilesCount() > this.blockingStoreFilesNumber) { + return true; + } + } + return false; + } + /** * Check if the regionserver's memstore memory usage is greater than the * limit. If so, flush regions with the biggest memstores until we're down