You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by te...@apache.org on 2017/01/18 15:50:32 UTC

hbase git commit: HBASE-17482 mvcc mechanism fails when using mvccPreAssign (Allan Yang)

Repository: hbase
Updated Branches:
  refs/heads/master 406f66a4e -> 6cbc375aa


HBASE-17482 mvcc mechanism fails when using mvccPreAssign (Allan Yang)


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/6cbc375a
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/6cbc375a
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/6cbc375a

Branch: refs/heads/master
Commit: 6cbc375aa493b159600996b86d3872e9db16f6c6
Parents: 406f66a
Author: tedyu <yu...@gmail.com>
Authored: Wed Jan 18 07:50:41 2017 -0800
Committer: tedyu <yu...@gmail.com>
Committed: Wed Jan 18 07:50:41 2017 -0800

----------------------------------------------------------------------
 .../hadoop/hbase/regionserver/HRegion.java      |  2 +-
 .../hbase/client/TestFromClientSide3.java       | 57 ++++++++++++++++++++
 2 files changed, 58 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/6cbc375a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
----------------------------------------------------------------------
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 b574c50..0b93cb1 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
@@ -3389,7 +3389,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
         // 1) If the op is in replay mode, FSWALEntry#stampRegionSequenceId won't stamp sequence id.
         // 2) If no WAL, FSWALEntry won't be used
         // we use durability of the original mutation for the mutation passed by CP.
-        boolean updateSeqId = replay || batchOp.getMutation(i).getDurability() == Durability.SKIP_WAL;
+        boolean updateSeqId = replay || batchOp.getMutation(i).getDurability() == Durability.SKIP_WAL || mvccPreAssign;
         if (updateSeqId) {
           this.updateSequenceId(familyMaps[i].values(),
             replay? batchOp.getReplaySequenceId(): writeEntry.getWriteNumber());

http://git-wip-us.apache.org/repos/asf/hbase/blob/6cbc375a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java
index 9fc20ec..b863b40 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java
@@ -692,6 +692,63 @@ public class TestFromClientSide3 {
     }
   }
 
+  /**
+   * A test case for issue HBASE-17482
+   * After combile seqid with mvcc readpoint, seqid/mvcc is acquired and stamped
+   * onto cells in the append thread, a countdown latch is used to ensure that happened
+   * before cells can be put into memstore. But the MVCCPreAssign patch(HBASE-16698)
+   * make the seqid/mvcc acquirement in handler thread and stamping in append thread
+   * No countdown latch to assure cells in memstore are stamped with seqid/mvcc.
+   * If cells without mvcc(A.K.A mvcc=0) are put into memstore, then a scanner
+   * with a smaller readpoint can see these data, which disobey the multi version
+   * concurrency control rules.
+   * This test case is to reproduce this scenario.
+   * @throws IOException
+   */
+  @Test
+  public void testMVCCUsingMVCCPreAssign() throws IOException {
+    TableName tableName = TableName.valueOf("testMVCCUsingMVCCPreAssign");
+    HTableDescriptor htd = new HTableDescriptor(tableName);
+    HColumnDescriptor fam = new HColumnDescriptor(FAMILY);
+    htd.addFamily(fam);
+    Admin admin = TEST_UTIL.getHBaseAdmin();
+    admin.createTable(htd);
+    Table table = admin.getConnection().getTable(TableName.valueOf("testMVCCUsingMVCCPreAssign"));
+    //put two row first to init the scanner
+    Put put = new Put(Bytes.toBytes("0"));
+    put.addColumn(FAMILY, Bytes.toBytes( ""), Bytes.toBytes("0"));
+    table.put(put);
+    put = new Put(Bytes.toBytes("00"));
+    put.addColumn(FAMILY, Bytes.toBytes( ""), Bytes.toBytes("0"));
+    table.put(put);
+    Scan scan = new Scan();
+    scan.setTimeRange(0, Long.MAX_VALUE);
+    scan.setCaching(1);
+    ResultScanner scanner = table.getScanner(scan);
+    //the started scanner shouldn't see the rows put below
+    for(int i = 1; i < 1000; i++) {
+      put = new Put(Bytes.toBytes(String.valueOf(i)));
+      put.setDurability(Durability.ASYNC_WAL);
+      put.addColumn(FAMILY, Bytes.toBytes( ""), Bytes.toBytes(i));
+      table.put(put);
+    }
+    int rowNum = 0;
+    for(Result result : scanner) {
+      rowNum++;
+    }
+    //scanner should only see two rows
+    assertEquals(2, rowNum);
+    scanner = table.getScanner(scan);
+    rowNum = 0;
+    for(Result result : scanner) {
+      rowNum++;
+    }
+    // the new scanner should see all rows
+    assertEquals(1001, rowNum);
+
+
+  }
+
   private static void assertNoLocks(final TableName tableName) throws IOException, InterruptedException {
     HRegion region = (HRegion) find(tableName);
     assertEquals(0, region.getLockedRows().size());