HBASE-3235 Intermittent incrementColumnValue failure in TestHRegion

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1035818 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Ryan Rawson 2010-11-16 21:20:31 +00:00
parent e9f910d607
commit 3dca408c49
3 changed files with 65 additions and 4 deletions

View File

@ -679,7 +679,9 @@ Release 0.90.0 - Unreleased
HBASE-3221 Race between splitting and disabling
HBASE-3224 NPE in KeyValue$KVComparator.compare when compacting
HBASE-3233 Fix Long Running Stats
HBASE-3232 : Fix KeyOnlyFilter + Add Value Length (Nicolas via Ryan)
HBASE-3232 Fix KeyOnlyFilter + Add Value Length (Nicolas via Ryan)
HBASE-3235 Intermittent incrementColumnValue failure in TestHRegion
(Gary via Ryan)
IMPROVEMENTS

View File

@ -466,9 +466,13 @@ public class MemStore implements HeapSize {
// Add the KeyValue to the MemStore
long addedSize = add(kv);
// Iterate the KeyValues after the one just inserted, cleaning up any
// other KeyValues with the same row/family/qualifier
SortedSet<KeyValue> ss = kvset.tailSet(kv);
// Get the KeyValues for the row/family/qualifier regardless of timestamp.
// For this case we want to clean up any other puts
KeyValue firstKv = KeyValue.createFirstOnRow(
kv.getBuffer(), kv.getRowOffset(), kv.getRowLength(),
kv.getBuffer(), kv.getFamilyOffset(), kv.getFamilyLength(),
kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength());
SortedSet<KeyValue> ss = kvset.tailSet(firstKv);
Iterator<KeyValue> it = ss.iterator();
while ( it.hasNext() ) {
KeyValue cur = it.next();

View File

@ -61,6 +61,8 @@ import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.regionserver.HRegion.RegionScanner;
import org.apache.hadoop.hbase.regionserver.wal.HLog;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.EnvironmentEdge;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;
import org.apache.hadoop.hbase.util.IncrementingEnvironmentEdge;
import org.apache.hadoop.hbase.util.ManualEnvironmentEdge;
@ -2066,6 +2068,59 @@ public class TestHRegion extends HBaseTestCase {
assertICV(row, fam1, qual3, amount);
}
/**
* Added for HBASE-3235.
*
* When the initial put and an ICV update were arriving with the same timestamp,
* the initial Put KV was being skipped during {@link MemStore#upsert(KeyValue)}
* causing the iteration for matching KVs, causing the update-in-place to not
* happen and the ICV put to effectively disappear.
* @throws IOException
*/
public void testIncrementColumnValue_UpdatingInPlace_TimestampClobber() throws IOException {
initHRegion(tableName, getName(), fam1);
long value = 1L;
long amount = 3L;
long now = EnvironmentEdgeManager.currentTimeMillis();
ManualEnvironmentEdge mock = new ManualEnvironmentEdge();
mock.setValue(now);
EnvironmentEdgeManagerTestHelper.injectEdge(mock);
// verify we catch an ICV on a put with the same timestamp
Put put = new Put(row);
put.add(fam1, qual1, now, Bytes.toBytes(value));
region.put(put);
long result = region.incrementColumnValue(row, fam1, qual1, amount, true);
assertEquals(value+amount, result);
Store store = region.getStore(fam1);
// ICV should update the existing Put with the same timestamp
assertEquals(1, store.memstore.kvset.size());
assertTrue(store.memstore.snapshot.isEmpty());
assertICV(row, fam1, qual1, value+amount);
// verify we catch an ICV even when the put ts > now
put = new Put(row);
put.add(fam1, qual2, now+1, Bytes.toBytes(value));
region.put(put);
result = region.incrementColumnValue(row, fam1, qual2, amount, true);
assertEquals(value+amount, result);
store = region.getStore(fam1);
// ICV should update the existing Put with the same timestamp
assertEquals(2, store.memstore.kvset.size());
assertTrue(store.memstore.snapshot.isEmpty());
assertICV(row, fam1, qual2, value+amount);
EnvironmentEdgeManagerTestHelper.reset();
}
private void assertICV(byte [] row,
byte [] familiy,
byte[] qualifier,