From ffe70158ccf99947a86ddbc0bf18e387581ebd63 Mon Sep 17 00:00:00 2001 From: tedyu Date: Thu, 15 Dec 2016 08:45:05 -0800 Subject: [PATCH] HBASE-17318 Increment does not add new column if the increment amount is zero at first time writing (Guangxu Cheng) --- .../hadoop/hbase/regionserver/HRegion.java | 5 ++- .../client/TestIncrementsFromClientSide.java | 44 +++++++++++++++++++ .../regionserver/wal/TestDurability.java | 22 +++++++--- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index b197a25ba0e..7337c171a74 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -7977,6 +7977,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi Cell currentValue = null; long ts = now; + boolean firstWrite = false; if (idx < currentValues.size() && CellUtil.matchingQualifier(currentValues.get(idx), inc)) { currentValue = currentValues.get(idx); ts = Math.max(now, currentValue.getTimestamp() + 1); @@ -7985,6 +7986,8 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi tags = Tag.carryForwardTags(tags, currentValue); if (i < (sortedIncrements.size() - 1) && !CellUtil.matchingQualifier(inc, sortedIncrements.get(i + 1))) idx++; + } else { + firstWrite = true; } // Append new incremented KeyValue to list @@ -8011,7 +8014,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi RegionObserver.MutationType.INCREMENT, increment, currentValue, newValue); } allKVs.add(newValue); - if (writeBack) { + if (writeBack || firstWrite) { results.add(newValue); } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java index 780fb19fd49..cd59c44c79e 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java @@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.client; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.io.IOException; @@ -328,6 +329,49 @@ public class TestIncrementsFromClientSide { ht.close(); } + @Test + public void testIncrementIncrZeroAtFirst() throws Exception { + LOG.info("Starting " + this.name.getMethodName()); + final TableName TABLENAME = + TableName.valueOf(filterStringSoTableNameSafe(this.name.getMethodName())); + Table ht = TEST_UTIL.createTable(TABLENAME, FAMILY); + + byte[] col1 = Bytes.toBytes("col1"); + byte[] col2 = Bytes.toBytes("col2"); + byte[] col3 = Bytes.toBytes("col3"); + + // Now increment zero at first time incr + Increment inc = new Increment(ROW); + inc.addColumn(FAMILY, col1, 0); + ht.increment(inc); + + // Verify expected results + Get get = new Get(ROW); + Result r = ht.get(get); + Cell [] kvs = r.rawCells(); + assertEquals(1, kvs.length); + assertNotNull(kvs[0]); + assertIncrementKey(kvs[0], ROW, FAMILY, col1, 0); + + // Now try multiple columns by different amounts + inc = new Increment(ROW); + inc.addColumn(FAMILY, col1, 1); + inc.addColumn(FAMILY, col2, 0); + inc.addColumn(FAMILY, col3, 2); + ht.increment(inc); + // Verify + get = new Get(ROW); + r = ht.get(get); + kvs = r.rawCells(); + assertEquals(3, kvs.length); + assertNotNull(kvs[0]); + assertNotNull(kvs[1]); + assertNotNull(kvs[2]); + assertIncrementKey(kvs[0], ROW, FAMILY, col1, 1); + assertIncrementKey(kvs[1], ROW, FAMILY, col2, 0); + assertIncrementKey(kvs[2], ROW, FAMILY, col3, 2); + } + @Test public void testIncrement() throws Exception { LOG.info("Starting " + this.name.getMethodName()); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestDurability.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestDurability.java index 4e9c5ff8b97..ba159cea1a0 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestDurability.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestDurability.java @@ -150,24 +150,32 @@ public class TestDurability { final WAL wal = wals.getWAL(tableName, null); HRegion region = createHRegion(tableName, "increment", wal, Durability.USE_DEFAULT); - // col1: amount = 1, 1 write back to WAL + // col1: amount = 0, 1 write back to WAL Increment inc1 = new Increment(row1); - inc1.addColumn(FAMILY, col1, 1); + inc1.addColumn(FAMILY, col1, 0); Result res = region.increment(inc1); assertEquals(1, res.size()); - assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); + assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col1))); verifyWALCount(wals, wal, 1); + // col1: amount = 1, 1 write back to WAL + inc1 = new Increment(row1); + inc1.addColumn(FAMILY, col1, 1); + res = region.increment(inc1); + assertEquals(1, res.size()); + assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); + verifyWALCount(wals, wal, 2); + // col1: amount = 0, 0 write back to WAL inc1 = new Increment(row1); inc1.addColumn(FAMILY, col1, 0); res = region.increment(inc1); assertEquals(1, res.size()); assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); - verifyWALCount(wals, wal, 1); + verifyWALCount(wals, wal, 2); // col1: amount = 0, col2: amount = 0, col3: amount = 0 - // 0 write back to WAL + // 1 write back to WAL inc1 = new Increment(row1); inc1.addColumn(FAMILY, col1, 0); inc1.addColumn(FAMILY, col2, 0); @@ -177,7 +185,7 @@ public class TestDurability { assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col2))); assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col3))); - verifyWALCount(wals, wal, 1); + verifyWALCount(wals, wal, 3); // col1: amount = 5, col2: amount = 4, col3: amount = 3 // 1 write back to WAL @@ -190,7 +198,7 @@ public class TestDurability { assertEquals(6, Bytes.toLong(res.getValue(FAMILY, col1))); assertEquals(4, Bytes.toLong(res.getValue(FAMILY, col2))); assertEquals(3, Bytes.toLong(res.getValue(FAMILY, col3))); - verifyWALCount(wals, wal, 2); + verifyWALCount(wals, wal, 4); } /*