HBASE-15050 Block Ref counting does not work in Region Split cases (Ram)

This commit is contained in:
ramkrishna 2015-12-30 14:39:03 +05:30
parent 413d663f92
commit 07b6236706
3 changed files with 68 additions and 1 deletions

View File

@ -314,6 +314,10 @@ public class HalfStoreFileReader extends StoreFile.Reader {
} }
} catch (IOException e) { } catch (IOException e) {
LOG.warn("Failed seekBefore " + Bytes.toStringBinary(this.splitkey), e); LOG.warn("Failed seekBefore " + Bytes.toStringBinary(this.splitkey), e);
} finally {
if (scanner != null) {
scanner.close();
}
} }
return null; return null;
} }
@ -335,6 +339,10 @@ public class HalfStoreFileReader extends StoreFile.Reader {
firstKeySeeked = true; firstKeySeeked = true;
} catch (IOException e) { } catch (IOException e) {
LOG.warn("Failed seekTo first KV in the file", e); LOG.warn("Failed seekTo first KV in the file", e);
} finally {
if(scanner != null) {
scanner.close();
}
} }
} }
return this.firstKey; return this.firstKey;

View File

@ -986,7 +986,13 @@ public class HFileReaderImpl implements HFile.Reader, Configurable {
return new KeyValue.KeyOnlyKeyValue(keyBuf.array(), keyBuf.arrayOffset() return new KeyValue.KeyOnlyKeyValue(keyBuf.array(), keyBuf.arrayOffset()
+ keyPair.getSecond(), currKeyLen); + keyPair.getSecond(), currKeyLen);
} else { } else {
return new ByteBufferedKeyOnlyKeyValue(keyBuf, keyPair.getSecond(), currKeyLen); // Better to do a copy here instead of holding on to this BB so that
// we could release the blocks referring to this key. This key is specifically used
// in HalfStoreFileReader to get the firstkey and lastkey by creating a new scanner
// every time. So holding onto the BB (incase of DBB) is not advised here.
byte[] key = new byte[currKeyLen];
ByteBufferUtils.copyFromBufferToArray(key, keyBuf, keyPair.getSecond(), 0, currKeyLen);
return new KeyValue.KeyOnlyKeyValue(key, 0, currKeyLen);
} }
} }

View File

@ -74,6 +74,8 @@ public class TestBlockEvictionFromClient {
private static int NO_OF_THREADS = 3; private static int NO_OF_THREADS = 3;
private static byte[] ROW = Bytes.toBytes("testRow"); private static byte[] ROW = Bytes.toBytes("testRow");
private static byte[] ROW1 = Bytes.toBytes("testRow1"); private static byte[] ROW1 = Bytes.toBytes("testRow1");
private static byte[] ROW2 = Bytes.toBytes("testRow2");
private static byte[] ROW3 = Bytes.toBytes("testRow3");
private static byte[] FAMILY = Bytes.toBytes("testFamily"); private static byte[] FAMILY = Bytes.toBytes("testFamily");
private static byte[][] FAMILIES_1 = new byte[1][0]; private static byte[][] FAMILIES_1 = new byte[1][0];
private static byte[] QUALIFIER = Bytes.toBytes("testQualifier"); private static byte[] QUALIFIER = Bytes.toBytes("testQualifier");
@ -553,6 +555,57 @@ public class TestBlockEvictionFromClient {
} }
} }
@Test
public void testBlockRefCountAfterSplits() throws IOException, InterruptedException {
HTable table = null;
try {
TableName tableName = TableName.valueOf("testBlockRefCountAfterSplits");
table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024);
// get the block cache and region
RegionLocator locator = table.getRegionLocator();
String regionName = locator.getAllRegionLocations().get(0).getRegionInfo().getEncodedName();
Region region =
TEST_UTIL.getRSForFirstRegionInTable(tableName).getFromOnlineRegions(regionName);
Store store = region.getStores().iterator().next();
CacheConfig cacheConf = store.getCacheConfig();
cacheConf.setEvictOnClose(true);
BlockCache cache = cacheConf.getBlockCache();
Put put = new Put(ROW);
put.addColumn(FAMILY, QUALIFIER, data);
table.put(put);
region.flush(true);
put = new Put(ROW1);
put.addColumn(FAMILY, QUALIFIER, data);
table.put(put);
region.flush(true);
byte[] QUALIFIER2 = Bytes.add(QUALIFIER, QUALIFIER);
put = new Put(ROW2);
put.addColumn(FAMILY, QUALIFIER2, data2);
table.put(put);
put = new Put(ROW3);
put.addColumn(FAMILY, QUALIFIER2, data2);
table.put(put);
region.flush(true);
TEST_UTIL.getAdmin().split(tableName, ROW1);
List<HRegionInfo> tableRegions = TEST_UTIL.getAdmin().getTableRegions(tableName);
// Wait for splits
while (tableRegions.size() != 2) {
tableRegions = TEST_UTIL.getAdmin().getTableRegions(tableName);
Thread.sleep(100);
}
region.compact(true);
Iterator<CachedBlock> iterator = cache.iterator();
// Though the split had created the HalfStorefileReader - the firstkey and lastkey scanners
// should be closed inorder to return those blocks
iterateBlockCache(cache, iterator);
} finally {
if (table != null) {
table.close();
}
}
}
@Test @Test
public void testMultiGets() throws IOException, InterruptedException { public void testMultiGets() throws IOException, InterruptedException {
HTable table = null; HTable table = null;