You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2010/05/04 23:57:26 UTC
svn commit: r941068 - in /hadoop/hbase/branches/0.20_pre_durability:
CHANGES.txt src/java/org/apache/hadoop/hbase/regionserver/HRegion.java
src/test/org/apache/hadoop/hbase/regionserver/TestHRegion.java
Author: stack
Date: Tue May 4 21:57:26 2010
New Revision: 941068
URL: http://svn.apache.org/viewvc?rev=941068&view=rev
Log:
HBASE-2509 NPEs in various places, HRegion.get, HRS.close
Modified:
hadoop/hbase/branches/0.20_pre_durability/CHANGES.txt
hadoop/hbase/branches/0.20_pre_durability/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java
hadoop/hbase/branches/0.20_pre_durability/src/test/org/apache/hadoop/hbase/regionserver/TestHRegion.java
Modified: hadoop/hbase/branches/0.20_pre_durability/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20_pre_durability/CHANGES.txt?rev=941068&r1=941067&r2=941068&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20_pre_durability/CHANGES.txt (original)
+++ hadoop/hbase/branches/0.20_pre_durability/CHANGES.txt Tue May 4 21:57:26 2010
@@ -65,6 +65,8 @@ Release 0.20.4 - Mon May 3 16:16:02 PDT
HBASE-2497 ProcessServerShutdown throws NullPointerException for offline
regions
HBASE-2499 Race condition when disabling a table leaves regions in transition
+ HBASE-2509 NPEs in various places, HRegion.get, HRS.close
+ (Ryan Rawson via Stack)
IMPROVEMENTS
HBASE-2180 Bad read performance from synchronizing hfile.fddatainputstream
Modified: hadoop/hbase/branches/0.20_pre_durability/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20_pre_durability/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java?rev=941068&r1=941067&r2=941068&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20_pre_durability/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java (original)
+++ hadoop/hbase/branches/0.20_pre_durability/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java Tue May 4 21:57:26 2010
@@ -1809,7 +1809,8 @@ public class HRegion implements HConstan
* It is used to combine scanners from multiple Stores (aka column families).
*/
class RegionScanner implements InternalScanner {
- private KeyValueHeap storeHeap = null;
+ // Package local for testability
+ KeyValueHeap storeHeap = null;
private final byte [] stopRow;
private Filter filter;
private RowFilterInterface oldFilter;
@@ -1974,7 +1975,10 @@ public class HRegion implements HConstan
}
public void close() {
- storeHeap.close();
+ if (storeHeap != null) {
+ storeHeap.close();
+ storeHeap = null;
+ }
}
/**
@@ -1986,13 +1990,6 @@ public class HRegion implements HConstan
scanner.close();
} catch(NullPointerException npe) {}
}
-
- /**
- * @return the current storeHeap
- */
- public KeyValueHeap getStoreHeap() {
- return this.storeHeap;
- }
}
// Utility methods
Modified: hadoop/hbase/branches/0.20_pre_durability/src/test/org/apache/hadoop/hbase/regionserver/TestHRegion.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20_pre_durability/src/test/org/apache/hadoop/hbase/regionserver/TestHRegion.java?rev=941068&r1=941067&r2=941068&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20_pre_durability/src/test/org/apache/hadoop/hbase/regionserver/TestHRegion.java (original)
+++ hadoop/hbase/branches/0.20_pre_durability/src/test/org/apache/hadoop/hbase/regionserver/TestHRegion.java Tue May 4 21:57:26 2010
@@ -25,6 +25,9 @@ import java.util.List;
import java.util.TreeMap;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import junit.framework.Assert;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -41,19 +44,17 @@ import org.apache.hadoop.hbase.client.Ge
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;
+import org.apache.hadoop.hbase.filter.CompareFilter;
+import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.PrefixFilter;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
-import org.apache.hadoop.hbase.filter.CompareFilter;
-import org.apache.hadoop.hbase.filter.BinaryComparator;
-import org.apache.hadoop.hbase.filter.RowFilter;
-import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.regionserver.HRegion.RegionScanner;
import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.hbase.util.Pair;
-import junit.framework.Assert;
/**
* Basic stand-alone testing of HRegion.
@@ -91,7 +92,94 @@ public class TestHRegion extends HBaseTe
// individual code pieces in the HRegion. Putting files locally in
// /tmp/testtable
//////////////////////////////////////////////////////////////////////////////
-
+
+ public void testGetWhileRegionClose() throws IOException {
+ HBaseConfiguration hc = initSplit();
+ int numRows = 100;
+ byte [][] families = {fam1, fam2, fam3};
+
+ //Setting up region
+ String method = this.getName();
+ initHRegion(tableName, method, hc, families);
+
+ // Put data in region
+ final int startRow = 100;
+ putData(startRow, numRows, qual1, families);
+ putData(startRow, numRows, qual2, families);
+ putData(startRow, numRows, qual3, families);
+ // this.region.flushcache();
+ final AtomicBoolean done = new AtomicBoolean(false);
+ final AtomicInteger gets = new AtomicInteger(0);
+ GetTillDoneOrException [] threads = new GetTillDoneOrException[10];
+ try {
+ // Set ten threads running concurrently getting from the region.
+ for (int i = 0; i < threads.length / 2; i++) {
+ threads[i] = new GetTillDoneOrException(i, Bytes.toBytes("" + startRow),
+ done, gets);
+ threads[i].setDaemon(true);
+ threads[i].start();
+ }
+ // Artificially make the condition by setting closing flag explicitly.
+ // I can't make the issue happen with a call to region.close().
+ this.region.closing.set(true);
+ for (int i = threads.length / 2; i < threads.length; i++) {
+ threads[i] = new GetTillDoneOrException(i, Bytes.toBytes("" + startRow),
+ done, gets);
+ threads[i].setDaemon(true);
+ threads[i].start();
+ }
+ } finally {
+ if (this.region != null) {
+ this.region.close();
+ this.region.getLog().closeAndDelete();
+ }
+ }
+ done.set(true);
+ for (GetTillDoneOrException t: threads) {
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if (t.e != null) {
+ LOG.info("Exception=" + t.e);
+ assertFalse("Found a NPE in " + t.getName(),
+ t.e instanceof NullPointerException);
+ }
+ }
+ }
+
+ /*
+ * Thread that does get on single row until 'done' flag is flipped. If an
+ * exception causes us to fail, it records it.
+ */
+ class GetTillDoneOrException extends Thread {
+ private final Get g;
+ private final AtomicBoolean done;
+ private final AtomicInteger count;
+ private Exception e;
+
+ GetTillDoneOrException(final int i, final byte[] r, final AtomicBoolean d,
+ final AtomicInteger c) {
+ super("getter." + i);
+ this.g = new Get(r);
+ this.done = d;
+ this.count = c;
+ }
+
+ @Override
+ public void run() {
+ while (!this.done.get()) {
+ try {
+ assertTrue(region.get(g, null).size() > 0);
+ this.count.incrementAndGet();
+ } catch (Exception e) {
+ this.e = e;
+ break;
+ }
+ }
+ }
+ }
/*
* An involved filter test. Has multiple column families and deletes in mix.
@@ -1011,13 +1099,13 @@ public class TestHRegion extends HBaseTe
scan.addFamily(fam4);
is = (RegionScanner) region.getScanner(scan);
is.initHeap(); // i dont like this test
- assertEquals(1, ((RegionScanner)is).getStoreHeap().getHeap().size());
+ assertEquals(1, ((RegionScanner)is).storeHeap.getHeap().size());
scan = new Scan();
is = (RegionScanner) region.getScanner(scan);
is.initHeap();
assertEquals(families.length -1,
- ((RegionScanner)is).getStoreHeap().getHeap().size());
+ ((RegionScanner)is).storeHeap.getHeap().size());
}
public void testRegionScanner_Next() throws IOException {