Improve aborted transaction logging 26/80426/1
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 20 Feb 2019 13:47:12 +0000 (14:47 +0100)
committerRobert Varga <nite@hq.sk>
Wed, 20 Feb 2019 22:08:41 +0000 (22:08 +0000)
The fact that a snapshot is recorded does not mean it has not been
closed -- in fact write-aspect transactions do not actively remove
themselves.

When we prune recorded snapshots on transaction chain close, we need
to pay attention to the return value of abort(), as that is
indicating whether we should in fact warn about an unclosed
transaction.

This means that the actual set of transactions we warn about cannot
be determined until we have traversed all recorded snapshots, hence
modify the logic to record the identifiers that were in fact aborted
and report all of them in a single message along with a stack trace
so the offender may be identifier.

Change-Id: I8b176f1990c9aa9c056cd03203ea50fb9b9549a0
JIRA: CONTROLLER-1886
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 21eed79684671b9a44e34edbd589419cb9bb6087)

opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ClientBackedTransactionChain.java

index 677610c84844aec2a65bffb4b6eb8f6305505bcd..6ae7e51c54baea21c7a4315b6c90d1289f957902 100644 (file)
@@ -8,9 +8,12 @@
 package org.opendaylight.controller.cluster.databroker;
 
 import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.WeakHashMap;
 import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
 import org.opendaylight.controller.cluster.databroker.actors.dds.AbstractClientHandle;
 import org.opendaylight.controller.cluster.databroker.actors.dds.ClientLocalHistory;
 import org.opendaylight.controller.cluster.databroker.actors.dds.ClientSnapshot;
@@ -58,12 +61,19 @@ final class ClientBackedTransactionChain implements DOMStoreTransactionChain {
 
     @Override
     public synchronized void close() {
+        final List<TransactionIdentifier> abortedSnapshots = new ArrayList<>();
         for (AbstractClientHandle<?> snap : openSnapshots.keySet()) {
-            LOG.warn("Aborting unclosed transaction {}", snap.getIdentifier());
-            snap.abort();
+            final TransactionIdentifier id = snap.getIdentifier();
+            LOG.debug("Aborting recorded transaction {}", id);
+            if (snap.abort()) {
+                abortedSnapshots.add(id);
+            }
         }
         openSnapshots.clear();
 
+        if (!abortedSnapshots.isEmpty()) {
+            LOG.warn("Aborted unclosed transactions {}", abortedSnapshots, new Throwable("at"));
+        }
         history.close();
     }