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:
parent
e9f910d607
commit
3dca408c49
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue