Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id E4A272009F4 for ; Thu, 26 May 2016 20:36:41 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id E3485160A18; Thu, 26 May 2016 18:36:41 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 1212C160A17 for ; Thu, 26 May 2016 20:36:40 +0200 (CEST) Received: (qmail 85817 invoked by uid 500); 26 May 2016 18:36:40 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 85807 invoked by uid 99); 26 May 2016 18:36:40 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 26 May 2016 18:36:40 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id E39B7DFC6F; Thu, 26 May 2016 18:36:39 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: enis@apache.org To: commits@hbase.apache.org Message-Id: <7b2f6e6b711e4a228d9d8b5cb884827b@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: hbase git commit: HBASE-15837 Memstore size accounting is wrong if postBatchMutate() throws exception Date: Thu, 26 May 2016 18:36:39 +0000 (UTC) archived-at: Thu, 26 May 2016 18:36:42 -0000 Repository: hbase Updated Branches: refs/heads/branch-1.2 254579893 -> bd6903b9e HBASE-15837 Memstore size accounting is wrong if postBatchMutate() throws exception Conflicts: hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/bd6903b9 Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/bd6903b9 Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/bd6903b9 Branch: refs/heads/branch-1.2 Commit: bd6903b9e7bd7707a0c03f30f089b1d31f700411 Parents: 2545798 Author: Enis Soztutar Authored: Wed May 25 17:04:50 2016 -0700 Committer: Enis Soztutar Committed: Thu May 26 11:34:14 2016 -0700 ---------------------------------------------------------------------- .../hadoop/hbase/regionserver/HRegion.java | 23 +++++++++--- .../hadoop/hbase/regionserver/TestHRegion.java | 39 ++++++++++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/bd6903b9/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 041c838..c4b4f5a 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 @@ -1090,7 +1090,15 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi if (this.rsAccounting != null) { rsAccounting.addAndGetGlobalMemstoreSize(memStoreSize); } - return this.memstoreSize.addAndGet(memStoreSize); + long size = this.memstoreSize.addAndGet(memStoreSize); + // This is extremely bad if we make memstoreSize negative. Log as much info on the offending + // caller as possible. (memStoreSize might be a negative value already -- freeing memory) + if (size < 0) { + LOG.error("Asked to modify this region's (" + this.toString() + + ") memstoreSize to a negative value which is incorrect. Current memstoreSize=" + + (size-memStoreSize) + ", delta=" + memStoreSize, new Exception()); + } + return size; } @Override @@ -2868,8 +2876,8 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi } initialized = true; } - long addedSize = doMiniBatchMutation(batchOp); - long newSize = this.addAndGetGlobalMemstoreSize(addedSize); + doMiniBatchMutation(batchOp); + long newSize = this.getMemstoreSize(); if (isFlushSize(newSize)) { requestFlush(); } @@ -2950,6 +2958,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi int noOfPuts = 0, noOfDeletes = 0; WALKey walKey = null; long mvccNum = 0; + long addedSize = 0; try { // ------------------------------------ // STEP 1. Try to acquire as many locks as we can, and ensure @@ -3182,7 +3191,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi // visible to scanners till we update the MVCC. The MVCC is // moved only when the sync is complete. // ---------------------------------- - long addedSize = 0; for (int i = firstIndex; i < lastIndexExclusive; i++) { if (batchOp.retCodeDetails[i].getOperationStatusCode() != OperationStatusCode.NOT_RUN) { @@ -3265,8 +3273,11 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi } } if (writeEntry != null) mvcc.complete(writeEntry); - } else if (writeEntry != null) { - mvcc.completeAndWait(writeEntry); + } else { + this.addAndGetGlobalMemstoreSize(addedSize); + if (writeEntry != null) { + mvcc.completeAndWait(writeEntry); + } } if (locked) { http://git-wip-us.apache.org/repos/asf/hbase/blob/bd6903b9/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java index 4d31374..558b4b3 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java @@ -36,6 +36,7 @@ import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -399,6 +400,44 @@ public class TestHRegion { HRegion.closeHRegion(region); } + @Test + public void testMemstoreSizeAccountingWithFailedPostBatchMutate() throws IOException { + String testName = "testMemstoreSizeAccountingWithFailedPostBatchMutate"; + FileSystem fs = FileSystem.get(CONF); + Path rootDir = new Path(dir + testName); + FSHLog hLog = new FSHLog(fs, rootDir, testName, CONF); + HRegion region = initHRegion(tableName, null, null, name.getMethodName(), + CONF, false, Durability.SYNC_WAL, hLog, COLUMN_FAMILY_BYTES); + Store store = region.getStore(COLUMN_FAMILY_BYTES); + assertEquals(0, region.getMemstoreSize()); + + // Put one value + byte [] value = Bytes.toBytes(name.getMethodName()); + Put put = new Put(value); + put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("abc"), value); + region.put(put); + long onePutSize = region.getMemstoreSize(); + assertTrue(onePutSize > 0); + + RegionCoprocessorHost mockedCPHost = Mockito.mock(RegionCoprocessorHost.class); + doThrow(new IOException()) + .when(mockedCPHost).postBatchMutate(Mockito.>any()); + region.setCoprocessorHost(mockedCPHost); + + put = new Put(value); + put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("dfg"), value); + try { + region.put(put); + fail("Should have failed with IOException"); + } catch (IOException expected) { + } + assertEquals("memstoreSize should be incremented", onePutSize * 2, region.getMemstoreSize()); + assertEquals("flushable size should be incremented", onePutSize * 2, store.getFlushableSize()); + + region.setCoprocessorHost(null); + HBaseTestingUtility.closeRegionAndWAL(region); + } + /** * Test we do not lose data if we fail a flush and then close. * Part of HBase-10466. Tests the following from the issue description: