Compare commits

...

6 Commits

Author SHA1 Message Date
Ivan Folgueira Bande
6784656ad3 adjust changelog 2024-07-12 10:02:28 +02:00
Ivan Folgueira Bande
14ff3c1e42 postgres_driver: add more error handling when creating partitions
Given that multiple nodes can be connected to the same database,
it can happen that other node did something that my node was willing
to do. In this commit, we overcome the possible "interleaved"
partition creation.
2024-07-08 14:57:52 +02:00
Ivan Folgueira Bande
3262e0c0ac CHANGELOG.md update 2024-07-08 12:25:09 +02:00
Alvaro Revuelta
5af1ddc4b5 chore(rln): rln message limit to 100 (#2883) 2024-07-08 11:52:04 +02:00
Ivan Folgueira Bande
b5019ab5bc CHANGELOG.md update for v0.30.2 2024-07-07 23:27:19 +02:00
Ivan Folgueira Bande
84a7c2bf7f postgres_driver: better partition creation without exclusive access 2024-07-07 18:56:08 +02:00
3 changed files with 77 additions and 13 deletions

View File

@ -1,3 +1,24 @@
## v0.30.2 (2024-07-12)
### Release highlights
* RLN message limit to 100 messages per epoch.
* Avoid exclusive access when creating new partitions in the PostgreSQL messages table.
### Changes
- chore(rln): rln message limit to 100 ([#2883](https://github.com/waku-org/nwaku/pull/2883))
- fix: postgres_driver better partition creation without exclusive access [28bdb70b](https://github.com/waku-org/nwaku/commit/28bdb70be46d3fb3a6f992b3f9f2de1defd85a30)
This release supports the following [libp2p protocols](https://docs.libp2p.io/concepts/protocols/):
| Protocol | Spec status | Protocol id |
| ---: | :---: | :--- |
| [`11/WAKU2-RELAY`](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/11/relay.md) | `stable` | `/vac/waku/relay/2.0.0` |
| [`12/WAKU2-FILTER`](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/12/filter.md) | `draft` | `/vac/waku/filter/2.0.0-beta1` <br />`/vac/waku/filter-subscribe/2.0.0-beta1` <br />`/vac/waku/filter-push/2.0.0-beta1` |
| [`13/WAKU2-STORE`](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/13/store.md) | `draft` | `/vac/waku/store/2.0.0-beta4` |
| [`19/WAKU2-LIGHTPUSH`](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/19/lightpush.md) | `draft` | `/vac/waku/lightpush/2.0.0-beta1` |
| [`66/WAKU2-METADATA`](https://github.com/waku-org/specs/blob/master/standards/core/metadata.md) | `raw` | `/vac/waku/metadata/1.0.0` |
## v0.30.1 (2024-07-03)
### Notes

View File

@ -41,7 +41,7 @@ proc TheWakuNetworkConf*(T: type ClusterConf): ClusterConf =
rlnRelayChainId: 11155111,
rlnRelayBandwidthThreshold: 0,
rlnEpochSizeSec: 600,
rlnRelayUserMessageLimit: 20,
rlnRelayUserMessageLimit: 100,
pubsubTopics:
@[
"/waku/2/rs/1/0", "/waku/2/rs/1/1", "/waku/2/rs/1/2", "/waku/2/rs/1/3",

View File

@ -918,7 +918,9 @@ const COULD_NOT_ACQUIRE_ADVISORY_LOCK* = "could not acquire advisory lock"
proc performWriteQueryWithLock*(
self: PostgresDriver, queryToProtect: string
): Future[ArchiveDriverResult[void]] {.async.} =
## This wraps the original query in a script so that we make sure a pg_advisory lock protects it
## This wraps the original query in a script so that we make sure a pg_advisory lock protects it.
## The purpose of this proc is to protect write queries that might be performed simultaneously
## to the same database, from different store nodes.
debug "performWriteQueryWithLock", queryToProtect
let query =
fmt"""
@ -947,6 +949,29 @@ proc performWriteQueryWithLock*(
END $$;
"""
(await self.performWriteQuery(query)).isOkOr:
if error.contains(COULD_NOT_ACQUIRE_ADVISORY_LOCK):
## We don't consider this as an error. Just someone else acquired the advisory lock
debug "skip performWriteQuery because the advisory lock is acquired by other"
return ok()
if error.contains("already exists"):
## expected to happen when trying to add a partition table constraint that already exists
## e.g., constraint "constraint_name" for relation "messages_1720364735_1720364740" already exists
debug "skip already exists error", error = error
return ok()
if error.contains("is already a partition"):
## expected to happen when a node tries to add a partition that is already attached,
## e.g., "messages_1720364735_1720364740" is already a partition
debug "skip is already a partition error", error = error
return ok()
if error.contains("does not exist"):
## expected to happen when trying to drop a constraint that has already been dropped by other
## constraint "constraint_name" of relation "messages_1720364735_1720364740" does not exist
debug "skip does not exist error", error = error
return ok()
debug "protected query ended with error", error = $error
return err("protected query ended with error:" & $error)
@ -971,22 +996,40 @@ proc addPartition(
let partitionName = "messages_" & fromInSec & "_" & untilInSec
## Create the partition table but not attach it yet to the main table
let createPartitionQuery =
"CREATE TABLE IF NOT EXISTS " & partitionName & " PARTITION OF " &
"messages FOR VALUES FROM ('" & fromInNanoSec & "') TO ('" & untilInNanoSec & "');"
"CREATE TABLE IF NOT EXISTS " & partitionName &
" (LIKE messages INCLUDING DEFAULTS INCLUDING CONSTRAINTS);"
(await self.performWriteQueryWithLock(createPartitionQuery)).isOkOr:
if error.contains("already exists"):
debug "skip create new partition as it already exists: ", skipped_error = $error
return ok()
if error.contains(COULD_NOT_ACQUIRE_ADVISORY_LOCK):
debug "skip create new partition because the advisory lock is acquired by other"
return ok()
## for any different error, just consider it
return err(fmt"error adding partition [{partitionName}]: " & $error)
## Add constraint to the partition table so that EXCLUSIVE ACCESS is not performed when
## the partition is attached to the main table.
let constraintName = partitionName & "_by_range_check"
let addTimeConstraintQuery =
"ALTER TABLE " & partitionName & " ADD CONSTRAINT " & constraintName &
" CHECK ( storedAt >= " & fromInNanoSec & " AND storedAt < " & untilInNanoSec & " );"
(await self.performWriteQueryWithLock(addTimeConstraintQuery)).isOkOr:
return err(fmt"error creating constraint [{partitionName}]: " & $error)
## Attaching the new created table as a new partition. That does not require EXCLUSIVE ACCESS.
let attachPartitionQuery =
"ALTER TABLE messages ATTACH PARTITION " & partitionName & " FOR VALUES FROM (" &
fromInNanoSec & ") TO (" & untilInNanoSec & ");"
(await self.performWriteQueryWithLock(attachPartitionQuery)).isOkOr:
return err(fmt"error attaching partition [{partitionName}]: " & $error)
## Dropping the check constraint as it was only necessary to prevent full scan,
## and EXCLUSIVE ACCESS, to the whole messages table, when the new partition was attached.
let dropConstraint =
"ALTER TABLE " & partitionName & " DROP CONSTRAINT " & constraintName & ";"
(await self.performWriteQueryWithLock(dropConstraint)).isOkOr:
return err(fmt"error dropping constraint [{partitionName}]: " & $error)
debug "new partition added", query = createPartitionQuery
self.partitionMngr.addPartitionInfo(partitionName, beginning, `end`)