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:
parent
fe2f84dbb1
commit
3e23493543
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue