This is an automated email from the ASF dual-hosted git repository.

irakov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 71b1f54  IGNITE-12516 Dump active transaction from near node does not 
work if transaction not follow first - Fixes #7221.
71b1f54 is described below

commit 71b1f54557293faaea703cb38f2e6c8eeb57402d
Author: denis-chudov <regmoongl...@gmail.com>
AuthorDate: Wed Jan 29 19:43:38 2020 +0300

    IGNITE-12516 Dump active transaction from near node does not work if 
transaction not follow first - Fixes #7221.
    
    Signed-off-by: Ivan Rakov <ira...@apache.org>
---
 .../cache/FetchActiveTxOwnerTraceClosure.java      |  37 ++-----
 .../cache/GridCachePartitionExchangeManager.java   | 121 +++++++++++----------
 ...CacheLongRunningTransactionDiagnosticsTest.java |  35 +++---
 3 files changed, 90 insertions(+), 103 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/FetchActiveTxOwnerTraceClosure.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/FetchActiveTxOwnerTraceClosure.java
index 0c51c83..4020f84 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/FetchActiveTxOwnerTraceClosure.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/FetchActiveTxOwnerTraceClosure.java
@@ -16,12 +16,10 @@
  */
 package org.apache.ignite.internal.processors.cache;
 
+import org.apache.ignite.internal.util.GridStringBuilder;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteCallable;
 
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
-
 /**
  * Closure that is computed on near node to get the stack trace of active 
transaction owner thread.
  */
