<!--
Les sources pour pgbench sont :

* Have pgbench report the number of failed transactions (Yugo Nagata) §

  * https://postgr.es/c/cae0f3c40
  * https://www.postgresql.org/message-id/flat/20240921003544.2436ef8da9c5c8cb963c651b%40sraoss.co.jp

Les sources pour pg_createsubscriber sont :

* Add pg_createsubscriber ohttps://postgr.es/c/fb2ea12f4ption --all to create logical replicas for all databases (Shubham Khanna) §

  + https://postgr.es/c/fb2ea12f4
    https://postgr.es/m/CAHv8RjKhA=_h5vAbozzJ1Opnv=KXYQHQ-fJyaMfqfRqPpnC2bA@mail.gmail.com

* Add pg_createsubscriber option --remove to remove publications (Shubham Khanna) §

  + https://postgr.es/c/e5aeed4b8
    https://postgr.es/m/CAHv8RjL4OvoYafofTb_U_JD5HuyoNowBoGpMfnEbhDSENA74Kg@mail.gmail.com

  + https://www.postgresql.org/message-id/E1uULyv-003GEm-0M@gemulon.postgresql.org => rename remove to clean

* Add pg_createsubscriber option --enable-two-phase to enable prepared transactions (Shubham Khanna) §

  + https://postgr.es/c/e117cfb2f
    https://postgr.es/m/CAHv8RjLPdFP=kA5LNSmWZ=+GMXmO+LczvV6p9HJjsXxZz10KGA@mail.gmail.com

  + https://www.postgresql.org/message-id/E1uVu1Z-003ti9-1v@gemulon.postgresql.org 

    Rename to renames the pg_recvlogical options --two-phase and --failover to
   --enable-two-phase and --enable-failover

* pgsql: pg_recvlogical: Add --failover option.

https://www.postgresql.org/message-id/E1u0l1n-002fdC-2n@gemulon.postgresql.org

Les sources pour pg_rewind sont :

* If pg_rewind's --source-server specifies a database name, use it in --write-recovery-conf output (Masahiko Sawada) §

  * https://postgr.es/c/4ecdd4110
  * https://postgr.es/m/CAD21AoAkW=Ht0k9dVoBTCcqLiiZ2MXhVr+d=j2T_EZMerGrLWQ@mail.gmail.com

-->

<div class="slide-content">

  * `pg_bench`
    + affiche désormais les erreurs de sérialisation et deadlock dans
      ses rapports.
  * `pg_createsubscriber`
    + `--all`, `--clean=publication`, `--enable-two-phase`, `--enable-failover`
  * `pg_rewind`
    + amélioration de `--write-recovery-conf` pour les _failover slots_

</div>

<div class="notes">

**Outil pgbench** :

Lorsque c'est approprié, les statistiques globales et par script contiennent
maintenant le nombre de transactions échouées à cause d'erreurs de
sérialisation ou de deadlock.

Voici un exemple tiré de la discussion du patch :

```bash
psql -dbname bench --command "CREATE TABLE t1(i int, j int);"
```

```default
CREATE TABLE
```

```bash
cat script1.sql
```

```default
BEGIN;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
INSERT INTO t1 SELECT max(i)+1,2 FROM t1;
END;
```

```bash
cat script2.sql
```

```default
BEGIN;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
INSERT INTO t1 SELECT MAX(i)+1,2 FROM t1;
END;
```

```bash
/usr/pgsql-18/bin/pgbench \
  --time=30 \
  --client=2 \
  --file=script1.sql \
  --file=script2.sql \
  --failures-detailed \
  --report-per-command \
  bench
```
```default
pgbench (18beta1)
starting vacuum...end.
transaction type: multiple scripts
scaling factor: 1
query mode: simple
number of clients: 2
number of threads: 1
maximum number of tries: 1
duration: 30 s
number of transactions actually processed: 11656
number of failed transactions: 11744 (50.188%)
number of serialization failures: 11744 (50.188%)
number of deadlock failures: 0 (0.000%)
latency average = 2.564 ms (including failures)
initial connection time = 5.911 ms
tps = 388.583176 (without initial connection time)
SQL script 1: script1.sql
 - weight: 1 (targets 50.0% of total)
 - 11639 transactions (49.7% of total)
 - number of transactions actually processed: 5773 (tps = 192.458019)
 - number of failed transactions: 5866 (50.400%)
 - number of serialization failures: 5866 (50.400%)
 - number of deadlock failures: 0 (0.000%)
 - latency average = 2.567 ms
 - latency stddev = 0.549 ms
 - statement latencies in milliseconds and failures:
         0.030           0 BEGIN;
         0.028           0 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
         1.141        5786 INSERT INTO t1 SELECT max(i)+1,2 FROM t1;
         1.383          80 END;
SQL script 2: script2.sql
 - weight: 1 (targets 50.0% of total)
 - 11761 transactions (50.3% of total)
 - number of transactions actually processed: 5883 (tps = 196.125156)
 - number of failed transactions: 5878 (49.979%)
 - number of serialization failures: 5878 (49.979%)
 - number of deadlock failures: 0 (0.000%)
 - latency average = 2.578 ms
 - latency stddev = 0.556 ms
 - statement latencies in milliseconds and failures:
         0.029           0 BEGIN;
         0.028           0 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
         1.147        5800 INSERT INTO t1 SELECT MAX(i)+1,2 FROM t1;
         1.388          78 END;
```

