pglogical setup
In certain cases, you can't do a full postgres replication to another instance, or you prefer a fine-grained control on what to replicate, pglogical is one way to achieve partial replication, albeit this requires more manual setup.
Below are steps I used to do a pglogical replication from AWS RDS to on-premise database.
Note: If a subscriber (from the above example, the on-premise database) is offline, postgres WAL would balloon up. You'll have to remove all traces of pglogical extension, including uninstalling pglogical extension, then reinitialize everything again to resolve the problem.
1. ON PROVIDER INSTANCE: Create a role for subscriber to fetch data from provider instance
WITH ENCRYPTED PASSWORD $SUBSCRIBER_ROLE_PASSWORD;
$SUBSCRIBER_ROLE_NAME -- RDS specific
rds_superuser TO $SUBSCRIBER_ROLE_NAME;
CONNECT ON DATABASE $DATABASE_TO_BE_REPLICATED TO $SUBSCRIBER_ROLE_NAME;
USAGE ON SCHEMA public TO $SUBSCRIBER_ROLE_NAME;
SELECT ON ALL TABLES IN SCHEMA public TO $SUBSCRIBER_ROLE_NAME;
-- RDS specific
rds_replication TO $SUBSCRIBER_ROLE_NAME;
2. ON PROVIDER INSTANCE: Init pglogical extension
CREATE EXTENSION pglogical;
ALL ON SCHEMA pglogical TO $SUBSCRIBER_ROLE_NAME;
3. ON PROVIDER INSTANCE: Define provider node
SELECT pglogical.create_node(
node_name := 'provider',
dsn := 'host=$PROVIDER_INSTANCE_HOSTNAME port=5432 user=$SUBSCRIBER_ROLE_NAME dbname=$DATABASE_TO_BE_REPLICATED password=$SUBSCRIBER_ROLE_PASSWORD'
);
4. ON PROVIDER INSTANCE: Define tables to be replicated
select pglogical.create_replication_set('replication_set');
select pglogical.replication_set_add_table(
set_name := 'replication_set',
relation := '$TABLE_NAME',
synchronize_data := true
);
5. ON SUBSCRIBER INSTANCE: Init pglogical extension
CREATE EXTENSION pglogical;
6. ON SUBSCRIBER INSTANCE: Define table schemas for replicated tables
pglogical does not transmit schema definition. Basically you need to do the equivalent of schema migration.
$TABLE_NAME
(
subject_id varchar not null,
foo integer,
bar varchar,
primary key (id)
);
-- also define indexes as well,
7. ON SUBSCRIBER INSTANCE: Define subscriber node
$SUBSCRIBER_INSTANCE_HOSTNAME
can be localhost
SELECT pglogical.create_node(
node_name := 'subscriber',
dsn := 'host=$SUBSCRIBER_INSTANCE_HOSTNAME port=5432 user=$SUBSCRIBER_INSTANCE_ROLE_NAME dbname=$DATABASE_TO_BE_REPLICATED password=$SUBSCRIBER_INSTANCE_ROLE_PASSWORD'
);
8. ON SUBSCRIBER INSTANCE: Define subscription
SELECT pglogical.create_subscription(
subscription_name := 'aws_sub',
provider_dsn := 'host=$PROVIDER_INSTANCE_HOSTNAME port=5432 dbname=$DATABASE_TO_BE_REPLICATED user=$SUBSCRIBER_ROLE_NAME password=$SUBSCRIBER_ROLE_PASSWORD',
replication_sets := ARRAY['replication_set']
);
9. ON PROVIDER INSTANCE: Verify that pglogical is working
SELECT
subscription_name,
status
FROM
pglogical.show_subscription_status ;