Using Spock to Create a Two-Node Cluster
After installing and initializing Postgres and creating the Spock Extension, you can use the following steps to configure a two-node cluster. In the examples that follow, we'll be creating a cluster that contains two nodes, named n1
and n2
that listen for Postgres server connections on port 5432
.
-
Connect to each node, and use the following commands to initialize a cluster:
sudo /usr/pgsql-17/bin/postgresql-17-setup initdb
sudo systemctl enable postgresql-17
-
Use your choice of editor to open the
postgresql.conf
file (located in/var/lib/pgsql/17/data/postgresql.conf
) and add the following parameters to the bottom of the file:wal_level = 'logical'
max_worker_processes = 10
max_replication_slots = 10
max_wal_senders = 10
shared_preload_libraries = 'spock'
track_commit_timestamp = on
-
Edit the
pg_hba.conf
file (opens in a new tab) (located in/var/lib/pgsql/17/data/postgresql.conf
) and allow connections betweenn1
andn2
; the following commands are provided as an example only, and are not recommended for production systems as they will open your system for connection from any client:host all all 0.0.0.0/0 trust
local replication all trust
host replication all 0.0.0.0/0 trust
-
Use the
spock.node_create
command to create the provider and subscriber nodes; onn1
, use the command:SELECT spock.node_create (node_name := 'n1', dsn := 'host=<n1_ip_address> port=<n1_port> dbname=<db_name>');
On
n2
:SELECT spock.node_create (node_name := 'n2', dsn := 'host=<n2_ip_address> port=<n2_port> =<db_name>');
-
On
n1
, use thespock.repset_add_all_tables
command to add the tables in thepublic
schema to thedefault
replication set. If you are working in another schema, customize this command as needed:SELECT spock.repset_add_all_tables('default', ARRAY['public']);
-
On n2, use the
spock.sub_create
command to create the subscription between n2 and n1; the name of the subscription issub_n2_n1
:SELECT spock.sub_create (subscription_name := 'sub_n2_n1', provider_dsn := 'host=<n1_ip_address> port=<n1 port> dbname=<db_name>');
SELECT spock.sub_wait_for_sync('sub_n2_n1');
-
On
n1
, create a corresponding subscription ton2
namedsub_n1_n2
:SELECT spock.sub_create (subscription_name := 'sub_n1_n2', subscriber_dsn := 'host=<n2_ip_address> port=<n2_port> dbname=<db_name>');
-
To ensure that modifications to your DDL statements are automatically replicated, connect to each node with a Postgres client and invoke the following SQL commands:
ALTER SYSTEM SET spock.enable_ddl_replication=on;
ALTER SYSTEM SET spock.include_ddl_repset=on;
ALTER SYSTEM SET spock.allow_ddl_from_functions=on;
SELECT pg_reload_conf();
-
Then, check the status of each node:
SELECT * FROM spock.node;
node_id | node_name | location | country | info
---------+-------------+----------+---------+------
22201 | subscriber1 | | |
53107 | provider1 | | |
(2 rows)
SELECT * FROM spock.sub_show_status();
subscription_name | status | provider_node | provider_dsn | slot_name | replication_sets | forward_origins
-------------------+-------------+---------------+------------------------------------------+--------------------------------------+---------------------------------------+-----------------
subscription1 | replicating | provider1 | host=localhost port=5432 dbname=postgres | spk_postgres_provider1_subscription1 | {default,default_insert_only,ddl_sql} |
(1 row)
A simple test to check that your system is replicating is to connect to the Postgres server on n1
and add an object (like a table), and then confirm that it is available on n2
. Similarly, you can create an object on n2
, and confirm that it has been created on n1
.