Les lignes suivantes ont été ajoutées :

* `number of failed transactions`
* `number of serialization failures`

**Outil pg_createsubscriber** :

Depuis PostgreSQL 17,
la commande `pg_createsubscriber` permet de transformer une instance standby 
en réplica logique en créant les publications/souscriptions nécessaires. 
Elle s'est vu ajouter plusieurs options qui permettent de simplifier ce 
processus.

La nouvelle option `--all` de `pg_createsubscriber` permet de s'assurer que
l'outil va créer un couple publication/souscription pour chaque base de
données présente à la fois sur la source et la cible. Précédemment, la liste de
toutes les bases de données devait être spécifiée avec l'option `-d,
--database` pour arriver au même résultat, ce qui pouvait être fastidieux.

Les options  `-d, --database`, `--publication`, `--subscription` et
`--replication-slot` ne sont pas compatible avec `--all`.

L'option `--clean` permet de supprimer tous les objets correspondant au type
spécifié sur le serveur cible (souscripteur). Pour le moment, le seul type
disponible est `publication`.

L'option `--enable-two-phase` permet d'activer le mode _two-phase commit_ sur
toutes les souscriptions lors de leur création. La modification pouvait déjà
être réalisée manuellement, mais nécessitait de désactiver la souscription au
préalable.

Si cette option est activée, les modifications faites par chaque transaction
préparée peuvent être envoyées au souscripteur à partir du moment où la commande
`PREPARE TRANSACTION` est exécutée, plutôt que lors du `COMMIT PREPARED`. Elle
sera traitée comme une transaction _two-phase_. Cela permet donc d'utiliser le
_streaming_ pour ce genre de transaction.

<!-- 
Pour une transaction préparée on a :

BEGIN;
  INSERT ...
  UPDATE ...
  PREPARE TRANSACTION 'ma txn';
COMMIT PREPARED;

D'après ma compréhension du truc on a :

* Sans _two-phase_, les modifications sont envoyées quand le `COMMIT PREPARED`
  est terminé.
* Avec, elles sont envoyées a partir du moment ou on fait le `PREPARE
  TRANSACTION` et donc, dés le début du `COMMIT PREPARED`.

Si la transaction est longue cela permet donc de la streamer de la même
manière que les transactions classiques.

-->

L'option `--enable-failover` permet de créer les slots de réplication en
activant l'option _failover_. Cette option peut être utilisée avec l'option
`--create-slot`.

**Outil pg_rewind** :

L'utilisation des slots de réplication logique synchronisés (ou _failover
slots_) nécessite :

* d'activer `sync_replication_slots` sur la standby ;
* d'utliser un slot de réplication physique pour la réplication entre l'instance
  primaire et la standy en question (et donc le renseigner dans
  `primary_slot_name`) ;
* d'activer `hot_standby_feedback` sur la standby ;
* de fournir un `dbname` dans la chaîne de connexion de la réplication 
  (`primary_conninfo`) ;
* de renseigner le nom du slot dans `synchronized_standby_slots` sur la
  primaire (conseillé).

Lorsque `--write-recovery-conf` est spécifié, `pg_rewind` est désormais capable
d'ajouter le nom de la base de données dans le paramètre `primary_conninfo` du
fichier `postgresql.auto.conf` en se basant sur la chaîne de connection
spécifiée via le paramètre `--source-server`.

Cela simplifie donc le retour en service de l'instance en évitant une
modification manuelle de la configuration. C'est intéressant puisque,
généralement, on doit utiliser `pg_rewind` dans le contexte d'un incident ou
avec un outil d'automatisation comme `patroni`.

</div>
