<!--
Add an asynchronous I/O subsystem (Andres Freund, Thomas Munro, Nazir Bilal Yavuz, Melanie Plageman) § § § § § § § § § § §

This feature allows backends to queue multiple read requests, which allows for
more efficient sequential scans, bitmap heap scans, vacuums, etc. This is
enabled by server variable io_method, with server variables io_combine_limit
and io_max_combine_limit added to control it. This also enables
effective_io_concurrency and maintenance_io_concurrency values greater than
zero for systems without fadvise() support. The new system view pg_aios shows
the file handles being used for asynchronous I/O.

* https://postgr.es/c/02844012b (minimal wiring up of the AIO subsystem)
  https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt

* https://postgr.es/c/da7226993 (aio: Add core asynchronous I/O infrastructure)
  https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
  https://postgr.es/m/20210223100344.llw5an2aklengrmn@alap3.anarazel.de
  https://postgr.es/m/stj36ea6yyhoxtqkhpieia2z4krnam7qyetc57rfezgk4zgapf@gcnactj4z56m

* https://postgr.es/c/55b454d0e (aio: Infrastructure for io_method=worker)
  https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
  https://postgr.es/m/20210223100344.llw5an2aklengrmn@alap3.anarazel.de
  https://postgr.es/m/stj36ea6yyhoxtqkhpieia2z4krnam7qyetc57rfezgk4zgapf@gcnactj4z56m

* https://postgr.es/c/247ce06b8 (aio: Add io_method=worker)
  https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
  https://postgr.es/m/20210223100344.llw5an2aklengrmn@alap3.anarazel.de
  https://postgr.es/m/stj36ea6yyhoxtqkhpieia2z4krnam7qyetc57rfezgk4zgapf@gcnactj4z56m

* https://postgr.es/c/10f664684 (Introduce io_max_combine_limit)
  https://postgr.es/m/CA%2BhUKG%2B2T9p-%2BzM6Eeou-RAJjTML6eit1qn26f9twznX59qtCA%40mail.gmail.com

* https://postgr.es/c/06fb5612c (Increase io_combine_limit range to 1MB.)
  https://postgr.es/m/CA%2BhUKG%2B2T9p-%2BzM6Eeou-RAJjTML6eit1qn26f9twznX59qtCA%40mail.gmail.com

* https://postgr.es/c/c325a7633 (aio: Add io_method=io_uring)
  https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
  https://postgr.es/m/20210223100344.llw5an2aklengrmn@alap3.anarazel.de
  https://postgr.es/m/stj36ea6yyhoxtqkhpieia2z4krnam7qyetc57rfezgk4zgapf@gcnactj4z56m

* https://postgr.es/c/50cb7505b (aio: Implement support for reads in smgr/md/fd)
  https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
  https://postgr.es/m/20210223100344.llw5an2aklengrmn@alap3.anarazel.de
  https://postgr.es/m/stj36ea6yyhoxtqkhpieia2z4krnam7qyetc57rfezgk4zgapf@gcnactj4z56m

* https://postgr.es/c/047cba7fa (bufmgr: Implement AIO read support)
  https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
  https://postgr.es/m/20210223100344.llw5an2aklengrmn@alap3.anarazel.de
  https://postgr.es/m/stj36ea6yyhoxtqkhpieia2z4krnam7qyetc57rfezgk4zgapf@gcnactj4z56m

* https://postgr.es/c/12ce89fd0 (bufmgr: Use AIO in StartReadBuffers())
  https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
  https://postgr.es/m/20210223100344.llw5an2aklengrmn@alap3.anarazel.de
  https://postgr.es/m/stj36ea6yyhoxtqkhpieia2z4krnam7qyetc57rfezgk4zgapf@gcnactj4z56m

* https://postgr.es/c/2a5e709e7 (Enable IO concurrency on all systems)
  https://postgr.es/m/CAAKRu_atGgZePo=_g6T3cNtfMf0QxpvoUh5OUqa_cnPdhLd=gw@mail.gmail.com

Autres sources :

* https://github.com/postgres/postgres/blob/master/src/backend/storage/aio/README.md
* https://youtu.be/qX50xrHwQa4 conf d'Andres

-->

<div class="slide-content">

  * IO asynchrones
    + PostgreSQL connaît mieux le contexte que l'OS
    + 15: `recovery_prefetch`
    + 16: extension des relations
    + 17: infrastructure pour combiner des IO (`io_combine_limit`)
    + 18: infrastructure pour les IO asynchrone (`io_method`)
  * De gros gains
     + _Bitmap Scan_ en premier lieu
     + en lecture uniquement
  * _Direct IO_ (pas "encore" disponible)
    + 16: `debug_io_direct`
