@@ -196,8 +196,10 @@ func TestLockTableBasic(t *testing.T) {
196
196
case "new-lock-table" :
197
197
var maxLocks int
198
198
d .ScanArgs (t , "maxlocks" , & maxLocks )
199
+ m := TestingMakeLockTableMetricsCfg ()
199
200
ltImpl := newLockTable (
200
201
int64 (maxLocks ), roachpb .RangeID (3 ), clock , cluster .MakeTestingClusterSettings (),
202
+ m .LocksShedDueToMemoryLimit , m .NumLockShedDueToMemoryLimitEvents ,
201
203
)
202
204
ltImpl .enabled = true
203
205
ltImpl .enabledSeq = 1
@@ -888,8 +890,10 @@ func newLock(txn *enginepb.TxnMeta, key roachpb.Key, str lock.Strength) *roachpb
888
890
}
889
891
890
892
func TestLockTableMaxLocks (t * testing.T ) {
893
+ m := TestingMakeLockTableMetricsCfg ()
891
894
lt := newLockTable (
892
895
5 , roachpb .RangeID (3 ), hlc .NewClockForTesting (nil ), cluster .MakeTestingClusterSettings (),
896
+ m .LocksShedDueToMemoryLimit , m .NumLockShedDueToMemoryLimitEvents ,
893
897
)
894
898
lt .minKeysLocked = 0
895
899
lt .enabled = true
@@ -926,6 +930,9 @@ func TestLockTableMaxLocks(t *testing.T) {
926
930
ID : uuid .MakeV4 (),
927
931
WriteTimestamp : hlc.Timestamp {WallTime : 10 },
928
932
}
933
+ // Sanity check counters at the start before we start adding locks.
934
+ require .Equal (t , int64 (0 ), m .NumLockShedDueToMemoryLimitEvents .Count ())
935
+ require .Equal (t , int64 (0 ), m .LocksShedDueToMemoryLimit .Count ())
929
936
for i := range guards {
930
937
for j := 0 ; j < 10 ; j ++ {
931
938
k := i * 20 + j
@@ -938,11 +945,16 @@ func TestLockTableMaxLocks(t *testing.T) {
938
945
}
939
946
// Only the notRemovable locks survive after addition.
940
947
require .Equal (t , int64 (10 ), lt .lockCountForTesting ())
941
- // Two guards are dequeued.
948
+ // The other 90 locks should be shed.
949
+ require .Equal (t , int64 (90 ), m .LocksShedDueToMemoryLimit .Count ())
950
+ require .Equal (t , int64 (66 ), m .NumLockShedDueToMemoryLimitEvents .Count ())
951
+ // Two guards are dequeued. This marks 2 notRemovable locks as removable.
952
+ // We're at 8 notRemovable locks now.
942
953
lt .Dequeue (guards [0 ])
943
954
lt .Dequeue (guards [1 ])
944
955
require .Equal (t , int64 (10 ), lt .lockCountForTesting ())
945
- // Two guards do ScanAndEnqueue.
956
+ // Two guards do ScanAndEnqueue. This marks 2 notRemovable locks as
957
+ // removable. We're at 6 notRemovable locks now.
946
958
for i := 2 ; i < 4 ; i ++ {
947
959
var err * Error
948
960
guards [i ], err = lt .ScanAndEnqueue (reqs [i ], guards [i ])
@@ -958,6 +970,10 @@ func TestLockTableMaxLocks(t *testing.T) {
958
970
require .NoError (t , err )
959
971
// The 6 notRemovable locks remain.
960
972
require .Equal (t , int64 (6 ), lt .lockCountForTesting ())
973
+ // NB: 4 locks that became removable are cleared + the lock that was added by
974
+ // AddDiscoveredLock, taking the total number of locks removed to 5.
975
+ require .Equal (t , int64 (95 ), m .LocksShedDueToMemoryLimit .Count ())
976
+ require .Equal (t , int64 (67 ), m .NumLockShedDueToMemoryLimitEvents .Count ())
961
977
require .Equal (t , int64 (101 ), int64 (lt .locks .lockIDSeqNum ))
962
978
// Add another discovered lock, to trigger tryClearLocks.
963
979
added , err = lt .AddDiscoveredLock (
@@ -967,7 +983,9 @@ func TestLockTableMaxLocks(t *testing.T) {
967
983
require .NoError (t , err )
968
984
// Still the 6 notRemovable locks remain.
969
985
require .Equal (t , int64 (6 ), lt .lockCountForTesting ())
970
- require .Equal (t , int64 (102 ), int64 (lt .locks .lockIDSeqNum ))
986
+ // NB: We cleared the lock added by AddDiscoveredLock above.
987
+ require .Equal (t , int64 (96 ), m .LocksShedDueToMemoryLimit .Count ())
988
+ require .Equal (t , int64 (68 ), m .NumLockShedDueToMemoryLimitEvents .Count ())
971
989
// Two more guards are dequeued, so we are down to 4 notRemovable locks.
972
990
lt .Dequeue (guards [4 ])
973
991
lt .Dequeue (guards [5 ])
@@ -981,6 +999,9 @@ func TestLockTableMaxLocks(t *testing.T) {
981
999
require .NoError (t , err )
982
1000
// This notRemovable=false lock is also added, since enforcement not done.
983
1001
require .Equal (t , int64 (7 ), lt .lockCountForTesting ())
1002
+ // Metrics shouldn't change as enforcement wasn't done.
1003
+ require .Equal (t , int64 (96 ), m .LocksShedDueToMemoryLimit .Count ())
1004
+ require .Equal (t , int64 (68 ), m .NumLockShedDueToMemoryLimitEvents .Count ())
984
1005
// Add another discovered lock, to trigger tryClearLocks.
985
1006
added , err = lt .AddDiscoveredLock (
986
1007
newLock (& txnMeta , keys [9 * 20 + 13 ], lock .Intent ),
@@ -989,10 +1010,14 @@ func TestLockTableMaxLocks(t *testing.T) {
989
1010
require .NoError (t , err )
990
1011
// Now enforcement is done, so only 4 remain.
991
1012
require .Equal (t , int64 (4 ), lt .lockCountForTesting ())
1013
+ // We made 2 locks removable above + added to locks by calling
1014
+ // AddDiscoveredLocks, resulting in 4 locks being cleared in total.
1015
+ require .Equal (t , int64 (100 ), m .LocksShedDueToMemoryLimit .Count ())
1016
+ require .Equal (t , int64 (69 ), m .NumLockShedDueToMemoryLimitEvents .Count ())
992
1017
// Bump down the enforcement interval manually, and bump up minKeysLocked.
993
1018
lt .locks .lockAddMaxLocksCheckInterval = 1
994
1019
lt .minKeysLocked = 2
995
- // Three more guards dequeued.
1020
+ // Three more guards dequeued. Now only 1 lock is notRemovable.
996
1021
lt .Dequeue (guards [6 ])
997
1022
lt .Dequeue (guards [7 ])
998
1023
lt .Dequeue (guards [8 ])
@@ -1003,6 +1028,10 @@ func TestLockTableMaxLocks(t *testing.T) {
1003
1028
require .True (t , added )
1004
1029
require .NoError (t , err )
1005
1030
require .Equal (t , int64 (5 ), lt .lockCountForTesting ())
1031
+ // NB: We're allowed 5 locks. We won't trigger tryClearLocks and the metrics
1032
+ // should reflect this.
1033
+ require .Equal (t , int64 (100 ), m .LocksShedDueToMemoryLimit .Count ())
1034
+ require .Equal (t , int64 (69 ), m .NumLockShedDueToMemoryLimitEvents .Count ())
1006
1035
// Add another discovered lock, to trigger tryClearLocks, and push us over 5
1007
1036
// locks.
1008
1037
added , err = lt .AddDiscoveredLock (
@@ -1013,6 +1042,9 @@ func TestLockTableMaxLocks(t *testing.T) {
1013
1042
// Enforcement keeps the 1 notRemovable lock, and another, since
1014
1043
// minKeysLocked=2.
1015
1044
require .Equal (t , int64 (2 ), lt .lockCountForTesting ())
1045
+ // Which means that in total, 4 more locks are cleared.
1046
+ require .Equal (t , int64 (104 ), m .LocksShedDueToMemoryLimit .Count ())
1047
+ require .Equal (t , int64 (70 ), m .NumLockShedDueToMemoryLimitEvents .Count ())
1016
1048
// Restore minKeysLocked to 0.
1017
1049
lt .minKeysLocked = 0
1018
1050
// Add locks to push us over 5 locks.
@@ -1025,13 +1057,19 @@ func TestLockTableMaxLocks(t *testing.T) {
1025
1057
}
1026
1058
// Only the 1 notRemovable lock remains.
1027
1059
require .Equal (t , int64 (1 ), lt .lockCountForTesting ())
1060
+ // Locks were cleared when we got to 6 locks (and 5 of them were cleared) as
1061
+ // one of them is notRemovable.
1062
+ require .Equal (t , int64 (109 ), m .LocksShedDueToMemoryLimit .Count ())
1063
+ require .Equal (t , int64 (71 ), m .NumLockShedDueToMemoryLimitEvents .Count ())
1028
1064
}
1029
1065
1030
1066
// TestLockTableMaxLocksWithMultipleNotRemovableRefs tests the notRemovable
1031
1067
// ref counting.
1032
1068
func TestLockTableMaxLocksWithMultipleNotRemovableRefs (t * testing.T ) {
1069
+ m := TestingMakeLockTableMetricsCfg ()
1033
1070
lt := newLockTable (
1034
1071
2 , roachpb .RangeID (3 ), hlc .NewClockForTesting (nil ), cluster .MakeTestingClusterSettings (),
1072
+ m .LocksShedDueToMemoryLimit , m .NumLockShedDueToMemoryLimitEvents ,
1035
1073
)
1036
1074
lt .minKeysLocked = 0
1037
1075
lt .enabled = true
@@ -1316,7 +1354,9 @@ func newWorkLoadExecutor(items []workloadItem, concurrency int) *workloadExecuto
1316
1354
nil , /* latchWaitDurations */
1317
1355
clock ,
1318
1356
)
1319
- ltImpl := newLockTable (maxLocks , roachpb .RangeID (3 ), clock , settings )
1357
+ m := TestingMakeLockTableMetricsCfg ()
1358
+ ltImpl := newLockTable (maxLocks , roachpb .RangeID (3 ), clock , settings ,
1359
+ m .LocksShedDueToMemoryLimit , m .NumLockShedDueToMemoryLimitEvents )
1320
1360
ltImpl .enabled = true
1321
1361
lt := maybeWrapInVerifyingLockTable (ltImpl )
1322
1362
ex := & workloadExecutor {
@@ -2018,7 +2058,10 @@ func BenchmarkLockTable(b *testing.B) {
2018
2058
lm := spanlatch .Make (
2019
2059
nil /* stopper */ , nil /* slowReqs */ , settings , nil /* latchWaitDurations */ , clock ,
2020
2060
)
2021
- lt := newLockTable (maxLocks , roachpb .RangeID (3 ), clock , settings )
2061
+ m := TestingMakeLockTableMetricsCfg ()
2062
+ lt := newLockTable (maxLocks , roachpb .RangeID (3 ), clock , settings ,
2063
+ m .LocksShedDueToMemoryLimit , m .NumLockShedDueToMemoryLimitEvents ,
2064
+ )
2022
2065
lt .enabled = true
2023
2066
env := benchEnv {
2024
2067
lm : & lm ,
@@ -2058,11 +2101,14 @@ func BenchmarkLockTableMetrics(b *testing.B) {
2058
2101
for _ , locks := range []int {0 , 1 << 0 , 1 << 4 , 1 << 8 , 1 << 12 } {
2059
2102
b .Run (fmt .Sprintf ("locks=%d" , locks ), func (b * testing.B ) {
2060
2103
const maxLocks = 100000
2104
+ m := TestingMakeLockTableMetricsCfg ()
2061
2105
lt := newLockTable (
2062
2106
maxLocks ,
2063
2107
roachpb .RangeID (3 ),
2064
2108
hlc .NewClockForTesting (nil ),
2065
2109
cluster .MakeTestingClusterSettings (),
2110
+ m .LocksShedDueToMemoryLimit ,
2111
+ m .NumLockShedDueToMemoryLimitEvents ,
2066
2112
)
2067
2113
lt .enabled = true
2068
2114
0 commit comments