Skip to content

Commit 4eaf57d

Browse files
authored
Merge pull request #10397 from ziggie1984/backport/add-back-globallock
backport: readd global lock for postgres and the channeldb_kv table
2 parents 0aa757b + 6bdfb1d commit 4eaf57d

File tree

8 files changed

+62
-17
lines changed

8 files changed

+62
-17
lines changed

docs/postgres.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ db.postgres.timeout=0
4242
Connection timeout is disabled, to account for situations where the database
4343
might be slow for unexpected reasons.
4444

45+
Moreover for particular kv tables we also add the option to access the
46+
tables via a global lock (single wirter). This is a temorpary measure until
47+
these particular tables have a native sql schema. This helps to mitigate
48+
resource exhaustion in case LND experiencing high concurrent load:
49+
50+
* `db.postgres.walletdb-with-global-lock=true` to run LND with a single writer
51+
for the walletdb_kv table (default is true).
52+
* `db.postgres.channeldb-with-global-lock=false` to run the channeldb_kv table
53+
with a single writer (default is false).
54+
4555
## Important note about replication
4656

4757
In case a replication architecture is planned, streaming replication should be avoided, as the master does not verify the replica is indeed identical, but it will only forward the edits queue, and let the slave catch up autonomously; synchronous mode, albeit slower, is paramount for `lnd` data integrity across the copies, as it will finalize writes only after the slave confirmed successful replication.

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@
5151

5252
## Performance Improvements
5353

