Skip to content

Commit 189e23a

Browse files
authored
Merge pull request #10429 from ziggie1984/backport/fix-sql-pool-exhaustion
backport: fix potential sql tx exhaustion
2 parents 0d225a1 + 0c7db1a commit 189e23a

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

docs/release-notes/release-notes-0.20.1.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
has been removed from the public key parsing methods, and proper mutex
5656
protection has been added to the cache access in `DisconnectBlockAtHeight`.
5757

58+
* [Fix potential sql tx exhaustion
59+
issue](https://github.com/lightningnetwork/lnd/pull/10428) in LND which might
60+
happen when running postgres with a limited number of connections configured.
61+
5862
# New Features
5963

6064
## Functional Enhancements

graph/db/kv_store.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,6 +2116,13 @@ func (c *KVStore) fetchNextChanUpdateBatch(
21162116
batch []ChannelEdge
21172117
hasMore bool
21182118
)
2119+
2120+
// Acquire read lock before starting transaction to ensure
2121+
// consistent lock ordering (cacheMu -> DB) and prevent
2122+
// deadlock with write operations.
2123+
c.cacheMu.RLock()
2124+
defer c.cacheMu.RUnlock()
2125+
21192126
err := kvdb.View(c.db, func(tx kvdb.RTx) error {
21202127
edges := tx.ReadBucket(edgeBucket)
21212128
if edges == nil {
@@ -2195,9 +2202,7 @@ func (c *KVStore) fetchNextChanUpdateBatch(
21952202
continue
21962203
}
21972204

2198-
// Before we read the edge info, we'll see if this
2199-
// element is already in the cache or not.
2200-
c.cacheMu.RLock()
2205+
// Check cache (we already hold shared read lock).
22012206
if channel, ok := c.chanCache.get(chanIDInt); ok {
22022207
state.edgesSeen[chanIDInt] = struct{}{}
22032208

@@ -2208,11 +2213,8 @@ func (c *KVStore) fetchNextChanUpdateBatch(
22082213

22092214
indexKey, _ = updateCursor.Next()
22102215

2211-
c.cacheMu.RUnlock()
2212-
22132216
continue
22142217
}
2215-
c.cacheMu.RUnlock()
22162218

22172219
// The edge wasn't in the cache, so we'll fetch it along
22182220
// w/ the edge policies and nodes.

graph/db/sql_store.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,11 @@ func (s *SQLStore) ChanUpdatesInHorizon(startTime, endTime time.Time,
11341134
for hasMore {
11351135
var batch []ChannelEdge
11361136

1137+
// Acquire read lock before starting transaction to
1138+
// ensure consistent lock ordering (cacheMu -> DB) and
1139+
// prevent deadlock with write operations.
1140+
s.cacheMu.RLock()
1141+
11371142
err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(),
11381143
func(db SQLQueries) error {
11391144
//nolint:ll
@@ -1186,11 +1191,11 @@ func (s *SQLStore) ChanUpdatesInHorizon(startTime, endTime time.Time,
11861191
continue
11871192
}
11881193

1189-
s.cacheMu.RLock()
1194+
// Check cache (we already hold
1195+
// shared read lock).
11901196
channel, ok := s.chanCache.get(
11911197
chanIDInt,
11921198
)
1193-
s.cacheMu.RUnlock()
11941199
if ok {
11951200
hits++
11961201
total++
@@ -1224,6 +1229,9 @@ func (s *SQLStore) ChanUpdatesInHorizon(startTime, endTime time.Time,
12241229
)
12251230
})
12261231

1232+
// Release read lock after transaction completes.
1233+
s.cacheMu.RUnlock()
1234+
12271235
if err != nil {
12281236
log.Errorf("ChanUpdatesInHorizon "+
12291237
"batch error: %v", err)

0 commit comments

Comments
 (0)