@@ -30,9 +28,6 @@ public class FetchActiveTxOwnerTraceClosure implements 
IgniteCallable<String> {
     private static final long serialVersionUID = 0L;
 
     /** */
-    private static final StackTraceElement[] STACK_TRACE_ELEMENT_EMPTY = new 
StackTraceElement[0];
-
-    /** */
     private final long txOwnerThreadId;
 
     /** */
@@ -47,33 +42,15 @@ public class FetchActiveTxOwnerTraceClosure implements 
IgniteCallable<String> {
      * @throws Exception If failed
      */
     @Override public String call() throws Exception {
-        StringBuilder traceDump = new StringBuilder("Stack trace of the 
transaction owner thread:\n");
-
-        for (StackTraceElement stackTraceElement : getStackTrace()) {
-            traceDump.append(stackTraceElement.toString());
-            traceDump.append("\n");
-        }
-
-        return traceDump.toString();
-    }
-
-    /**
-     * Gets the stack trace of the transaction owner thread
-     *
-     * @return stack trace elements
-     */
-    private StackTraceElement[] getStackTrace() {
-        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
-
-        ThreadInfo threadInfo;
+        GridStringBuilder traceDump = new GridStringBuilder("Stack trace of 
the transaction owner thread:\n");
 
         try {
-            threadInfo = threadMXBean.getThreadInfo(txOwnerThreadId, 
Integer.MAX_VALUE);
+            U.printStackTrace(txOwnerThreadId, traceDump);
         }
-        catch (SecurityException | IllegalArgumentException ignored) {
-            threadInfo = null;
+        catch (SecurityException | IllegalArgumentException e) {
+            traceDump = new GridStringBuilder("Could not get stack trace of 
the transaction owner thread: " + e.getMessage());
         }
 
-        return threadInfo == null ? STACK_TRACE_ELEMENT_EMPTY : 
threadInfo.getStackTrace();
+        return traceDump.toString();
     }
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
index 9d9917a..308e6a4 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
@@ -30,6 +30,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.NavigableMap;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.UUID;
@@ -2151,7 +2152,11 @@ public class GridCachePartitionExchangeManager<K, V> 
extends GridCacheSharedMana
                         if (warnings.canAddMessage()) {
                             warnings.add(longRunningTransactionWarning(tx, 
curTime));
 
-                            if (ltrDumpLimiter.allowAction(tx))
+                            if (cctx.tm().txOwnerDumpRequestsAllowed()
+                                && 
!Optional.ofNullable(cctx.kernalContext().config().isClientMode()).orElse(false)
+                                && tx.local()
+                                && tx.state() == TransactionState.ACTIVE
+                                && ltrDumpLimiter.allowAction(tx))
                                 dumpLongRunningTransaction(tx);
                         }
                         else
@@ -2232,77 +2237,75 @@ public class GridCachePartitionExchangeManager<K, V> 
extends GridCacheSharedMana
      * @param tx Transaction.
      */
     private void dumpLongRunningTransaction(IgniteInternalTx tx) {
-        if (cctx.tm().txOwnerDumpRequestsAllowed() && tx.local() && tx.state() 
== TransactionState.ACTIVE) {
-            Collection<UUID> masterNodeIds = tx.masterNodeIds();
+        Collection<UUID> masterNodeIds = tx.masterNodeIds();
 
-            if (masterNodeIds.size() == 1) {
-                UUID nearNodeId = masterNodeIds.iterator().next();
+        if (masterNodeIds.size() == 1) {
+            UUID nearNodeId = masterNodeIds.iterator().next();
 
-                long txOwnerThreadId = tx.threadId();
+            long txOwnerThreadId = tx.threadId();
 
-                Ignite ignite = cctx.kernalContext().grid();
+            Ignite ignite = cctx.kernalContext().grid();
 
-                ClusterGroup nearNode = ignite.cluster().forNodeId(nearNodeId);
+            ClusterGroup nearNode = ignite.cluster().forNodeId(nearNodeId);
 
-                String txRequestInfo = String.format(
-                    "[xidVer=%s, nodeId=%s]",
-                    tx.xidVersion().toString(),
-                    nearNodeId.toString()
-                );
+            String txRequestInfo = String.format(
+                "[xidVer=%s, nodeId=%s]",
+                tx.xidVersion().toString(),
+                nearNodeId.toString()
+            );
 
-                if (allNodesSupports(nearNode.nodes(), 
TRANSACTION_OWNER_THREAD_DUMP_PROVIDING)) {
-                    IgniteCompute compute = 
ignite.compute(ignite.cluster().forNodeId(nearNodeId));
+            if (allNodesSupports(nearNode.nodes(), 
TRANSACTION_OWNER_THREAD_DUMP_PROVIDING)) {
+                IgniteCompute compute = 
ignite.compute(ignite.cluster().forNodeId(nearNodeId));
 
-                    try {
-                        compute
-                            .callAsync(new 
FetchActiveTxOwnerTraceClosure(txOwnerThreadId))
-                            .listen(new 
IgniteInClosure<IgniteFuture<String>>() {
-                                @Override public void 
apply(IgniteFuture<String> strIgniteFut) {
-                                    String traceDump = null;
+                try {
+                    compute
+                        .callAsync(new 
FetchActiveTxOwnerTraceClosure(txOwnerThreadId))
+                        .listen(new IgniteInClosure<IgniteFuture<String>>() {
+                            @Override public void apply(IgniteFuture<String> 
strIgniteFut) {
+                                String traceDump = null;
 
-                                    try {
-                                        traceDump = strIgniteFut.get();
-                                    }
-                                    catch (ClusterGroupEmptyException e) {
-                                        U.error(
-                                            diagnosticLog,
-                                            "Could not get thread dump from 
transaction owner because near node " +
-                                                    "is now out of topology. " 
+ txRequestInfo
-                                        );
-                                    }
-                                    catch (Exception e) {
-                                        U.error(
-                                            diagnosticLog,
-                                            "Could not get thread dump from 
transaction owner near node " + txRequestInfo,
-                                            e
-                                        );
-                                    }
+                                try {
+                                    traceDump = strIgniteFut.get();
+                                }
+                                catch (ClusterGroupEmptyException e) {
+                                    U.error(
+                                        diagnosticLog,
+                                        "Could not get thread dump from 
transaction owner because near node " +
+                                                "is out of topology now. " + 
txRequestInfo
+                                    );
+                                }
+                                catch (Exception e) {
+                                    U.error(
+                                        diagnosticLog,
+                                        "Could not get thread dump from 
transaction owner near node " + txRequestInfo,
+                                        e
+                                    );
+                                }
 
-                                    if (traceDump != null) {
-                                        U.warn(
-                                            diagnosticLog,
-                                            String.format(
-                                                "Dumping the near node thread 
that started transaction %s\n%s",
-                                                txRequestInfo,
-                                                traceDump
-                                            )
-                                        );
-                                    }
+                                if (traceDump != null) {
+                                    U.warn(
+                                        diagnosticLog,
+                                        String.format(
+                                            "Dumping the near node thread that 
started transaction %s\n%s",
+                                            txRequestInfo,
+                                            traceDump
+                                        )
+                                    );
                                 }
-                            });
-                    }
-                    catch (Exception e) {
-                        U.error(diagnosticLog, "Could not send dump request to 
transaction owner near node " + txRequestInfo, e);
-                    }
+                            }
+                        });
                 }
-                else {
-                    U.warn(
-                        diagnosticLog,
-                        "Could not send dump request to transaction owner near 
node: node does not support this feature. " +
-                            txRequestInfo
-                    );
+                catch (Exception e) {
+                    U.error(diagnosticLog, "Could not send dump request to 
transaction owner near node " + txRequestInfo, e);
                 }
             }
+            else {
+                U.warn(
+                    diagnosticLog,
+                    "Could not send dump request to transaction owner near 
node: node does not support this feature. " +
+                        txRequestInfo
+                );
+            }
         }
     }
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheLongRunningTransactionDiagnosticsTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheLongRunningTransactionDiagnosticsTest.java
index 00ac8b5..196a6ad 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheLongRunningTransactionDiagnosticsTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheLongRunningTransactionDiagnosticsTest.java
@@ -16,10 +16,6 @@
  */
 package org.apache.ignite.internal.processors.cache;
 
-import java.lang.management.ManagementFactory;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.ObjectName;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.GridJobExecuteRequest;
@@ -27,8 +23,9 @@ import org.apache.ignite.internal.GridTopic;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.TestRecordingCommunicationSpi;
 import org.apache.ignite.internal.TransactionsMXBeanImpl;
-import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.mxbean.TransactionsMXBean;
+import org.apache.ignite.testframework.ListeningTestLogger;
+import org.apache.ignite.testframework.LogListener;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.transactions.Transaction;
 import org.junit.Test;
@@ -55,6 +52,9 @@ public class GridCacheLongRunningTransactionDiagnosticsTest 
extends GridCommonAb
     /** */
     private static String longOpTimeoutCommon;
 
+    /** */
+    private final LogListener dumpLsnr = LogListener.matches("Dumping the near 
node thread that started transaction").build();
+
     /** {@inheritDoc} */
     @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
         IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
@@ -77,6 +77,12 @@ public class GridCacheLongRunningTransactionDiagnosticsTest 
extends GridCommonAb
             cfg.setCacheConfiguration(ccfg);
         }
 
+        ListeningTestLogger testLog = new ListeningTestLogger(false, log);
+
+        testLog.registerListener(dumpLsnr);
+
+        cfg.setGridLogger(testLog);
+
         return cfg;
     }
 
@@ -154,6 +160,8 @@ public class GridCacheLongRunningTransactionDiagnosticsTest 
extends GridCommonAb
      * @throws Exception if failed.
      */
     private void imitateLongTransaction(boolean shouldRcvThreadDumpReq) throws 
Exception {
+        dumpLsnr.reset();
+
         final int val = 0;
 
         final IgniteEx client = startGrid("client");
@@ -181,20 +189,19 @@ public class 
GridCacheLongRunningTransactionDiagnosticsTest extends GridCommonAb
             shouldRcvThreadDumpReq,
             
FetchActiveTxOwnerTraceClosure.class.getName().equals(taskNameContainer.toString())
         );
+
+        assertEquals(shouldRcvThreadDumpReq, dumpLsnr.check());
     }
 
     /**
      *
      */
     private TransactionsMXBean txMXBean(int igniteInt) throws Exception {
-        ObjectName mbeanName = 
U.makeMBeanName(getTestIgniteInstanceName(igniteInt), "Transactions",
-            TransactionsMXBeanImpl.class.getSimpleName());
-
-        MBeanServer mbeanSrv = ManagementFactory.getPlatformMBeanServer();
-
-        if (!mbeanSrv.isRegistered(mbeanName))
-            fail("MBean is not registered: " + mbeanName.getCanonicalName());
-
-        return MBeanServerInvocationHandler.newProxyInstance(mbeanSrv, 
mbeanName, TransactionsMXBean.class, true);
+        return getMxBean(
+            getTestIgniteInstanceName(igniteInt),
+            "Transactions",
+            TransactionsMXBean.class,
+            TransactionsMXBeanImpl.class
+        );
     }
 }

Reply via email to