|
| 1 | +--- |
| 2 | +title: Setting up logical replication as a publisher in PostgreSQL |
| 3 | +description: Learn how to set up and use logical replication as a publisher in PostgreSQL |
| 4 | +tags: postgresql logical replication publisher migration database |
| 5 | +dates: |
| 6 | + validation: 2025-08-25 |
| 7 | + posted: 2025-02-20 |
| 8 | +--- |
| 9 | +import Requirements from '@macros/iam/requirements.mdx' |
| 10 | + |
| 11 | +The logical replication of databases as a publisher is available with [PostgreSQL 17](/managed-databases-for-postgresql-and-mysql/reference-content/pg-version-updates#postgresql-17), which is supported in Scaleway's Managed Databases for PostgreSQL. |
| 12 | + |
| 13 | +The feature allows you to replicate data from a managed PostgreSQL to another Database Instance (a Managed PostgreSQL in another region, for example). |
| 14 | + |
| 15 | +Replication slots can be created with the `failover` flag, which ensures that replication slots survive failovers. When a secondary node is promoted to primary, the replication slot is automatically available on the new main node. |
| 16 | + |
| 17 | +<Requirements /> |
| 18 | + |
| 19 | +- A Scaleway account logged into the [console](https://console.scaleway.com) |
| 20 | +- [Owner](/iam/concepts/#owner) status or [IAM permissions](/iam/concepts/#permission) allowing you to perform actions in the intended Organization |
| 21 | +- A [Database Instance](/managed-databases-for-postgresql-and-mysql/how-to/create-a-database/) running PostgreSQL 17 |
| 22 | + |
| 23 | +## Configuring advanced settings and user rights |
| 24 | + |
| 25 | +As the service uses physical replication to provide High Availability, some parameters must be enabled to allow the logical replication to remain active after the promotion of a secondary node, without disturbing the HA setup. It is essential to ensure these setting are enabled as even Database Instances with in standalone mode can be replaced with temporary replicas. |
| 26 | + |
| 27 | +The [replication slot](https://www.postgresql.org/docs/17/logicaldecoding-explanation.html#LOGICALDECODING-REPLICATION-SLOTS) is an important part of the logical replication. Each subscription receives changes via one replication slot created on the "publishing" node. You have one replication slot available per logical database. |
| 28 | + |
| 29 | +To use replication, users must also have the corresponding rights. |
| 30 | + |
| 31 | +Follow the steps in the [How to configure advanced settings](/managed-databases-for-postgresql-and-mysql/how-to/configure-advanced-settings) documentation page to configure the following settings: |
| 32 | + |
| 33 | +To enable logical replication, you must: |
| 34 | + |
| 35 | +- Enable the `rdb.enable_logical_replication` setting. This automatically changes the `wal_level` settings to `logical`. |
| 36 | +- Set `hot_standby_feedback` to `ON` |
| 37 | +- Set `sync_replication_slots` to `ON` |
| 38 | + |
| 39 | +Follow the steps in the [How to manage users](/managed-databases-for-postgresql-and-mysql/how-to/manage-users) documentation page to attribute user rights. |
| 40 | + |
| 41 | +To create publications and replication slots, the `replication_user` must: |
| 42 | + |
| 43 | +- Either be an admin user (`rdb_admin`) |
| 44 | +- Or be granted the following rights from an `rdb_admin`: |
| 45 | + - `ALTER replication_user with REPLICATION` |
| 46 | + - `GRANT CREATE ON DATABASE my_database TO my_replication_user;` |
| 47 | + |
| 48 | +## Setting up logical replication |
| 49 | + |
| 50 | +We use an example scenario to show how logical replication can be set up. |
| 51 | + |
| 52 | +1. Create the table and publication on the publisher database. |
| 53 | + ```sql |
| 54 | + CREATE TABLE mytable (id INTEGER PRIMARY KEY, val TEXT); |
| 55 | + CREATE PUBLICATION pub FOR TABLE mytable; |
| 56 | + ``` |
| 57 | +2. Insert a sample row into the table. This ensures there's data to test the replication with. |
| 58 | + ```sql |
| 59 | + INSERT INTO mytable VALUES (1, 'foo'); |
| 60 | + ``` |
| 61 | +3. Create the same table structure on the subscriber database. Leave the table empty, as data will be copied into it upon subscription. |
| 62 | + ```sql |
| 63 | + CREATE TABLE mytable (id INTEGER PRIMARY KEY, val TEXT); |
| 64 | + ``` |
| 65 | +4. Create a subscription. Two methods are available: |
| 66 | + - **Direct subscription with failover** - use this method if your environment supports the failover option in `CREATE SUBSCRIPTION` |
| 67 | + - **Creating a replication slot manually on the publisher** - |
| 68 | + |
| 69 | + <Tabs> |
| 70 | + <TabsTab label="Set up direct subscription"> |
| 71 | + ```sql |
| 72 | + CREATE SUBSCRIPTION sub CONNECTION 'host=myhost port=myport user=myuser dbname=mydb password=mypassword' PUBLICATION pub WITH (failover); |
| 73 | + ``` |
| 74 | + </TabsTab> |
| 75 | + <TabsTab label="Create replication slot manually"> |
| 76 | + Some environments do not allow `CREATE SUBSCRIPTION` to auto-create slots due to permissions or configuration. In this case, you can create a slot with failover manually. |
| 77 | + 1. Create a replication slot on the publisher database. |
| 78 | + ```sql |
| 79 | + SELECT pg_create_logical_replication_slot('sub', 'pgoutput', false, false, true); |
| 80 | + ``` |
| 81 | + <Message type="note"> |
| 82 | + The last `true` in the command above enables the `failover` flag. |
| 83 | + </Message> |
| 84 | + 2. Create the subscription without creating a slot. |
| 85 | + ```sql |
| 86 | + CREATE SUBSCRIPTION sub CONNECTION 'host=myhost port=myport user=myuser dbname=mydb password=mypassword' PUBLICATION pub WITH (enabled=true, create_slot=false, slot_name='sub'); |
| 87 | + ``` |
| 88 | + <Message type="note"> |
| 89 | + Refer to the [PostgreSQL documentation](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-REPLICATION) for more information about `pg_create_logical_replication_slot()`. |
| 90 | + </Message> |
| 91 | + </TabsTab> |
| 92 | + </Tabs> |
| 93 | + |
| 94 | +5. Query the publisher table in the subscriber to test the replication. |
| 95 | + ```sql |
| 96 | + SELECT * FROM mytable; |
| 97 | + ``` |
| 98 | + |
| 99 | +## Limitations |
| 100 | + |
| 101 | +- 100 replication slots are available for each Database Instance. |
| 102 | +- 25 out of the 100 slots are reserved for Scaleway's internal systems. |
| 103 | +- During the synchronization phase, 2 or more slots might be needed for a subscription. |
| 104 | + <Message type="important"> |
| 105 | + - If you need more than 50 replication slots, [create a support ticket](https://console.scaleway.com/support). |
| 106 | + - If the limit is exceeded, your Managed Database service may become compromised. |
| 107 | + </Message> |
| 108 | + |
| 109 | + <Message type="tip"> |
| 110 | + Run the following command to get a list of your replication slots: |
| 111 | + ```sql |
| 112 | + SELECT * FROM pg_replication_slots where slot_type = 'logical'; |
| 113 | + ``` |
| 114 | + And the following command to check publications: |
| 115 | + ```sql |
| 116 | + SELECT * from pg_publication; |
| 117 | + ``` |
| 118 | + </Message> |
| 119 | + |
| 120 | +- If a logical replication is not active but still consumed by a subscription or other tool, PostgreSQL WAL files will accumulate in the primary node, filling up storage. In the worst case scenario, your database can be set to read only mode (check disk full section). |
| 121 | + <Message type="tip"> |
| 122 | + - We recommend you delete any replications that are no longer used. |
| 123 | + - If a logical replication is inactive for 24h, it will be automatically removed. |
| 124 | + </Message> |
0 commit comments