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 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() {
synchronized(this.writestate) {
return this.writestate.writesEnabled;

View File

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

View File

@ -19,6 +19,8 @@
*/
package org.apache.hadoop.hbase.regionserver;
import com.google.common.collect.ImmutableList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@ -137,6 +139,28 @@ public class TestSplitTransaction {
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.
*/