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
niterations and then testing that all three representations align.
- Start postgres with logical replication mode - see the
docker-compose.yamland theDockerfilefor configuration. - Run
cargo install sqlx-clito set up the sqlx command line utility to allow database migrations. - Run
sqlx migrate runto 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: rust-postgres/rust-postgres#116- Materialize's fork of
rust-postgreswith 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