@@ -196,8 +196,10 @@ func TestLockTableBasic(t *testing.T) {
196196 case "new-lock-table" :
197197 var maxLocks int
198198 d .ScanArgs (t , "maxlocks" , & maxLocks )
199+ m := TestingMakeLockTableMetricsCfg ()
199200 ltImpl := newLockTable (
200201 int64 (maxLocks ), roachpb .RangeID (3 ), clock , cluster .MakeTestingClusterSettings (),
202+ m .LocksShedDueToMemoryLimit , m .NumLockShedDueToMemoryLimitEvents ,
201203 )
202204 ltImpl .enabled = true
203205 ltImpl .enabledSeq = 1
@@ -888,8 +890,10 @@ func newLock(txn *enginepb.TxnMeta, key roachpb.Key, str lock.Strength) *roachpb
888890}
889891
890892func TestLockTableMaxLocks (t * testing.T ) {
893+ m := TestingMakeLockTableMetricsCfg ()
891894 lt := newLockTable (
892895 5 , roachpb .RangeID (3 ), hlc .NewClockForTesting (nil ), cluster .MakeTestingClusterSettings (),
896+ m .LocksShedDueToMemoryLimit , m .NumLockShedDueToMemoryLimitEvents ,
893897 )
894898 lt .minKeysLocked = 0
895899 lt .enabled = true
@@ -926,6 +930,9 @@ func TestLockTableMaxLocks(t *testing.T) {
926930 ID : uuid .MakeV4 (),
927931 WriteTimestamp : hlc.Timestamp {WallTime : 10 },
928932 }
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 ())
929936 for i := range guards {
930937 for j := 0 ; j < 10 ; j ++ {
931938 k := i * 20 + j
@@ -938,11 +945,16 @@ func TestLockTableMaxLocks(t *testing.T) {
938945 }
939946 // Only the notRemovable locks survive after addition.
940947 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.
942953 lt .Dequeue (guards [0 ])
943954 lt .Dequeue (guards [1 ])
944955 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.
946958 for i := 2 ; i < 4 ; i ++ {
947959 var err * Error
948960 guards [i ], err = lt .ScanAndEnqueue (reqs [i ], guards [i ])
@@ -958,6 +970,10 @@ func TestLockTableMaxLocks(t *testing.T) {
958970 require .NoError (t , err )
959971 // The 6 notRemovable locks remain.
960972 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 ())
961977 require .Equal (t , int64 (101 ), int64 (lt .locks .lockIDSeqNum ))
962978 // Add another discovered lock, to trigger tryClearLocks.
963979 added , err = lt .AddDiscoveredLock (
@@ -967,7 +983,9 @@ func TestLockTableMaxLocks(t *testing.T) {
967983 require .NoError (t , err )
968984 // Still the 6 notRemovable locks remain.
969985 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 ())
971989 // Two more guards are dequeued, so we are down to 4 notRemovable locks.
972990 lt .Dequeue (guards [4 ])
973991 lt .Dequeue (guards [5 ])
@@ -981,6 +999,9 @@ func TestLockTableMaxLocks(t *testing.T) {
981999 require .NoError (t , err )
9821000 // This notRemovable=false lock is also added, since enforcement not done.
9831001 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 ())
9841005 // Add another discovered lock, to trigger tryClearLocks.
9851006 added , err = lt .AddDiscoveredLock (
9861007 newLock (& txnMeta , keys [9 * 20 + 13 ], lock .Intent ),
@@ -989,10 +1010,14 @@ func TestLockTableMaxLocks(t *testing.T) {
9891010 require .NoError (t , err )
9901011 // Now enforcement is done, so only 4 remain.
9911012 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 ())
9921017 // Bump down the enforcement interval manually, and bump up minKeysLocked.
9931018 lt .locks .lockAddMaxLocksCheckInterval = 1
9941019 lt .minKeysLocked = 2
995- // Three more guards dequeued.
1020+ // Three more guards dequeued. Now only 1 lock is notRemovable.
9961021 lt .Dequeue (guards [6 ])
9971022 lt .Dequeue (guards [7 ])
9981023 lt .Dequeue (guards [8 ])
@@ -1003,6 +1028,10 @@ func TestLockTableMaxLocks(t *testing.T) {
10031028 require .True (t , added )
10041029 require .NoError (t , err )
10051030 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 ())
10061035 // Add another discovered lock, to trigger tryClearLocks, and push us over 5
10071036 // locks.
10081037 added , err = lt .AddDiscoveredLock (
@@ -1013,6 +1042,9 @@ func TestLockTableMaxLocks(t *testing.T) {
10131042 // Enforcement keeps the 1 notRemovable lock, and another, since
10141043 // minKeysLocked=2.
10151044 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 ())
10161048 // Restore minKeysLocked to 0.
10171049 lt .minKeysLocked = 0
10181050 // Add locks to push us over 5 locks.
@@ -1025,13 +1057,19 @@ func TestLockTableMaxLocks(t *testing.T) {
10251057 }
10261058 // Only the 1 notRemovable lock remains.
10271059 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 ())
10281064}
10291065
10301066// TestLockTableMaxLocksWithMultipleNotRemovableRefs tests the notRemovable
10311067// ref counting.
10321068func TestLockTableMaxLocksWithMultipleNotRemovableRefs (t * testing.T ) {
1069+ m := TestingMakeLockTableMetricsCfg ()
10331070 lt := newLockTable (
10341071 2 , roachpb .RangeID (3 ), hlc .NewClockForTesting (nil ), cluster .MakeTestingClusterSettings (),
1072+ m .LocksShedDueToMemoryLimit , m .NumLockShedDueToMemoryLimitEvents ,
10351073 )
10361074 lt .minKeysLocked = 0
10371075 lt .enabled = true
@@ -1316,7 +1354,9 @@ func newWorkLoadExecutor(items []workloadItem, concurrency int) *workloadExecuto
13161354 nil , /* latchWaitDurations */
13171355 clock ,
13181356 )
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 )
13201360 ltImpl .enabled = true
13211361 lt := maybeWrapInVerifyingLockTable (ltImpl )
13221362 ex := & workloadExecutor {
@@ -2018,7 +2058,10 @@ func BenchmarkLockTable(b *testing.B) {
20182058 lm := spanlatch .Make (
20192059 nil /* stopper */ , nil /* slowReqs */ , settings , nil /* latchWaitDurations */ , clock ,
20202060 )
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+ )
20222065 lt .enabled = true
20232066 env := benchEnv {
20242067 lm : & lm ,
@@ -2058,11 +2101,14 @@ func BenchmarkLockTableMetrics(b *testing.B) {
20582101 for _ , locks := range []int {0 , 1 << 0 , 1 << 4 , 1 << 8 , 1 << 12 } {
20592102 b .Run (fmt .Sprintf ("locks=%d" , locks ), func (b * testing.B ) {
20602103 const maxLocks = 100000
2104+ m := TestingMakeLockTableMetricsCfg ()
20612105 lt := newLockTable (
20622106 maxLocks ,
20632107 roachpb .RangeID (3 ),
20642108 hlc .NewClockForTesting (nil ),
20652109 cluster .MakeTestingClusterSettings (),
2110+ m .LocksShedDueToMemoryLimit ,
2111+ m .NumLockShedDueToMemoryLimitEvents ,
20662112 )
20672113 lt .enabled = true
20682114
0 commit comments