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 E0B4D200C65 for ; Sat, 15 Apr 2017 00:03:46 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id DF713160B8C; Fri, 14 Apr 2017 22:03:46 +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 0D47A160BA3 for ; Sat, 15 Apr 2017 00:03:45 +0200 (CEST) Received: (qmail 60443 invoked by uid 500); 14 Apr 2017 22:03:45 -0000 Mailing-List: contact dev-help@phoenix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@phoenix.apache.org Delivered-To: mailing list dev@phoenix.apache.org Received: (qmail 60424 invoked by uid 99); 14 Apr 2017 22:03:45 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 14 Apr 2017 22:03:45 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id C623F1B024F for ; Fri, 14 Apr 2017 22:03:44 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -99.202 X-Spam-Level: X-Spam-Status: No, score=-99.202 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001, USER_IN_WHITELIST=-100] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id Z4Bf-q1Xo6gG for ; Fri, 14 Apr 2017 22:03:43 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with ESMTP id 8618C5FCD6 for ; Fri, 14 Apr 2017 22:03:42 +0000 (UTC) Received: from jira-lw-us.apache.org (unknown [207.244.88.139]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id D86C7E0BFB for ; Fri, 14 Apr 2017 22:03:41 +0000 (UTC) Received: from jira-lw-us.apache.org (localhost [127.0.0.1]) by jira-lw-us.apache.org (ASF Mail Server at jira-lw-us.apache.org) with ESMTP id 8F5D221B47 for ; Fri, 14 Apr 2017 22:03:41 +0000 (UTC) Date: Fri, 14 Apr 2017 22:03:41 +0000 (UTC) From: "James Taylor (JIRA)" To: dev@phoenix.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Commented] (PHOENIX-3789) Execute cross region index maintenance calls outside of row lock MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 archived-at: Fri, 14 Apr 2017 22:03:47 -0000 [ https://issues.apache.org/jira/browse/PHOENIX-3789?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15969593#comment-15969593 ] James Taylor commented on PHOENIX-3789: --------------------------------------- bq. If the mutation's durability is SKIP_WAL then Indexer will try to update indexes out of the PRE hook (preBatchMutate). Good news is we're only under the region read lock here, not rowlocks. I'm looking at HRegion.doMiniBatchMutation() and it seems to me that row locks are in place during preBatchMutate (see getRowLockInternal here): {code} // If we haven't got any rows in our batch, we should block to // get the next one. boolean shouldBlock = numReadyToWrite == 0; RowLock rowLock = null; try { rowLock = getRowLockInternal(mutation.getRow(), shouldBlock); } catch (IOException ioe) { LOG.warn("Failed getting lock in batch put, row=" + Bytes.toStringBinary(mutation.getRow()), ioe); } if (rowLock == null) { // We failed to grab another lock break; // stop acquiring more rows for this batch } else { acquiredRowLocks.add(rowLock); } lastIndexExclusive++; numReadyToWrite++; if (isPutMutation) { // If Column Families stay consistent through out all of the // individual puts then metrics can be reported as a mutliput across // column families in the first put. if (putsCfSet == null) { putsCfSet = mutation.getFamilyCellMap().keySet(); } else { putsCfSetConsistent = putsCfSetConsistent && mutation.getFamilyCellMap().keySet().equals(putsCfSet); } } else { if (deletesCfSet == null) { deletesCfSet = mutation.getFamilyCellMap().keySet(); } else { deletesCfSetConsistent = deletesCfSetConsistent && mutation.getFamilyCellMap().keySet().equals(deletesCfSet); } } } // we should record the timestamp only after we have acquired the rowLock, // otherwise, newer puts/deletes are not guaranteed to have a newer timestamp now = EnvironmentEdgeManager.currentTimeMillis(); byte[] byteNow = Bytes.toBytes(now); // Nothing to put/delete -- an exception in the above such as NoSuchColumnFamily? if (numReadyToWrite <= 0) return 0L; // We've now grabbed as many mutations off the list as we can // ------------------------------------ // STEP 2. Update any LATEST_TIMESTAMP timestamps // ---------------------------------- for (int i = firstIndex; i < lastIndexExclusive; i++) { // skip invalid if (batchOp.retCodeDetails[i].getOperationStatusCode() != OperationStatusCode.NOT_RUN) continue; Mutation mutation = batchOp.getMutation(i); if (mutation instanceof Put) { updateKVTimestamps(familyMaps[i].values(), byteNow); noOfPuts++; } else { if (!isInReplay) { prepareDeleteTimestamps(mutation, familyMaps[i], byteNow); } noOfDeletes++; } rewriteCellTags(familyMaps[i], mutation); } lock(this.updatesLock.readLock(), numReadyToWrite); locked = true; // // ------------------------------------ // Acquire the latest mvcc number // ---------------------------------- w = mvcc.beginMemstoreInsert(); // calling the pre CP hook for batch mutation if (!isInReplay && coprocessorHost != null) { MiniBatchOperationInProgress miniBatchOp = new MiniBatchOperationInProgress(batchOp.getMutationsForCoprocs(), batchOp.retCodeDetails, batchOp.walEditsFromCoprocessors, firstIndex, lastIndexExclusive); if (coprocessorHost.preBatchMutate(miniBatchOp)) return 0L; } {code} but are *not* in place during postBatchMutate (see releaseRowLocks right before STEP 7): {code} // ------------------------------- // STEP 6. Release row locks, etc. // ------------------------------- if (locked) { this.updatesLock.readLock().unlock(); locked = false; } releaseRowLocks(acquiredRowLocks); // ------------------------- // STEP 7. Sync wal. // ------------------------- if (hasWalAppends) { syncOrDefer(txid, durability); } doRollBackMemstore = false; // calling the post CP hook for batch mutation if (!isInReplay && coprocessorHost != null) { MiniBatchOperationInProgress miniBatchOp = new MiniBatchOperationInProgress(batchOp.getMutationsForCoprocs(), batchOp.retCodeDetails, batchOp.walEditsFromCoprocessors, firstIndex, lastIndexExclusive); coprocessorHost.postBatchMutate(miniBatchOp); } {code} If that's the case, there's no need for this patch. Am I missing something, [~apurtell] & [~gjacoby]? > Execute cross region index maintenance calls outside of row lock > ---------------------------------------------------------------- > > Key: PHOENIX-3789 > URL: https://issues.apache.org/jira/browse/PHOENIX-3789 > Project: Phoenix > Issue Type: Bug > Reporter: James Taylor > Assignee: James Taylor > Fix For: 4.11.0, 4.10.1 > > Attachments: PHOENIX-3789.patch, PHOENIX-3789_v2.patch > > > Making cross region server calls while the row is locked can lead to a greater chance of resource starvation. We can use the postBatchMutateIndispensably hook instead of the postBatchMutate call for our processing. -- This message was sent by Atlassian JIRA (v6.3.15#6346)