</div>

<div class="notes">

**Pourquoi utiliser les IO directes et asynchrones ?**

Jusqu'à maintenant, PostgreSQL se base sur l'OS pour l'ensemble de ses IO.
PostgreSQL lui demande des blocs, que l'OS a déjà en cache, ou qu'il va chercher
sur disque. Cependant un chantier est en cours pour passer, au moins
partiellement, de ce mode d'accès aux données appelé _buffered IO_, à ce qu'on
appelle des IO directes (ou _direct IO[^DIO]_).

Dans beaucoup de cas, cela permet de déplacer les données directement du
stockage vers le cache de PostgreSQL sans faire intervenir le CPU en utilisant
la technologie DMA[^DMA]. Cela réduit la charge CPU et diminue la latence des
IO. Un autre avantage de ce changement est une meilleure utilisation de la
mémoire, puisque l'on évite une double mise en cache de certaines données (OS +
PostgreSQL). Pour finir, cela permet de mieux contrôler les IO en tirant partie
du fait que PostgreSQL a une meilleure connaissance du contexte dans lequel les
IO sont réalisées. Cela donne, par exemple, plus de contrôle sur le timing où
les écritures sont effectivement faites sur le stockage (`fsync`).

Cependant, en donnant à PostgreSQL la main sur l'exécution des IO, on se passe
des mécanismes en place au niveau du système d'exploitation comme la mise en
cache des fichiers et le _kernel read ahead_. Seule, cette modification
serait donc délétère pour les performances. 

On peut facilement s'en rendre compte en expérimentant l'option
`debug_io_direct`, qui a été ajoutée en version 16 et qui permet de demander à
l'OS d'utiliser le cache au minimum pour les relations et/ou les WAL. Comme son
nom l'indique, cette option est destinée aux développeurs de PostgreSQL, et
surtout pas à la production.

Un préalable aux IO directes est donc de mettre en place toute une
infrastructure pour réaliser des IO asynchrones (appelées AIO[^AIO] dans la
suite de ce texte) afin de grouper et de réaliser les IO en avance de phase
(_prefetch_) et de manière concurrente.

Ces améliorations laissent espérer beaucoup d'améliorations de performances
notamment dans le cadre des écritures et synchronisations des WAL.

Le parcours séquentiel d'une table avec plusieurs segments est un autre cas où
le contexte des IO est important. En effet, pour le _kernel read ahead_ un
changement de fichiers provoque des fluctuations dans l'usage du _prefetch_ car
le noyau ne sait pas qu'il s'agit de la même table et que l'on va continuer à
lire le segment et les suivants jusqu'au bout. PostgreSQL, lui, est au courant
de ce contexte et pourra continuer le prefetch avec la même agressivité.

Pour finir, les IO directes et asynchrones nécessitent des quantités de _shared
buffers_ importantes pour fonctionner de manière optimale.

Mettre en place ce nouveau mode de fonctionnement touche donc énormément
d'aspects du fonctionnement de PostgreSQL et il faudra plusieurs versions pour
en tirer tous les bénéfices.

Certaines fonctionnalités exploitaient déja les io asynchrones du système
d'exploitation comme la [recovery en version 15] (`recovery_prefetch`) et les
extensions de relations en masse en version 16. Plus ancien, le _bitmap heap
scan_ a longtemps été le seul cas où le _prefetch_ était utilisé.

D'autres améliorations ont été faites en version 17, avec la création d'une
nouvelle API permettant de [regrouper plusieurs IO] en un seul appel système.
Actuellement seules l’implémentation du parcours séquentiel (_Seq Scan_),
celle de `ANALYZE`,
et celle de l'extension `pg_prewarm` utilisent cette nouvelle API.

Cette nouvelle version continue donc l'effort engagé sur l'amélioration du
système d'IO de PostgreSQL en ajoutant un système pour gérer les IO asynchrones
qui s'intègrent avec les fonctionnalités existantes.

Le travail pour utiliser les IO directes ne viendra « que » plus tard.

[recovery en version 15]: https://dali.bo/workshop15_html#permettre-le-pre-fetch-du-contenu-des-fichiers-wal-pendant-le-recovery
[regrouper plusieurs IO]: https://dali.bo/workshop17_html#regroupement-des-io

[^DMA]: _Direct Memory Access_
[^AIO]: _Async IO_
[^DIO]: _Direct IO_

</div>