54+
* [Added new Postgres configuration
55+
options](https://github.com/lightningnetwork/lnd/pull/10394)
56+
`db.postgres.channeldb-with-global-lock` and
57+
`db.postgres.walletdb-with-global-lock` to allow fine-grained control over
58+
database concurrency. The channeldb global lock defaults to `false` to enable
59+
concurrent access, while the wallet global lock defaults to `true` to maintain
60+
safe single-writer behavior until the wallet subsystem is fully
61+
concurrent-safe.
62+
5463
## Deprecations
5564

5665
# Technical and Architectural Updates

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ require (
202202
sigs.k8s.io/yaml v1.2.0 // indirect
203203
)
204204

205+
// Use the local sqldb package for development.
206+
// TODO(norbert): remove once sqldb package is tagged.
207+
replace github.com/lightningnetwork/lnd/sqldb => ./sqldb
208+
205209
// This replace is for https://github.com/advisories/GHSA-25xm-hr59-7c27
206210
replace github.com/ulikunitz/xz => github.com/ulikunitz/xz v0.5.11
207211

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,6 @@ github.com/lightningnetwork/lnd/kvdb v1.4.16 h1:9BZgWdDfjmHRHLS97cz39bVuBAqMc4/p
382382
github.com/lightningnetwork/lnd/kvdb v1.4.16/go.mod h1:HW+bvwkxNaopkz3oIgBV6NEnV4jCEZCACFUcNg4xSjM=
383383
github.com/lightningnetwork/lnd/queue v1.1.1 h1:99ovBlpM9B0FRCGYJo6RSFDlt8/vOkQQZznVb18iNMI=
384384
github.com/lightningnetwork/lnd/queue v1.1.1/go.mod h1:7A6nC1Qrm32FHuhx/mi1cieAiBZo5O6l8IBIoQxvkz4=
385-
github.com/lightningnetwork/lnd/sqldb v1.0.11 h1:X8J3OvdIhJVniQG78Qsp3niErl1zdGMTPvzgiLMWOOo=
386-
github.com/lightningnetwork/lnd/sqldb v1.0.11/go.mod h1:oOdZ7vjmAUmI9He+aFHTunnxKVefHZAfJttZdz16hSg=
387385
github.com/lightningnetwork/lnd/ticker v1.1.1 h1:J/b6N2hibFtC7JLV77ULQp++QLtCwT6ijJlbdiZFbSM=
388386
github.com/lightningnetwork/lnd/ticker v1.1.1/go.mod h1:waPTRAAcwtu7Ji3+3k+u/xH5GHovTsCoSVpho0KDvdA=
389387
github.com/lightningnetwork/lnd/tlv v1.3.2 h1:MO4FCk7F4k5xPMqVZF6Nb/kOpxlwPrUQpYjmyKny5s0=

lncfg/db.go

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,15 @@ func DefaultDB() *DB {
115115
},
116116
Postgres: &sqldb.PostgresConfig{
117117
MaxConnections: defaultPostgresMaxConnections,
118-
QueryConfig: *sqldb.DefaultPostgresConfig(),
118+
// Normally we don't use a global lock for channeldb
119+
// access, but if a user encounters huge concurrency
120+
// issues, they can enable this to use a global lock.
121+
ChannelDBWithGlobalLock: false,
122+
// Default to true to maintain safe single-writer
123+
// behavior until the wallet subsystem is upgraded to
124+
// a native sql schema.
125+
WalletDBWithGlobalLock: true,
126+
QueryConfig: *sqldb.DefaultPostgresConfig(),
119127
},
120128
Sqlite: &sqldb.SqliteConfig{
121129
MaxConnections: defaultSqliteMaxConnections,
@@ -400,9 +408,15 @@ func (db *DB) GetBackends(ctx context.Context, chanDBPath,
400408
// users to native SQL.
401409
postgresConfig := GetPostgresConfigKVDB(db.Postgres)
402410

411+
// Create a separate config for channeldb with the global lock
412+
// setting if configured.
413+
postgresConfigChannelDB := GetPostgresConfigKVDB(db.Postgres)
414+
postgresConfigChannelDB.WithGlobalLock = db.Postgres.
415+
ChannelDBWithGlobalLock
416+
403417
postgresBackend, err := kvdb.Open(
404418
kvdb.PostgresBackendName, ctx,
405-
postgresConfig, NSChannelDB,
419+
postgresConfigChannelDB, NSChannelDB,
406420
)
407421
if err != nil {
408422
return nil, fmt.Errorf("error opening postgres graph "+
@@ -450,14 +464,11 @@ func (db *DB) GetBackends(ctx context.Context, chanDBPath,
450464
}
451465
closeFuncs[NSTowerServerDB] = postgresTowerServerBackend.Close
452466

453-
// The wallet subsystem is still not robust enough to run it
454-
// without a single writer in postgres therefore we create a
455-
// new config with the global lock enabled.
456-
//
457-
// NOTE: This is a temporary measure and should be removed as
458-
// soon as the wallet code is more robust.
467+
// Create a separate config for wallet with the global lock
468+
// setting if configured.
459469
postgresConfigWalletDB := GetPostgresConfigKVDB(db.Postgres)
460-
postgresConfigWalletDB.WithGlobalLock = true
470+
postgresConfigWalletDB.WithGlobalLock = db.Postgres.
471+
WalletDBWithGlobalLock
461472

462473
postgresWalletBackend, err := kvdb.Open(
463474
kvdb.PostgresBackendName, ctx,

sample-lnd.conf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,17 @@
16161616
; Whether to skip executing schema migrations.
16171617
; db.postgres.skipmigrations=false
16181618

1619+
; Use a global lock for channeldb access. This ensures only a single writer at
1620+
; a time but reduces concurrency. This is a temporary workaround until the
1621+
; revocation log is migrated to native SQL.
1622+
; db.postgres.channeldb-with-global-lock=false
1623+
1624+
1625+
; Use a global lock for wallet database access. This is a temporary workaround
1626+
; until the wallet subsystem is upgraded to a native sql schema.
1627+
; db.postgres.walletdb-with-global-lock=true
1628+
1629+
16191630
; The maximum number of elements to use in a native-SQL batch query IN clause.
16201631
; db.postgres.query.max-batch-size=5000
16211632

scripts/check-sample-lnd-conf.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ OPTIONS_NO_LND_DEFAULT_VALUE_CHECK="channel-max-fee-exposure adminmacaroonpath \
5959
backupfilepath maxchansize bitcoin.chaindir bitcoin.defaultchanconfs \
6060
bitcoin.defaultremotedelay bitcoin.dnsseed signrpc.signermacaroonpath \
6161
walletrpc.walletkitmacaroonpath chainrpc.notifiermacaroonpath \
62-
routerrpc.routermacaroonpath"
62+
routerrpc.routermacaroonpath db.postgres.walletdb-with-global-lock"
6363

6464

6565
# EXITCODE is returned at the end after all checks are performed and set to 1

sqldb/config.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,13 @@ func (p *SqliteConfig) Validate() error {
4444
//
4545
//nolint:ll
4646
type PostgresConfig struct {
47-
Dsn string `long:"dsn" description:"Database connection string."`
48-
Timeout time.Duration `long:"timeout" description:"Database connection timeout. Set to zero to disable."`
49-
MaxConnections int `long:"maxconnections" description:"The maximum number of open connections to the database. Set to zero for unlimited."`
50-
SkipMigrations bool `long:"skipmigrations" description:"Skip applying migrations on startup."`
51-
QueryConfig `group:"query" namespace:"query"`
47+
Dsn string `long:"dsn" description:"Database connection string."`
48+
Timeout time.Duration `long:"timeout" description:"Database connection timeout. Set to zero to disable."`
49+
MaxConnections int `long:"maxconnections" description:"The maximum number of open connections to the database. Set to zero for unlimited."`
50+
SkipMigrations bool `long:"skipmigrations" description:"Skip applying migrations on startup."`
51+
ChannelDBWithGlobalLock bool `long:"channeldb-with-global-lock" description:"Use a global lock for channeldb access. This ensures only a single writer at a time but reduces concurrency. This is a temporary workaround until the revocation log is migrated to a native sql schema."`
52+
WalletDBWithGlobalLock bool `long:"walletdb-with-global-lock" description:"Use a global lock for wallet database access. This ensures only a single writer at a time but reduces concurrency. This is a temporary workaround until the wallet subsystem is upgraded to a native sql schema."`
53+
QueryConfig `group:"query" namespace:"query"`
5254
}
5355

5456
// Validate checks that the PostgresConfig values are valid.

0 commit comments

Comments
 (0)