Mythe : ASYNC_IO_COMPLETION indique-t-il toujours une attente sur une IO asynchrone ?

Lundi, mai 16, 2016
By David Baffaleuf in SQL Server (dbaffaleuf@capdata-osmozium.com) [71 article(s)]

Ceux qui pensent que oui lèvent la main… Perdu :)

Pour rappel, ASYNC_IO_COMPLETION est un évènement d’attente utilisé pour marquer les attentes liées à des IO asynchrones hors activité buffer pool (qui elles sont marquées avec PAGEIOLATCH_*). L’exemple le plus connu est le checkpoint, qui écrit en faisant appel à WriteFileGather et des IO asynchrones. Un moins connu est la lecture des fichiers de données pendant un backup.

Son opposé est IO_COMPLETION qui lui marque les attentes liées à des IO synchrones. Pour la différence entre les deux, retourner à l’article sur les IO asynchrones.

Or nous avons vu dans l’article que ce n’est pas parce qu’on poste une IO asynchrone qu’on a la garantie qu’elle sera bien asynchrone. C’est la raison pour laquelle on teste toujours le code retour de WriteFileGather ou ReadFileScatter :

- Si getlasterror retourne ERROR_IO_PENDING (997) : il s’agit bien d’une IO asynchrone.
- Si getlasterror retourne ERROR_SUCCESS (0) : il s’agit d’une IO synchrone.

Qu’est -ce qui pourrait bien causer la conversion d’une IO asynchrone en synchrone ? Comme l’indique Raymond Chen sur son blog, par exemple lorsqu’une écriture dans un fichier déclenche une extension sur disque, ou lorsqu’on écrit sur un filesystem compressé ou encrypté. Un plus grand nombre de causes sont listées dans un KB.

Or comme l’événement d’attente au niveau du code de SQL Server est déterminé avant de poster l’IO, que celle-ci soit asynchrone ou non ne changera pas la nature de l’attente vue par SQL Server. Donc ne pas s’y fier absolument.

On en profite pour rappeler que Paul Randal a publié la semaine dernière son référentiel des évènements d’attente.

Update 2016/07/01: Bob Dorr nous remonte une autre cause de blocage des IO asynchrones: lorsque le journal de transactions est zero-initialisé, certains systèmes de stockage récupèrent l’espace car cela peut s’apparenter à du thin provisionning. SQL Server doit réinitialiser l’espace à nouveau et l’IO sera postée en synchrone. SQL 2016 initialise avec 0xC0 à la place de 0×00 pour éviter ce problème. Cf : https://blogs.msdn.microsoft.com/bobsql/2016/06/03/sql-2016-it-just-runs-faster-ldf-stamped/

A+

Continuez votre lecture sur le blog :




Cliquer pour partager cet article sur Viadeo
Cliquer sur "CAPTURER" pour sauvegarder cet article dans Evernote Clip to Evernote

Tags: ,

Leave a Reply