|
| 1 | +--- |
| 2 | +title: "PostgreSQL read-only replication" |
| 3 | +sidebarTitle: "Read-only replication" |
| 4 | +description: Configure and access read-only PostgreSQL replicas to ease the load on a primary database. |
| 5 | +--- |
| 6 | + |
| 7 | +You can improve the performance of read-heavy applications by defining read-only replicas of your PostgreSQL database and then connecting your applications to those replicas. |
| 8 | + |
| 9 | +Examples of read-heavy applications include: |
| 10 | +- Listing pages or dashboards |
| 11 | +- Reporting or analytics jobs |
| 12 | +- Background jobs that frequently query data |
| 13 | + |
| 14 | +{{< note theme="info" title="Note" >}} |
| 15 | +- **Replication is asynchronous**: Delays of a few milliseconds might occur between writes on the primary database and reads on the replica database. |
| 16 | +- **Replicas are read-only**: This restriction ensures data consistency and integrity. Attempts to modify data will result in an SQL error. |
| 17 | +{{< /note >}} |
| 18 | + |
| 19 | +### Replica scope and sharing services {#replica-scope-sharing-services} |
| 20 | +PostgreSQL services (which provide access to databases and replicas) defined in a project cannot be accessed by or shared with applications in other projects. |
| 21 | + |
| 22 | + |
| 23 | + |
| 24 | +## 1. Configure the primary and replica services |
| 25 | + |
| 26 | +The following code fragment defines two MariaDB services: a primary and a replica. You can use this fragment as a template by copying it into your `services.yaml` or `application.yaml` file. |
| 27 | + |
| 28 | +Be sure to: |
| 29 | +- Replace `<VERSION>` with the [supported PostgreSQL version](/add-services/postgresql/_index.md#supported-versions) that you need. Use the same version number for the primary and replica services. |
| 30 | +- **Important:** Use `replicator` as the endpoint name when you define the replica service. This is a special endpoint name that the replica service uses to connect to the database. |
| 31 | + |
| 32 | +```yaml {configFile="services"} |
| 33 | +services: |
| 34 | + db: |
| 35 | + type: postgresql:<VERSION> |
| 36 | + configuration: |
| 37 | + extensions: |
| 38 | + - postgis |
| 39 | + endpoints: |
| 40 | + replicator: |
| 41 | + replication: true |
| 42 | + |
| 43 | + db-replica1: |
| 44 | + type: postgres-replica:<VERSION> |
| 45 | + configuration: |
| 46 | + endpoints: |
| 47 | + postgresql: |
| 48 | + default_database: main |
| 49 | + extensions: |
| 50 | + - postgis |
| 51 | + relationships: |
| 52 | + primary: db:replicator # Do not change the name `primary`. The service expects to receive this name. |
| 53 | + |
| 54 | + db-replica2: |
| 55 | + type: postgres-replica:<VERSION> |
| 56 | + configuration: |
| 57 | + endpoints: |
| 58 | + postgresql: |
| 59 | + default_database: main |
| 60 | + extensions: |
| 61 | + - postgis |
| 62 | + relationships: |
| 63 | + primary: db:replicator # Do not change the name `primary`. The service expects to receive this name. |
| 64 | +``` |
| 65 | +
|
| 66 | +
|
| 67 | +### How it works |
| 68 | +
|
| 69 | +Using the sample code fragment above: |
| 70 | +
|
| 71 | +1. After you define the replicator endpoints, the primary service creates a `replicator` user that has permission to replicate the database. You must specify `replicator` as the endpoint name, as described at the start of this topic. |
| 72 | + |
| 73 | + ```yaml |
| 74 | + endpoints: |
| 75 | + replicator: |
| 76 | + replication: true |
| 77 | + ``` |
| 78 | + |
| 79 | +2. In the replica services (in this example, db-replica1 and db-replica2), defining the relationship `primary: db:replicator` ensures that the service can connect to the primary database as the `replicator` user. |
| 80 | + |
| 81 | + ```yaml |
| 82 | + relationships: |
| 83 | + primary: db:replicator |
| 84 | + ``` |
| 85 | + |
| 86 | +The `db-replica1` and `db-replica2` replica services continuously stream data from the primary endpoint, maintaining a read-only copy of the primary database content. Write operations are not permitted on the replicas. |
| 87 | + |
| 88 | + |
| 89 | +## 2. Define the relationship between the application and the replicas |
| 90 | + |
| 91 | +Even if your application won't access the replication endpoint, you must expose the endpoint to an application as a relationship so that you can connect to it over SSH. |
| 92 | + |
| 93 | +Add a new relationship to your application container, as shown below: |
| 94 | + |
| 95 | +```yaml {configFile="app"} |
| 96 | +name: myapp |
| 97 | +
|
| 98 | +[...] |
| 99 | +
|
| 100 | +# Relationships enable an app container's access to a service. |
| 101 | +relationships: |
| 102 | + # More information: https://fixed.docs.upsun.com/anchors/fixed/app/reference/relationships/ |
| 103 | + database: |
| 104 | + service: db |
| 105 | + endpoint: main |
| 106 | + database-readonly: |
| 107 | + service: db-replica |
| 108 | +``` |
0 commit comments