0

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

twitterlinkedinmail

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 0x00 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 :

twitterlinkedinmail

David Baffaleuf

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.