HBASE-5665 Repeated split causes HRegionServer failures and breaks table

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1308545 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2012-04-02 20:48:22 +00:00
parent fe2f84dbb1
commit 3e23493543
4 changed files with 37 additions and 4 deletions

View File

@ -846,6 +846,16 @@ public class HRegion implements HeapSize { // , Writable{
return this.closing.get(); return this.closing.get();
} }
/** @return true if region is available (not closed and not closing) */
public boolean isAvailable() {
return !isClosed() && !isClosing();
}
/** @return true if region is splittable */
public boolean isSplittable() {
return isAvailable() && !hasReferences();
}
boolean areWritesEnabled() { boolean areWritesEnabled() {
synchronized(this.writestate) { synchronized(this.writestate) {
return this.writestate.writesEnabled; return this.writestate.writesEnabled;

View File

@ -1914,8 +1914,7 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
try { try {
for (Map.Entry<String, HRegion> e: this.onlineRegions.entrySet()) { for (Map.Entry<String, HRegion> e: this.onlineRegions.entrySet()) {
HRegion r = e.getValue(); HRegion r = e.getValue();
if (!r.getRegionInfo().isMetaRegion()) { if (!r.getRegionInfo().isMetaRegion() && r.isAvailable()) {
if (r.isClosed() || r.isClosing()) continue;
// Don't update zk with this close transition; pass false. // Don't update zk with this close transition; pass false.
closeRegion(r.getRegionInfo(), abort, false); closeRegion(r.getRegionInfo(), abort, false);
} }
@ -3135,7 +3134,7 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
protected HRegionInfo[] getMostLoadedRegions() { protected HRegionInfo[] getMostLoadedRegions() {
ArrayList<HRegionInfo> regions = new ArrayList<HRegionInfo>(); ArrayList<HRegionInfo> regions = new ArrayList<HRegionInfo>();
for (HRegion r : onlineRegions.values()) { for (HRegion r : onlineRegions.values()) {
if (r.isClosed() || r.isClosing()) { if (!r.isAvailable()) {
continue; continue;
} }
if (regions.size() < numRegionsToReport) { if (regions.size() < numRegionsToReport) {

View File

@ -163,7 +163,7 @@ public class SplitTransaction {
* <code>false</code> if it is not (e.g. its already closed, etc.). * <code>false</code> if it is not (e.g. its already closed, etc.).
*/ */
public boolean prepare() { public boolean prepare() {
if (this.parent.isClosed() || this.parent.isClosing()) return false; if (!this.parent.isSplittable()) return false;
// Split key can be null if this region is unsplittable; i.e. has refs. // Split key can be null if this region is unsplittable; i.e. has refs.
if (this.splitrow == null) return false; if (this.splitrow == null) return false;
HRegionInfo hri = this.parent.getRegionInfo(); HRegionInfo hri = this.parent.getRegionInfo();

View File

@ -19,6 +19,8 @@
*/ */
package org.apache.hadoop.hbase.regionserver; package org.apache.hadoop.hbase.regionserver;
import com.google.common.collect.ImmutableList;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@ -137,6 +139,28 @@ public class TestSplitTransaction {
return st; return st;
} }
/**
* Pass a reference store
*/
@Test public void testPrepareWithRegionsWithReference() throws IOException {
// create a mock that will act as a reference StoreFile
StoreFile storeFileMock = Mockito.mock(StoreFile.class);
when(storeFileMock.isReference()).thenReturn(true);
// add the mock to the parent stores
Store storeMock = Mockito.mock(Store.class);
List<StoreFile> storeFileList = new ArrayList<StoreFile>(1);
storeFileList.add(storeFileMock);
when(storeMock.getStorefiles()).thenReturn(storeFileList);
when(storeMock.close()).thenReturn(ImmutableList.copyOf(storeFileList));
this.parent.stores.put(Bytes.toBytes(""), storeMock);
SplitTransaction st = new SplitTransaction(this.parent, GOOD_SPLIT_ROW);
assertFalse("a region should not be splittable if it has instances of store file references",
st.prepare());
}
/** /**
* Pass an unreasonable split row. * Pass an unreasonable split row.
*/ */