Skip to content

Commit 5bbed69

Browse files
IGNITE-28833 Add system views for cache locks
1 parent 93cf8f0 commit 5bbed69

11 files changed

Lines changed: 754 additions & 3 deletions

File tree

docs/_docs/monitoring-metrics/system-views.adoc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ Each row in this view represents a transaction object on the node where the view
275275
|ORIGINATING_NODE_ID | UUID | ID of the node that initiated the current transaction object. For a transaction object mapped to a primary partition, this is the transaction initiator node; for a transaction object mapped to a backup partition, this is the node that owns the primary partition
276276
|STATE | string | Current transaction state
277277
|XID | UUID | Unique transaction identifier
278+
|ORIGINATING_XID | UUID | Ttransaction ID on originating node
278279
|LABEL | string | Transaction label
279280
|START_TIME | long | Start time of the transaction on this node
280281
|ISOLATION | string | Transaction isolation level
@@ -299,6 +300,39 @@ Each row in this view represents a transaction object on the node where the view
299300
|TOP_VER | string | Topology version assigned to the transaction. If not assigned explicitly, it is a topology version of the latest partition exchange.
300301
|===
301302

303+
== CACHE_EXPLICIT_LOCKS
304+
305+
This view exposes information about explicit locks acquired on the current node.
306+
Explicit locks are acquired using the `Cache.lock(key)` API.
307+
308+
[{table_opts}]
309+
|===
310+
|NAME | TYPE | DESCRIPTION
311+
|CACHE_ID | int | Cache ID
312+
|KEY | string | Locked key
313+
|THREAD_ID | long | ID of the thread that acquired the lock
314+
|XID | UUID | Lock ID (unique identifier)
315+
|===
316+
317+
== CACHE_KEY_LOCKS
318+
319+
This view exposes information about all locks (both explicit and transactional) requested for keys hosted on the current node.
320+
This includes locks from remote nodes trying to access primary keys on this node.
321+
322+
[{table_opts}]
323+
|===
324+
|NAME | TYPE | DESCRIPTION
325+
|CACHE_ID | int | Cache ID
326+
|KEY | string | Locked key
327+
|NODE_ID | UUID | ID of the node where the lock is hosted
328+
|ORIGINATING_NODE_ID | UUID | ID of the node that initiated the lock request
329+
|IS_OWNER | boolean | `True` if the lock is currently owned
330+
|IS_TX | boolean | `True` if the lock is part of a transaction
331+
|FLAGS | string | All flags for the lock
332+
|XID | UUID | Current transaction ID (or explicit lock ID)
333+
|ORIGINATING_XID | UUID | Originating transaction ID (or explicit lock ID)
334+
|===
335+
302336
== NODES
303337

304338

modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3291,7 +3291,7 @@ public void clearAllListener() {
32913291
* @param ver Cache version.
32923292
* @return Version represented as {@code IgniteUuid}.
32933293
*/
3294-
public static IgniteUuid asIgniteUuid(GridCacheVersion ver) {
3295-
return new IgniteUuid(new UUID(ver.topologyVersion(), ver.nodeOrderAndDrIdRaw()), ver.order());
3294+
public static @Nullable IgniteUuid asIgniteUuid(@Nullable GridCacheVersion ver) {
3295+
return ver == null ? null : new IgniteUuid(new UUID(ver.topologyVersion(), ver.nodeOrderAndDrIdRaw()), ver.order());
32963296
}
32973297
}

modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheExplicitLockSpan.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
package org.apache.ignite.internal.processors.cache;
1919

20+
import java.util.ArrayList;
21+
import java.util.Collection;
2022
import java.util.Deque;
2123
import java.util.HashMap;
2224
import java.util.Iterator;
@@ -216,6 +218,20 @@ public boolean isEmpty() {
216218
}
217219
}
218220

221+
/**
222+
* @return Lock candidates.
223+
*/
224+
public Collection<GridCacheMvccCandidate> candidates() {
225+
lock();
226+
227+
try {
228+
return new ArrayList<>(F.flatCollections(cands.values()));
229+
}
230+
finally {
231+
unlock();
232+
}
233+
}
234+
219235
/**
220236
* Marks all candidates added for given key as owned.
221237
*

modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,22 @@ public IgniteTxKey key() {
607607
return parent0.txKey();
608608
}
609609

610+
/** */
611+
public String enabledFlags() {
612+
SB sb = new SB();
613+
614+
for (Mask m : Mask.MASKS) {
615+
if (m.bit(flags) != 0) {
616+
if (sb.length() != 0)
617+
sb.a(" | ");
618+
619+
sb.a(m.name());
620+
}
621+
}
622+
623+
return sb.toString();
624+
}
625+
610626
/** {@inheritDoc} */
611627
@Override public GridCacheMvccCandidate candidate(int idx) {
612628
assert idx == 0 : idx;

modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.ArrayDeque;
2121
import java.util.ArrayList;
2222
import java.util.Collection;
23+
import java.util.Collections;
2324
import java.util.Deque;
2425
import java.util.HashMap;
2526
import java.util.HashSet;
@@ -49,6 +50,8 @@
4950
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
5051
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
5152
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
53+
import org.apache.ignite.internal.systemview.CacheExplicitLockViewWalker;
54+
import org.apache.ignite.internal.systemview.CacheKeyLockViewWalker;
5255
import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashSet;
5356
import org.apache.ignite.internal.util.GridConcurrentFactory;
5457
import org.apache.ignite.internal.util.GridConcurrentHashSet;
@@ -67,6 +70,8 @@
6770
import org.apache.ignite.lang.IgniteFuture;
6871
import org.apache.ignite.lang.IgnitePredicate;
6972
import org.apache.ignite.lang.IgniteUuid;
73+
import org.apache.ignite.spi.systemview.view.CacheExplicitLockView;
74+
import org.apache.ignite.spi.systemview.view.CacheKeyLockView;
7075
import org.apache.ignite.util.deque.FastSizeDeque;
7176
import org.jetbrains.annotations.Nullable;
7277

@@ -94,6 +99,18 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
9499
private static final int MAX_NESTED_LSNR_CALLS =
95100
getInteger(IGNITE_MAX_NESTED_LISTENER_CALLS, DFLT_MAX_NESTED_LISTENER_CALLS);
96101

102+
/** System view name for cache explicit locks. */
103+
public static final String CACHE_EXPLICIT_LOCKS_VIEW = "cacheExplicitLocks";
104+
105+
/** System view description for cache explicit locks. */
106+
public static final String CACHE_EXPLICIT_LOCKS_VIEW_DESC = "Explicit locks on cache keys";
107+
108+
/** System view name for cache locks. */
109+
public static final String CACHE_KEY_LOCKS_VIEW = "cacheKeyLocks";
110+
111+
/** System view description for cache keys locks. */
112+
public static final String CACHE_KEY_LOCKS_VIEW_DESC = "Held and queued locks on cache keys";
113+
97114
/** Pending locks per thread. */
98115
private final ThreadLocal<Deque<GridCacheMvccCandidate>> pending = new ThreadLocal<>();
99116

@@ -282,6 +299,33 @@ else if (log.isDebugEnabled())
282299
pendingExplicit = GridConcurrentFactory.newMap();
283300

284301
cctx.gridEvents().addLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT);
302+
303+
cctx.kernalContext().systemView().registerInnerCollectionView(
304+
CACHE_EXPLICIT_LOCKS_VIEW,
305+
CACHE_EXPLICIT_LOCKS_VIEW_DESC,
306+
new CacheExplicitLockViewWalker(),
307+
pendingExplicit.values(),
308+
GridCacheExplicitLockSpan::candidates,
309+
(threadId, lock) -> new CacheExplicitLockView(lock)
310+
);
311+
312+
cctx.kernalContext().systemView().registerInnerCollectionView(
313+
CACHE_KEY_LOCKS_VIEW,
314+
CACHE_KEY_LOCKS_VIEW_DESC,
315+
new CacheKeyLockViewWalker(),
316+
locked.values(),
317+
entry -> {
318+
entry.lockEntry();
319+
try {
320+
GridCacheMvcc mvcc = entry.mvccExtras();
321+
return mvcc != null ? mvcc.localCandidates() : Collections.emptyList();
322+
}
323+
finally {
324+
entry.unlockEntry();
325+
}
326+
},
327+
(entry, cand) -> new CacheKeyLockView(cand)
328+
);
285329
}
286330

287331
/** {@inheritDoc} */
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.spi.systemview.view;
19+
20+
import org.apache.ignite.internal.binary.BinaryUtils;
21+
import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
22+
import org.apache.ignite.internal.systemview.Order;
23+
import org.apache.ignite.internal.systemview.SystemViewDescriptor;
24+
import org.apache.ignite.lang.IgniteUuid;
25+
26+
/**
27+
* Cache explicit lock representation for a {@link SystemView}.
28+
* Shows locks acquired on current node (not hosted by current node).
29+
*/
30+
@SystemViewDescriptor
31+
public class CacheExplicitLockView {
32+
/** */
33+
private final GridCacheMvccCandidate cand;
34+
35+
/**
36+
* @param cand Lock candidate
37+
*/
38+
public CacheExplicitLockView(GridCacheMvccCandidate cand) {
39+
this.cand = cand;
40+
}
41+
42+
/**
43+
* @return Cache ID.
44+
*/
45+
@Order
46+
public int cacheId() {
47+
return cand.key().cacheId();
48+
}
49+
50+
/**
51+
* @return Key.
52+
*/
53+
@Order(1)
54+
public String key() {
55+
return cand.key().key().toString();
56+
}
57+
58+
/**
59+
* @return Thread ID.
60+
*/
61+
@Order(2)
62+
public long threadId() {
63+
return cand.threadId();
64+
}
65+
66+
/**
67+
* @return Version.
68+
*/
69+
@Order(3)
70+
public IgniteUuid xid() {
71+
return BinaryUtils.asIgniteUuid(cand.version());
72+
}
73+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.spi.systemview.view;
19+
20+
import java.util.UUID;
21+
import org.apache.ignite.internal.binary.BinaryUtils;
22+
import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
23+
import org.apache.ignite.internal.systemview.Order;
24+
import org.apache.ignite.internal.systemview.SystemViewDescriptor;
25+
import org.apache.ignite.lang.IgniteUuid;
26+
27+
/**
28+
* Cache key lock representation for a {@link SystemView}.
29+
* Shows held cache key locks and queued cache key locks hosted on current node,
30+
* including explicit locks and transactional locks.
31+
*/
32+
@SystemViewDescriptor
33+
public class CacheKeyLockView {
34+
/** Lock candidate. */
35+
private final GridCacheMvccCandidate cand;
36+
37+
/**
38+
* @param cand Lock candidate
39+
*/
40+
public CacheKeyLockView(GridCacheMvccCandidate cand) {
41+
this.cand = cand;
42+
}
43+
44+
/**
45+
* @return Cache ID.
46+
*/
47+
@Order
48+
public int cacheId() {
49+
return cand.key().cacheId();
50+
}
51+
52+
/**
53+
* @return Key.
54+
*/
55+
@Order(1)
56+
public String key() {
57+
return cand.key().key().toString();
58+
}
59+
60+
/**
61+
* @return Node ID.
62+
*/
63+
@Order(2)
64+
public UUID nodeId() {
65+
return cand.nodeId();
66+
}
67+
68+
/**
69+
* @return Originating node ID.
70+
*/
71+
@Order(3)
72+
public UUID originatingNodeId() {
73+
return cand.otherNodeId();
74+
}
75+
76+
77+
/**
78+
* @return "OWNER" flag.
79+
*/
80+
@Order(4)
81+
public boolean isOwner() {
82+
return cand.owner();
83+
}
84+
85+
/**
86+
* @return "TX" flag.
87+
*/
88+
@Order(5)
89+
public boolean isTx() {
90+
return cand.tx();
91+
}
92+
93+
/**
94+
* @return All enabled flags.
95+
*/
96+
@Order(6)
97+
public String flags() {
98+
return cand.enabledFlags();
99+
}
100+
101+
/**
102+
* @return Transaction ID.
103+
*/
104+
@Order(7)
105+
public IgniteUuid xid() {
106+
return BinaryUtils.asIgniteUuid(cand.version());
107+
}
108+
109+
/**
110+
* @return Originating transaction ID.
111+
*/
112+
@Order(8)
113+
public IgniteUuid originatingXid() {
114+
return BinaryUtils.asIgniteUuid(cand.otherVersion());
115+
}
116+
}

0 commit comments

Comments
 (0)