# API REST Patroni

> Référence des points de terminaison de l'API REST de Patroni et de leurs comportements opérationnels.

---

Index LLMS : [llms.txt](/fr/llms.txt)

---

<a id="rest_api"></a>
Patroni dispose d'une API REST riche, utilisée par Patroni lui-même lors de la course au leader, par l'outil [patronictl](/fr/docs/patroni/patronictl#patronictl) afin d'effectuer des basculements, des basculements planifiés, des réinitialisations, des redémarrages ou des rechargements, par HAProxy ou tout autre équilibreur de charge pour effectuer des vérifications de santé HTTP, et bien entendu également utilisée pour la surveillance. Ci-dessous figure la liste des points de terminaison de l'API REST de Patroni.

--------

## Points de terminaison de vérification de santé {#health-check-endpoints}

Pour toutes les requêtes de vérification de santé `GET`, Patroni renvoie un document JSON indiquant l'état du nœud, accompagné du code d'état HTTP. Si vous ne souhaitez pas ou n'avez pas besoin du document JSON, vous pouvez envisager d'utiliser la méthode `HEAD` ou `OPTIONS` au lieu de `GET`.

- Les requêtes suivantes vers l'API REST de Patroni renvoient le code d'état HTTP **200** uniquement lorsque le nœud Patroni fonctionne en tant que primaire avec verrou de leader :

  - `GET /`
  - `GET /primary`
  - `GET /read-write`

- `GET /standby-leader` : renvoie le code d’état HTTP **200** uniquement lorsque le nœud Patroni est en cours d’exécution en tant que leader dans un [cluster de secours](/fr/docs/patroni/standby_cluster#standby_cluster).

- `GET /leader` : renvoie le code d’état HTTP **200** lorsque le nœud Patroni détient le verrou leader. Contrairement à `GET /primary` et à `GET /standby-leader`, cette vérification ne dépend pas du fait que PostgreSQL s’exécute en tant que `primary` ou `standby_leader`.

- `GET /replica` : point de terminaison de vérification de santé de la réplique. Il renvoie le code d’état HTTP **200** uniquement lorsque le nœud Patroni est dans l’état `running`, que son rôle est `replica` et que l’étiquette `noloadbalance` n’est pas définie.

- `GET /replica?replication_state=<required state>` : point de contrôle de réplique. En plus des vérifications effectuées par `replica`, il vérifie également que l'état de réplication correspond à celui requis. Principalement utile avec `replication_state=streaming`, afin d'exclure les répliques encore en cours de rattrapage lors d'une récupération depuis les archives.

- `GET /replica?lag=<max-lag>` : point de contrôle de réplique. En plus des vérifications effectuées par `replica`, il vérifie également le retard de réplication et renvoie le code d’état **200** uniquement lorsque ce retard est inférieur à la valeur spécifiée. La clé cluster.last_leader_operation provenant du DCS est utilisée pour la position WAL du leader et le calcul du retard sur la réplique, pour des raisons de performance. max-lag peut être spécifié en octets (entier) ou sous forme lisible par l’humain, par exemple 16kB, 64MB, 1GB.

  - `GET /replica?lag=1048576`
  - `GET /replica?lag=1024kB`
  - `GET /replica?lag=10MB`
  - `GET /replica?lag=1GB`

- `GET /replica?tag_key1=value1&tag_key2=value2` : point de contrôle de réplique. En outre, il vérifie également les étiquettes définies par l'utilisateur `key1` et `key2` ainsi que leurs valeurs respectives dans la section **tags** de la configuration YAML. Si une étiquette n'est pas définie pour une instance, ou si la valeur dans la configuration YAML ne correspond pas à la valeur demandée, le code d'état HTTP 503 est renvoyé.

  Dans les requêtes suivantes, comme nous vérifions l'état de leader ou de standby-leader, Patroni ne prend pas en compte les étiquettes définies par l'utilisateur, qui seront ignorées.

  - `GET /?tag_key1=value1&tag_key2=value2`
  - `GET /leader?tag_key1=value1&tag_key2=value2`
  - `GET /primary?tag_key1=value1&tag_key2=value2`
  - `GET /read-write?tag_key1=value1&tag_key2=value2`
  - `GET /standby_leader?tag_key1=value1&tag_key2=value2`
  - `GET /standby-leader?tag_key1=value1&tag_key2=value2`

- `GET /read-only` : comme le point de terminaison précédent, mais inclut également le primaire.

- `GET /synchronous` ou `GET /sync` : renvoie le code d’état HTTP **200** uniquement lorsque le nœud Patroni fonctionne en réplique synchrone.

- `GET /read-only-sync` : comme le point de terminaison précédent, mais inclut également le primaire.

- `GET /quorum` : renvoie le code d'état HTTP **200** uniquement lorsque ce nœud Patroni est répertorié comme nœud de quorum dans `synchronous_standby_names` sur le primaire.

- `GET /read-only-quorum` : comme le point de terminaison précédent, mais inclut également le primaire.

- `GET /asynchronous` ou `GET /async` : renvoie le code d’état HTTP **200** uniquement lorsque le nœud Patroni fonctionne en réplique asynchrone.

- `GET /asynchronous?lag=<max-lag>` ou `GET /async?lag=<max-lag>` : point de contrôle de réplique asynchrone. En plus des vérifications effectuées par `asynchronous` ou `async`, il vérifie également le retard de réplication et renvoie le code d’état **200** uniquement lorsque ce retard est inférieur à la valeur spécifiée. La clé cluster.last_leader_operation provenant du DCS est utilisée pour la position WAL du leader et le calcul du retard sur la réplique, pour des raisons de performance. max-lag peut être spécifié en octets (entier) ou sous forme lisible par l’humain, par exemple 16kB, 64MB, 1GB.

  - `GET /async?lag=1048576`
  - `GET /async?lag=1024kB`
  - `GET /async?lag=10MB`
  - `GET /async?lag=1GB`

- `GET /health` : renvoie le code d'état HTTP **200** uniquement lorsque PostgreSQL est en cours d'exécution.

- `GET /liveness` : renvoie le code d'état HTTP **200** si la boucle de battement de cœur Patroni fonctionne correctement, et **503** si la dernière exécution remonte à plus de `ttl` secondes sur le serveur primaire ou à plus de `2*ttl` secondes sur la réplique. Peut être utilisé pour `livenessProbe`.

- `GET /readiness?lag=<max-lag>&mode=apply|write` : renvoie le code d’état HTTP **200** lorsque le nœud Patroni fonctionne en tant que leader ou lorsque PostgreSQL est actif, en réplication et pas trop en retard par rapport au leader. Le paramètre lag définit le retard maximal autorisé pour une réplique, avec une valeur par défaut de `maximum_lag_on_failover`. Le retard peut être spécifié en octets ou en valeurs lisibles par l’humain, par exemple 16kB, 64MB ou 1GB. Le paramètre mode indique si le WAL doit être rejoué (apply) ou simplement reçu (write). La valeur par défaut est apply.

Lorsqu’il est utilisé comme Kubernetes `readinessProbe`, il garantit que les nouveaux pods démarrés ne deviennent prêts qu’après avoir rattrapé le leader. Cela, combiné à un PodDisruptionBudget, protège contre une terminaison prématurée du leader lors d’un redémarrage progressif des nœuds. Il garantit également que les répliques incapables de suivre la réplication ne traitent pas le trafic en lecture seule. Ce point de terminaison peut être utilisé pour `readinessProbe` lorsque l’utilisation des endpoints Kubernetes pour les élections de leader n’est pas possible (OpenShift).

Le point de terminaison `liveness` est très léger et n'exécute aucune requête SQL. Les sondes devraient être configurées de manière à commencer à échouer environ au moment où la clé leader expire. Avec la valeur par défaut de `ttl`, qui est `30s`, les sondes devraient ressembler à l'exemple suivant :

```yaml
readinessProbe:
  httpGet:
    scheme: HTTP
    path: /readiness
    port: 8008
  initialDelaySeconds: 3
  periodSeconds: 10
  timeoutSeconds: 5
  successThreshold: 1
  failureThreshold: 3
livenessProbe:
  httpGet:
    scheme: HTTP
    path: /liveness
    port: 8008
  initialDelaySeconds: 3
  periodSeconds: 10
  timeoutSeconds: 5
  successThreshold: 1
  failureThreshold: 3
```

--------

## Point de terminaison de surveillance {#monitoring-endpoint}

Le `GET /patroni` est utilisé par Patroni lors de la course au leader. Il peut également être utilisé par votre système de surveillance. Le document JSON produit par ce point de terminaison a la même structure que le JSON produit par les points de terminaison de vérification de santé.

**Exemple** : un cluster sain

``` bash
$ curl -s http://localhost:8008/patroni | jq .
{
  "state": "running",
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "role": "primary",
  "server_version": 160004,
  "xlog": {
    "location": 67395656
  },
  "timeline": 1,
  "replication": [
    {
      "usename": "replicator",
      "application_name": "patroni2",
      "client_addr": "10.89.0.6",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    },
    {
      "usename": "replicator",
      "application_name": "patroni3",
      "client_addr": "10.89.0.2",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    }
  ],
  "dcs_last_seen": 1692356718,
  "tags": {
    "clonefrom": true
  },
  "database_system_identifier": "7268616322854375442",
  "patroni": {
    "version": "4.0.0",
    "scope": "demo",
    "name": "patroni1"
  }
}
```

**Exemple** : un cluster déverrouillé

``` bash
$ curl -s http://localhost:8008/patroni  | jq .
{
  "state": "running",
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "role": "replica",
  "server_version": 160004,
  "xlog": {
    "received_location": 67419744,
    "replayed_location": 67419744,
    "replayed_timestamp": null,
    "paused": false
  },
  "timeline": 1,
  "replication": [
    {
      "usename": "replicator",
      "application_name": "patroni2",
      "client_addr": "10.89.0.6",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    },
    {
      "usename": "replicator",
      "application_name": "patroni3",
      "client_addr": "10.89.0.2",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    }
  ],
  "cluster_unlocked": true,
  "dcs_last_seen": 1692356928,
  "tags": {
    "clonefrom": true
  },
  "database_system_identifier": "7268616322854375442",
  "patroni": {
    "version": "4.0.0",
    "scope": "demo",
    "name": "patroni1"
  }
}
```

**Exemple :** Un cluster déverrouillé avec le [mode failsafe du DCS](/fr/docs/patroni/dcs_failsafe_mode#dcs_failsafe_mode) activé

``` bash
$ curl -s http://localhost:8008/patroni  | jq .
{
  "state": "running",
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "role": "replica",
  "server_version": 160004,
  "xlog": {
    "location": 67420024
  },
  "timeline": 1,
  "replication": [
    {
      "usename": "replicator",
      "application_name": "patroni2",
      "client_addr": "10.89.0.6",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    },
    {
      "usename": "replicator",
      "application_name": "patroni3",
      "client_addr": "10.89.0.2",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    }
  ],
  "cluster_unlocked": true,
  "failsafe_mode_is_active": true,
  "dcs_last_seen": 1692356928,
  "tags": {
    "clonefrom": true
  },
  "database_system_identifier": "7268616322854375442",
  "patroni": {
    "version": "4.0.0",
    "scope": "demo",
    "name": "patroni1"
  }
}
```

**Exemple :** Un cluster avec le mode [pause](/fr/docs/patroni/pause#pause) activé

``` bash
$ curl -s http://localhost:8008/patroni  | jq .
{
  "state": "running",
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "role": "replica",
  "server_version": 160004,
  "xlog": {
    "location": 67420024
  },
  "timeline": 1,
  "replication": [
    {
      "usename": "replicator",
      "application_name": "patroni2",
      "client_addr": "10.89.0.6",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    },
    {
      "usename": "replicator",
      "application_name": "patroni3",
      "client_addr": "10.89.0.2",
      "state": "streaming",
      "sync_state": "async",
      "sync_priority": 0
    }
  ],
  "pause": true,
  "dcs_last_seen": 1724874295,
  "tags": {
    "clonefrom": true
  },
  "database_system_identifier": "7268616322854375442",
  "patroni": {
    "version": "4.0.0",
    "scope": "demo",
    "name": "patroni1"
  }
}
```

Récupérez les métriques Patroni au format Prometheus via le point de terminaison `GET /metrics`.

``` bash
$ curl http://localhost:8008/metrics

# HELP patroni_version Patroni semver without periods. \
# TYPE patroni_version gauge
patroni_version{scope="batman",name="patroni1"} 040000
# HELP patroni_postgres_running Value is 1 if Postgres is running, 0 otherwise.
# TYPE patroni_postgres_running gauge
patroni_postgres_running{scope="batman",name="patroni1"} 1
# HELP patroni_postmaster_start_time Epoch seconds since Postgres started.
# TYPE patroni_postmaster_start_time gauge
patroni_postmaster_start_time{scope="batman",name="patroni1"} 1724873966.352526
# HELP patroni_primary Value is 1 if this node is the leader, 0 otherwise.
# TYPE patroni_primary gauge
patroni_primary{scope="batman",name="patroni1"} 1
# HELP patroni_xlog_location Current location of the Postgres transaction log, 0 if this node is not the leader.
# TYPE patroni_xlog_location counter
patroni_xlog_location{scope="batman",name="patroni1"} 22320573386952
# HELP patroni_standby_leader Value is 1 if this node is the standby_leader, 0 otherwise.
# TYPE patroni_standby_leader gauge
patroni_standby_leader{scope="batman",name="patroni1"} 0
# HELP patroni_replica Value is 1 if this node is a replica, 0 otherwise.
# TYPE patroni_replica gauge
patroni_replica{scope="batman",name="patroni1"} 0
# HELP patroni_sync_standby Value is 1 if this node is a sync standby replica, 0 otherwise.
# TYPE patroni_sync_standby gauge
patroni_sync_standby{scope="batman",name="patroni1"} 0
# HELP patroni_quorum_standby Value is 1 if this node is a quorum standby replica, 0 otherwise.
# TYPE patroni_quorum_standby gauge
patroni_quorum_standby{scope="batman",name="patroni1"} 0
# HELP patroni_xlog_received_location Current location of the received Postgres transaction log, 0 if this node is not a replica.
# TYPE patroni_xlog_received_location counter
patroni_xlog_received_location{scope="batman",name="patroni1"} 0
# HELP patroni_xlog_replayed_location Current location of the replayed Postgres transaction log, 0 if this node is not a replica.
# TYPE patroni_xlog_replayed_location counter
patroni_xlog_replayed_location{scope="batman",name="patroni1"} 0
# HELP patroni_xlog_replayed_timestamp Current timestamp of the replayed Postgres transaction log, 0 if null.
# TYPE patroni_xlog_replayed_timestamp gauge
patroni_xlog_replayed_timestamp{scope="batman",name="patroni1"} 0
# HELP patroni_xlog_paused Value is 1 if the Postgres xlog is paused, 0 otherwise.
# TYPE patroni_xlog_paused gauge
patroni_xlog_paused{scope="batman",name="patroni1"} 0
# HELP patroni_postgres_streaming Value is 1 if Postgres is streaming, 0 otherwise.
# TYPE patroni_postgres_streaming gauge
patroni_postgres_streaming{scope="batman",name="patroni1"} 1
# HELP patroni_postgres_in_archive_recovery Value is 1 if Postgres is replicating from archive, 0 otherwise.
# TYPE patroni_postgres_in_archive_recovery gauge
patroni_postgres_in_archive_recovery{scope="batman",name="patroni1"} 0
# HELP patroni_postgres_server_version Version of Postgres (if running), 0 otherwise.
# TYPE patroni_postgres_server_version gauge
patroni_postgres_server_version{scope="batman",name="patroni1"} 160004
# HELP patroni_cluster_unlocked Value is 1 if the cluster is unlocked, 0 if locked.
# TYPE patroni_cluster_unlocked gauge
patroni_cluster_unlocked{scope="batman",name="patroni1"} 0
# HELP patroni_failsafe_mode_is_active Value is 1 if failsafe mode is active, 0 otherwise.
# TYPE patroni_failsafe_mode_is_active gauge
patroni_failsafe_mode_is_active{scope="batman",name="patroni1"} 0
# HELP patroni_failsafe_mode_enabled Value is 1 if failsafe_mode is enabled, 0 otherwise.
# TYPE patroni_failsafe_mode_enabled gauge
patroni_failsafe_mode_enabled{scope="batman",name="patroni1"} 0
# HELP patroni_failsafe_member Value is 1 if this node is a member of failsafe, 0 otherwise.
# TYPE patroni_failsafe_member gauge
patroni_failsafe_member{scope="batman",name="patroni1"} 0
# HELP patroni_postgres_timeline Postgres timeline of this node (if running), 0 otherwise.
# TYPE patroni_postgres_timeline gauge
patroni_postgres_timeline{scope="batman",name="patroni1"} 24
# HELP patroni_dcs_last_seen Epoch timestamp when DCS was last contacted successfully by Patroni.
# TYPE patroni_dcs_last_seen gauge
patroni_dcs_last_seen{scope="batman",name="patroni1"} 1724874235
# HELP patroni_pending_restart Value is 1 if the node needs a restart, 0 otherwise.
# TYPE patroni_pending_restart gauge
patroni_pending_restart{scope="batman",name="patroni1"} 1
# HELP patroni_is_paused Value is 1 if auto failover is disabled, 0 otherwise.
# TYPE patroni_is_paused gauge
patroni_is_paused{scope="batman",name="patroni1"} 1
# HELP patroni_postgres_state Numeric representation of Postgres state.
# Values: 0=initdb, 1=initdb_failed, 2=custom_bootstrap, 3=custom_bootstrap_failed, 4=creating_replica, 5=running, 6=starting, 7=bootstrap_starting, 8=start_failed, 9=restarting, 10=restart_failed, 11=stopping, 12=stopped, 13=stop_failed, 14=crashed
# TYPE patroni_postgres_state gauge
patroni_postgres_state{scope="batman",name="patroni1"} 5
# HELP patroni_failover_priority Failover priority of this node.
# TYPE patroni_failover_priority gauge
patroni_failover_priority{scope="batman",name="patroni1"} 1
```

### Valeurs d'état PostgreSQL {#postgresql-state-values}

La métrique `patroni_postgres_state` fournit une représentation numérique de l'état actuel de l'instance PostgreSQL. Cela est utile pour les systèmes de surveillance et d'alerte qui doivent suivre les changements d'état au fil du temps. Les valeurs numériques sont générées à l'aide de la méthode statique `PostgresqlState.get_metrics_description()`.

| Valeur | Nom d'état               | Description                          |
|-------|--------------------------|--------------------------------------|
| 0     | initdb                   | Initialisation du nouveau cluster    |
| 1     | initdb_failed            | Échec de l'initialisation du nouveau cluster |
| 2     | custom_bootstrap         | Exécution du script d'amorçage personnalisé |
| 3     | custom_bootstrap_failed  | Échec du script d'amorçage personnalisé |
| 4     | creating_replica         | Création d'une réplique à partir du primaire |
| 5     | running                  | PostgreSQL fonctionne normalement    |
| 6     | starting                 | PostgreSQL démarre                     |
| 7     | bootstrap_starting       | Démarrage après l'amorçage personnalisé |
| 8     | start_failed             | Échec du démarrage de PostgreSQL     |
| 9     | restarting               | PostgreSQL redémarre                   |
| 10    | restart_failed           | Échec du redémarrage de PostgreSQL   |
| 11    | stopping                 | PostgreSQL s'arrête                    |
| 12    | stopped                  | PostgreSQL est arrêté                  |
| 13    | stop_failed              | Échec de l'arrêt de PostgreSQL       |
| 14    | crashed                  | PostgreSQL a planté                    |

Valeurs d'état de PostgreSQL

> [!NOTE]
> Ces valeurs numériques sont fixes et ne changeront jamais afin de préserver la rétrocompatibilité avec les systèmes de surveillance existants. Si de nouveaux états sont ajoutés à l’avenir, ils seront affectés à de nouvelles valeurs numériques sans modifier les valeurs existantes.

--------

## Points de terminaison d'état du cluster {#cluster-status-endpoints}

- Le point de terminaison `GET /cluster` génère un document JSON décrivant la topologie et l’état actuels du cluster :

``` bash
$ curl -s http://localhost:8008/cluster | jq .
{
  "members": [
    {
      "name": "patroni1",
      "role": "leader",
      "state": "running",
      "api_url": "http://10.89.0.4:8008/patroni",
      "host": "10.89.0.4",
      "port": 5432,
      "timeline": 5,
      "tags": {
        "clonefrom": true
      }
    },
    {
      "name": "patroni2",
      "role": "replica",
      "state": "streaming",
      "api_url": "http://10.89.0.6:8008/patroni",
      "host": "10.89.0.6",
      "port": 5433,
      "timeline": 5,
      "tags": {
        "clonefrom": true
      },
      "receive_lag": 0,
      "receive_lsn": "0/4000060",
      "replay_lag": 0,
      "replay_lsn": "0/4000060",
      "lag": 0,
      "lsn": "0/4000060"
    }
  ],
  "scope": "demo",
  "scheduled_switchover": {
    "at": "2023-09-24T10:36:00+02:00",
    "from": "patroni1",
    "to": "patroni3"
  }
}
```

-  Le point de terminaison `GET /history` fournit une vue sur l'historique des basculements planifiés ou des basculements du cluster. Le format est très similaire au contenu des fichiers d'historique dans le répertoire `pg_wal`. La seule différence réside dans le champ horodatage, qui indique quand la nouvelle timeline a été créée.

``` bash
$ curl -s http://localhost:8008/history | jq .
[
  [
    1,
    25623960,
    "no recovery target specified",
    "2019-09-23T16:57:57+02:00"
  ],
  [
    2,
    25624344,
    "no recovery target specified",
    "2019-09-24T09:22:33+02:00"
  ],
  [
    3,
    25624752,
    "no recovery target specified",
    "2019-09-24T09:26:15+02:00"
  ],
  [
    4,
    50331856,
    "no recovery target specified",
    "2019-09-24T09:35:52+02:00"
  ]
]
```

<a id="config_endpoint"></a>

--------

## Point de terminaison de configuration {#config-endpoint}

`GET /config` : Obtenir la version actuelle de la configuration dynamique :

``` bash
$ curl -s http://localhost:8008/config | jq .
{
  "ttl": 30,
  "loop_wait": 10,
  "retry_timeout": 10,
  "maximum_lag_on_failover": 1048576,
  "postgresql": {
    "use_slots": true,
    "use_pg_rewind": true,
    "parameters": {
      "hot_standby": "on",
      "wal_level": "hot_standby",
      "max_wal_senders": 5,
      "max_replication_slots": 5,
      "max_connections": "100"
    }
  }
}
```

`PATCH /config` : Modifiez la configuration existante.

``` bash
$ curl -s -XPATCH -d \
    '{"loop_wait":5,"ttl":20,"postgresql":{"parameters":{"max_connections":"101"}}}' \
    http://localhost:8008/config | jq .
{
  "ttl": 20,
  "loop_wait": 5,
  "maximum_lag_on_failover": 1048576,
  "retry_timeout": 10,
  "postgresql": {
    "use_slots": true,
    "use_pg_rewind": true,
    "parameters": {
      "hot_standby": "on",
      "wal_level": "hot_standby",
      "max_wal_senders": 5,
      "max_replication_slots": 5,
      "max_connections": "101"
    }
  }
}
```

L'appel d'API REST ci-dessus met à jour la configuration existante et renvoie la configuration mise à jour.

Vérifions que le nœud a bien appliqué cette configuration. Tout d'abord, il devrait commencer à afficher des lignes de journal toutes les 5 secondes (loop_wait=5). Le changement de "max_connections" nécessite un redémarrage, donc le drapeau "pending_restart" devrait être affiché :

``` bash
$ curl -s http://localhost:8008/patroni | jq .
{
  "postmaster_start_time": "2024-08-28 19:39:26.352526+00:00",
  "xlog": {
    "location": 2197818976
  },
  "timeline": 1,
  "dcs_last_seen": 1724874545,
  "database_system_identifier": "7408277255830290455",
  "pending_restart": true,
  "pending_restart_reason": {
    "max_connections": {
      "old_value": "100",
      "new_value": "101"
    }
  },
  "patroni": {
    "version": "4.0.0",
    "scope": "batman",
    "name": "patroni1"
  },
  "state": "running",
  "role": "primary",
  "server_version": 160004
}
```

Suppression des paramètres :

Si vous souhaitez supprimer (réinitialiser) un paramètre, il suffit d'envoyer un PATCH avec la valeur `null` :

``` bash
$ curl -s -XPATCH -d \
    '{"postgresql":{"parameters":{"max_connections":null}}}' \
    http://localhost:8008/config | jq .
{
  "ttl": 20,
  "loop_wait": 5,
  "retry_timeout": 10,
  "maximum_lag_on_failover": 1048576,
  "postgresql": {
    "use_slots": true,
    "use_pg_rewind": true,
    "parameters": {
      "hot_standby": "on",
      "unix_socket_directories": ".",
      "wal_level": "hot_standby",
      "max_wal_senders": 5,
      "max_replication_slots": 5
    }
  }
}
```

L'appel ci-dessus retire `postgresql.parameters.max_connections` de la configuration dynamique.

`PUT /config` : Il est également possible d'effectuer la réécriture complète d'une configuration dynamique existante de manière inconditionnelle :

``` bash
$ curl -s -XPUT -d \
    '{"maximum_lag_on_failover":1048576,"retry_timeout":10,"postgresql":{"use_slots":true,"use_pg_rewind":true,"parameters":{"hot_standby":"on","wal_level":"hot_standby","unix_socket_directories":".","max_wal_senders":5}},"loop_wait":3,"ttl":20}' \
    http://localhost:8008/config | jq .
{
  "ttl": 20,
  "maximum_lag_on_failover": 1048576,
  "retry_timeout": 10,
  "postgresql": {
    "use_slots": true,
    "parameters": {
      "hot_standby": "on",
      "unix_socket_directories": ".",
      "wal_level": "hot_standby",
      "max_wal_senders": 5
    },
    "use_pg_rewind": true
  },
  "loop_wait": 3
}
```

--------

## Points de terminaison de basculement planifié et de basculement {#switchover-and-failover-endpoints}

<a id="switchover_api"></a>

### Basculement planifié {#switchover}

Le point de terminaison `/switchover` ne fonctionne que lorsque le cluster est sain (un leader est présent). Il permet également de planifier l'exécution d'un basculement planifié à une heure donnée.

Lors de l'appel du point de terminaison `/switchover`, un candidat peut être spécifié mais n'est pas obligatoire, contrairement au point de terminaison `/failover`. Si aucun candidat n'est fourni, tous les nœuds éligibles du cluster participeront à la course au leader après la rétrogradation du leader.

Dans le corps JSON de la requête `POST`, vous devez spécifier le champ `leader`. Les champs `candidate` et `scheduled_at` sont facultatifs et peuvent être utilisés pour planifier l'exécution d'un basculement planifié à une heure précise.

Selon la situation, les requêtes peuvent renvoyer des codes d’état HTTP et des corps différents. Le code d’état **200** est retourné lorsque le basculement planifié ou le basculement s’est terminé avec succès. Si le basculement planifié a été correctement planifié, Patroni renvoie le code d’état HTTP **202**. En cas d’erreur, un code d’état d’erreur (l’un des codes **400**, **412** ou **503**) est retourné, accompagné de détails dans le corps de la réponse.

`DELETE /switchover` peut être utilisé pour supprimer le basculement planifié actuellement prévu.

**Exemple :** effectuer un basculement planifié vers n'importe quelle réplique saine

``` bash
$ curl -s http://localhost:8008/switchover -XPOST -d '{"leader":"postgresql1"}'
Successfully switched over to "postgresql2"
```

**Exemple :** effectuer un basculement planifié vers un nœud spécifique

``` bash
$ curl -s http://localhost:8008/switchover -XPOST -d \
    '{"leader":"postgresql1","candidate":"postgresql2"}'
Successfully switched over to "postgresql2"
```

**Exemple :** planifier un basculement planifié du leader vers n'importe quelle autre réplique saine du cluster à une heure précise.

``` bash
$ curl -s http://localhost:8008/switchover -XPOST -d \
    '{"leader":"postgresql0","scheduled_at":"2019-09-24T12:00+00"}'
Switchover scheduled
```

### Basculement {#failover}

Le point de terminaison `/failover` peut être utilisé pour effectuer un basculement manuel lorsque aucun nœud sain n'est disponible (par exemple, vers une réplique asynchrone si toutes les répliques synchrones ne sont pas suffisamment sains pour être promus). Toutefois, il n'existe aucune obligation pour un cluster de ne pas avoir de leader : le basculement peut également être exécuté sur un cluster sain.

Dans le corps JSON de la requête `POST`, vous devez spécifier le champ `candidate`. Si le champ `leader` est spécifié, un basculement planifié est déclenché à la place.

**Exemple :**

``` bash
$ curl -s http://localhost:8008/failover -XPOST -d '{"candidate":"postgresql1"}'
Successfully failed over to "postgresql1"
```

> [!WARNING]
> [Soyez très prudent](/fr/docs/patroni/rest_api#failover_healthcheck) lors de l'utilisation de ce point de terminaison, car cela peut entraîner une perte de données dans certaines situations. Dans la plupart des cas, [le point de terminaison de basculement planifié](/fr/docs/patroni/rest_api#switchover_api) répond aux besoins de l'administrateur.

Les points de terminaison `POST /switchover` et `POST /failover` sont utilisés par [patronictl_switchover](/fr/docs/patroni/patronictl#patronictl_switchover) et [patronictl_failover](/fr/docs/patroni/patronictl#patronictl_failover) respectivement.

`DELETE /switchover` est utilisé par [patronictl flush cluster-name switchover](/fr/docs/patroni/patronictl#patronictl_flush_parameters).

|                              | Basculement | Basculement planifié                  |
|------------------------------|----------|------------------------------------|
| Nécessite un leader spécifié | non      | oui                                |
| Nécessite un candidat spécifié | oui    | non                                |
| Peut être exécuté en pause   | oui      | oui (uniquement vers un candidat spécifique) |
| Peut être planifié           | non      | oui (si non en pause)              |

Comparaison entre basculement et basculement planifié

<a id="failover_healthcheck"></a>

### Réplique de secours saine {#healthy-standby}

Un membre d’un cluster devrait satisfaire plusieurs critères afin de pouvoir participer à la course au rôle de leader lors d’un basculement planifié ou de devenir leader en tant que candidat au basculement ou au basculement planifié :

- être accessible via l'API Patroni ;
- ne pas avoir l'étiquette `nofailover` définie sur `true` ;
- avoir le watchdog entièrement fonctionnel (si requis par la configuration) ;
- en cas de basculement planifié dans un cluster sain ou de basculement automatique, ne pas dépasser le retard maximal de réplication (`maximum_lag_on_failover` [paramètre de configuration](/fr/docs/patroni/config/dynamic#dynamic)) ;
- en cas de basculement planifié dans un cluster sain ou de basculement automatique, ne pas avoir un numéro de timeline inférieur à celui du cluster si `check_timeline` [paramètre de configuration](/fr/docs/patroni/config/dynamic#dynamic) est défini sur `true` ;
- en mode [synchrone](/fr/docs/patroni/replication_modes#synchronous_mode) :
  - En cas de basculement planifié (avec ou sans candidat) : être listé parmi les membres de la clé `/sync` ;
  - En cas de basculement dans des clusters sains ou défaillants, cette vérification est omise.

> [!WARNING]
> En cas de basculement manuel dans un cluster sans leader, un candidat sera autorisé à être promu même si :
>
> - il ne figure pas parmi les membres de la clé `/sync` lorsque le mode synchrone est activé ;
> - son retard dépasse le retard maximal de réplication autorisé ;
> - son numéro de timeline est inférieur au dernier numéro de timeline connu du cluster.

<a id="restart_endpoint"></a>

--------

## Point de terminaison de redémarrage {#restart-endpoint}

- `POST /restart` : Vous pouvez redémarrer Postgres sur le nœud spécifique en effectuant l'appel `POST /restart`. Dans le corps JSON de la requête `POST`, il est possible de spécifier de manière optionnelle certaines conditions de redémarrage :
  - **restart_pending** : booléen, si défini à `true`, Patroni redémarrera PostgreSQL uniquement lorsque le redémarrage est en attente afin d'appliquer certaines modifications de configuration de PostgreSQL.
  - **role** : effectuer le redémarrage uniquement si le rôle actuel du nœud correspond au rôle fourni dans la requête POST.
  - **postgres_version** : effectuer le redémarrage uniquement si la version actuelle de PostgreSQL est inférieure à celle spécifiée dans la requête POST.
  - **timeout** : durée d'attente avant que PostgreSQL ne commence à accepter les connexions. Remplace `primary_start_timeout`.
  - **schedule** : horodatage avec fuseau horaire, planifier le redémarrage à une date future.
- `DELETE /restart` : supprimer le redémarrage planifié

Les points de terminaison `POST /restart` et `DELETE /restart` sont utilisés par [patronictl_restart](/fr/docs/patroni/patronictl#patronictl_restart) et [patronictl flush cluster-name restart](/fr/docs/patroni/patronictl#patronictl_flush_parameters) respectivement.

<a id="reload_endpoint"></a>

--------

## Point de terminaison de rechargement {#reload-endpoint}

L'appel `POST /reload` ordonne à Patroni de relire et d'appliquer le fichier de configuration. Cela équivaut à envoyer le signal `SIGHUP` au processus Patroni. Si vous avez modifié certains paramètres de Postgres nécessitant un redémarrage (comme **shared_buffers**), vous devez toujours effectuer explicitement le redémarrage de Postgres en appelant le point de terminaison `POST /restart` ou à l'aide de [patronictl_restart](/fr/docs/patroni/patronictl#patronictl_restart).

Le point de terminaison de rechargement est utilisé par [patronictl_reload](/fr/docs/patroni/patronictl#patronictl_reload).

--------

## Point de terminaison de réinitialisation {#reinitialize-endpoint}

`POST /reinitialize` : réinitialiser le répertoire de données PostgreSQL sur le nœud spécifié. Cette opération n'est autorisée que sur les répliques. Une fois appelée, elle supprime le répertoire de données et démarre `pg_basebackup` ou une autre [méthode de création de réplique](/fr/docs/patroni/replica_bootstrap#custom_replica_creation).

L'appel peut échouer si Patroni est en boucle de récupération (redémarrage) d'une instance Postgres défaillante. Pour contourner ce problème, il est possible de spécifier `{"force":true}` dans le corps de la requête.

Vous pouvez spécifier {"from-leader":true} dans le corps de la requête pour obtenir directement un basebackup depuis le nœud leader. Cela est utile lors de l'exécution d'un reinit lorsque tous les nœuds répliques échouent.

Le point de terminaison de réinitialisation est utilisé par [patronictl_reinit](/fr/docs/patroni/patronictl#patronictl_reinit).

---

Liens inverses :

- [Configuration Patroni](/fr/docs/patroni/config/)
- [Configuration dynamique](/fr/docs/patroni/config/dynamic/)
- [Configuration YAML](/fr/docs/patroni/config/yaml/)
- [Mode failsafe du DCS](/fr/docs/patroni/dcs_failsafe_mode/)
- [FAQ](/fr/docs/patroni/faq/)
