A project to play with and test Postgres logical replication using Rust.
Logical replication gives the ability to subscribe to the Postgres write-ahead-log messages and decode them into usable (and transactional) data. There are many uses for this functionality, for example:
- a web server could store (and invalidate) a local cache of a table in a database to prevent a database round-trip.
- a notification could be sent to a user as a result of an action by another user connected to a different web server instance.
Logical replication is lower level than the Postgres LISTEN functionality, causes no performance impact and does not require the user to choose which tables to listen to.
The main test is in types/mod.rs.
This test attempts to perform deterministic simulation by first attaching the logicalreplication
listener to an empty database then:
- Deterministically produce random batches of transactions against an in-memory representation of the table.
- Applying the batched transactions to the Postgres database.
- Listening to the logical replication stream and trying to apply them to a second in-memory representation of the table.
- Stopping the test after
n
iterations and then testing that all three representations align.
- Start postgres with logical replication mode - see the
docker-compose.yaml
and theDockerfile
for configuration. - Run
cargo install sqlx-cli
to set up the sqlx command line utility to allow database migrations. - Run
sqlx migrate run
to set up the intial database. - Run
cargo test
.
Ideas of what would be helpful:
-
It would be good to build a procedural macro similar to structmap which automates the generation of applying what is received from the logical decoding (effectively a vector of hashmaps) directly to structs.
-
This version deliberately chooses decoderbufs but work could be done to ensure it works with wal2json too and that output data is standardised.
Thank you to:
rust-postgres
: sfackler/rust-postgres#116- Materialize's fork of
rust-postgres
with the patches required to support logical decoding: https://github.com/MaterializeInc/rust-postgres postgres-decoderbufs
: https://github.com/debezium/postgres-decoderbufs- this example: https://github.com/debate-map/app/blob/afc6467b6c6c961f7bcc7b7f901f0ff5cd79d440/Packages/app-server-rs/src/pgclient.rs