The pg_follower extension provides a logical replication feature for PostgreSQL.
Note that this extension was created for educational purposes. Please do not use it in the production stage.
The pg_follower extension must be installed on both upstream and downstream.
Since this extension intensely uses the logical decoding mechanism, the wal_level must be set to logical on the upstream.
This section describes the primary usage of pg_follower.
At first, you must install pg_follower extension on both node, e.g.:
upstream=# CREATE EXTENSION pg_follower ;
CREATE EXTENSION
Then, start_follow can be called on the downstream, with a connection string toward the upstream:
downstream=# SELECT * FROM start_follow('user=postgres port=5431');
start_follow
--------------
(1 row)
This function kicks the background worker, which receives and applies changes from the upstream.
$ ps aux | grep postgres
...
hayato 80919 0.0 0.2 203692 11888 ? Ss 03:06 0:00 postgres: pg_follower worker
hayato 80920 0.0 0.4 211184 16092 ? Ss 03:06 0:00 postgres: walsender postgres postgres [local] START_REPLICATION
After that, the downstream can follow changes done on the upstream. Assuming a table is created and 20 tuples are inserted upstream.
upstream=# CREATE TABLE foo (id int);
CREATE TABLE
upstream=# INSERT INTO foo VALUES (generate_series(1, 20));
INSERT 0 20
After a specific time, we can see the table is also created on the downstream, and tuples exist.
downstream=# SELECT * FROM foo ;
id
----
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(20 rows)
For now, only INSERT, CREATE TABLE, DROP TABLE, and TRUNCATE statements can be replicated.
Any constraints and parameters for the CREATE TABLE would be ignored.
Also, an ERROR would be raised if below clauses are used:
UNLOGGEDTEMPORARYPARTITION OFPARTITION BYINHERITSOF type_name
The pg_follower extension contains a logical decoding output plugin, a background worker, and an event trigger.
The logical decoding plugin outputs a mimic of raw SQL statements from reorder-buffer changes.
The worker connects to the upstream via the libpqwalreceiver shared library. The connection string is passed from the kick function. Then, the worker creates a temporary replication slot with the output plugin described above and requests stream changes.
When the worker receives messages (it would be a usual SQL statement) from the upstream, it opens a transaction and executes them via SPI.
The event trigger will fire when DDL commands end. In the trigger function, the parse-tree is checked and de-parsed into an SQL statement. The result would be written to WAL record as logical decoding messages.
- Add support for table/column constraints
- Add support for
UPDATEstatement - Add support for
DELETEstatement