Maison >base de données >tutoriel mysql >MySQL · Fonctionnalités du moteur · Introduction détaillée au sous-système InnoDB IO
En tant que moteur de base de données multiplateforme mature, InnoDB implémente un ensemble d'interfaces IO efficaces et faciles à utiliser, notamment des IO asynchrones synchrones, une fusion d'IO, etc. Cet article présente brièvement son implémentation interne. Le code principal est concentré dans le fichier os0file.cc. L'analyse de cet article est basée par défaut sur MySQL 5.6, CentOS 6 et gcc 4.8. Les informations sur les autres versions seront indiquées séparément.
Technologie WAL : Technologie Log-first, essentiellement toutes les bases de données utilisent cette technologie. Pour faire simple, lorsqu'un bloc de données doit être écrit, le thread frontal de la base de données écrit d'abord le journal correspondant (écriture séquentielle par lots) sur le disque, puis informe le client que l'opération a réussi. du bloc de données (écriture aléatoire discrète) Ensuite, placez-le dans le thread IO en arrière-plan. En utilisant cette technologie, bien qu'il y ait une opération d'écriture sur disque supplémentaire, comme le journal est écrit par lots et séquentiellement, l'efficacité est très élevée, de sorte que le client peut obtenir la réponse rapidement. De plus, si la base de données tombe en panne avant que les blocs de données réels ne soient écrits sur le disque, la base de données peut utiliser le journal pour une récupération après incident sans entraîner de perte de données lors du redémarrage.
Prélecture des données : Les blocs de données B et C "adjacents" au bloc de données A auront également une grande différence lorsque A est lu. La probabilité est lue, donc quand. en lisant B, ils peuvent être lus dans la mémoire à l'avance. Il s'agit de la technologie de prélecture des données. La contiguïté mentionnée ici a deux significations, l’une est la contiguïté physique et l’autre la contiguïté logique. Les contiguïtés dans le fichier de données sous-jacent sont appelées physiquement adjacentes. Si les fichiers de données ne sont pas adjacents, mais sont logiquement adjacents (les données avec id=1 et les données avec id=2 sont logiquement adjacentes, mais pas nécessairement physiquement adjacentes, et peuvent exister à des emplacements différents dans le même fichier), il est appelée contiguïté logique.
Mode d'ouverture de fichier : Il existe trois principaux modes courants pour les appels système ouverts : O_DIRECT, O_SYNC et le mode par défaut. Le mode O_DIRECT signifie que les opérations ultérieures sur le fichier n'utilisent pas le cache du système de fichiers. Le mode utilisateur exploite directement le fichier de périphérique, en contournant le cache et l'optimisation du noyau. D'un autre point de vue, utilisez le mode O_DIRECT pour écrire le fichier. est réussi, les données sont réellement écrites sur le disque (quel que soit le cache fourni avec le disque). Utilisez le mode O_DIRECT pour lire le fichier. Chaque opération de lecture est réellement lue sur le disque et ne sera pas lue sur le cache. du système de fichiers. O_SYNC signifie utiliser le cache du système d'exploitation, et la lecture et l'écriture des fichiers passent par le noyau, mais ce mode garantit également que les données seront écrites sur le disque à chaque fois. Le mode par défaut est similaire au mode O_SYNC, sauf qu'après l'écriture des données, il n'y a aucune garantie que les données seront placées sur le disque. Les données peuvent toujours être dans le système de fichiers. Lorsque l'hôte tombe en panne, les données peuvent être conservées. être perdu.
De plus, l'opération d'écriture nécessite non seulement que les données modifiées ou ajoutées soient écrites sur le disque, mais nécessite également que les métainformations du fichier soient écrites sur le disque. Ce n'est que lorsque les deux parties sont écrites sur le disque que les données ne peuvent pas être perdues. Le mode O_DIRECT ne garantit pas que les métainformations du fichier seront écrites sur le disque (mais la plupart des systèmes de fichiers le font, bug n°45892), donc si aucune autre opération n'est effectuée, il existe un risque de perte après l'écriture du fichier avec O_DIRECT. O_SYNC garantit que les données et les méta-informations sont placées sur le disque. Aucune des deux données n’est garantie en mode par défaut.
Après avoir appelé la fonction fsync, cela peut garantir que les données et les journaux sont écrits sur le disque. Par conséquent, si vous utilisez O_DIRECT et le mode par défaut pour ouvrir le fichier, vous devez appeler la fonction fsync après avoir écrit les données.
IO synchrone : Notre fonction de lecture/écriture couramment utilisée (sous Linux) est ce type d'IO. La caractéristique est que lorsque la fonction est exécutée, l'appelant attendra. la fonction à terminer. , et il n'y a pas de mécanisme de notification de message, car lorsque la fonction revient, cela signifie que l'opération est terminée, et vous pouvez savoir si l'opération a réussi en vérifiant directement la valeur de retour plus tard. Ce type d'opération d'E/S est relativement simple à programmer et peut effectuer toutes les opérations dans le même thread, mais nécessite que l'appelant attende. Dans un système de base de données, il est plus approprié d'appeler lorsque certaines données sont nécessaires de toute urgence, par exemple le journal. dans WAL doit être renvoyé au client Avant le téléchargement, une opération IO synchrone sera effectuée.
E/S asynchrones : Dans la base de données, le thread IO qui vide les blocs de données en arrière-plan utilise essentiellement des E/S asynchrones. Le thread frontal de la base de données n'a besoin que de soumettre la demande de bloc de brossage à la file d'attente d'E/S asynchrone avant de revenir faire autre chose, tandis que le thread d'E/S du thread d'arrière-plan vérifie régulièrement si ces demandes soumises ont été complétées et, si c'est le cas, effectue un suivi. en cours de traitement. Dans le même temps, les IO asynchrones sont souvent soumises par lots de requêtes. Si différentes requêtes accèdent au même fichier et ont des décalages consécutifs, elles peuvent être fusionnées en une seule requête IO. Par exemple, la première requête lit le fichier 1, 200 octets de données à partir du décalage 100, et la deuxième requête lit le fichier 1, 100 octets de données à partir du décalage 300, puis les deux requêtes peuvent être fusionnées dans Lire le fichier 1, 300 octets. de données commençant au décalage 100. La prélecture logique dans la prélecture des données utilise également souvent la technologie IO asynchrone.
La bibliothèque IO asynchrone actuelle sous Linux nécessite que le fichier soit ouvert en mode O_DIRECT, et l'adresse mémoire où le bloc de données est stocké, le décalage de lecture et d'écriture du fichier et la quantité de données lues et écrites doivent être un multiple entier de la taille du bloc logique du système de fichiers. La taille du bloc logique du système de fichiers peut être interrogée à l'aide d'une instruction similaire à sudo blockdev --getss /dev/sda5
. Si les trois ci-dessus ne sont pas des multiples entiers de la taille du bloc logique du système de fichiers, une erreur EINVAL sera signalée lors de l'appel des fonctions de lecture et d'écriture. Cependant, si le fichier n'est pas ouvert à l'aide de O_DIRECT, le programme peut toujours s'exécuter, mais il le fera. dégrader en IO synchrone et bloquer l'appel de fonction io_submit supérieur.
Dans InnoDB, si le système dispose de fonctions pread/pwrite (os_file_read_func
et os_file_write_func
), utilisez-les pour la lecture et l'écriture, sinon utilisez lseek read/write plan. Il s'agit d'une E/S synchrone InnoDB. En regardant la documentation pread/pwrite, nous pouvons voir que ces deux fonctions ne modifieront pas le décalage du handle de fichier et sont thread-safe, elles sont donc recommandées dans les environnements multithread. Cependant, la solution de lecture/écriture lseek nécessite son exécution. propre protection mutex, qui peut être utilisée dans des situations de concurrence élevée. Dans certaines circonstances, les chutes fréquentes dans l'état du noyau auront un certain impact sur les performances.
Dans InnoDB, utilisez l'appel système open pour ouvrir le fichier (os_file_create_func
En termes de mode, en plus de O_RDONLY (lecture seule), O_RDWR (lecture-écriture), O_CREAT (créer un fichier). ), O_EXCL (garanti que c'est ce thread qui a créé ce fichier) et O_TRUNC (effacer le fichier). Par défaut (la base de données n'est pas définie en mode lecture seule), tous les fichiers sont ouverts en mode O_RDWR. Le paramètre innodb_flush_method est plus important. Concentrons-nous dessus :
Si innodb_flush_method définit O_DSYNC, le fichier journal (ib_logfileXXX) est ouvert en utilisant O_SYNC, il n'est donc pas nécessaire d'appeler la fonction fsync. pour vider les données après l'écriture des données. Le fichier (ibd) est ouvert en mode par défaut, donc fsync doit être appelé pour vider le disque après l'écriture des données.
Si innodb_flush_method définit O_DIRECT, le fichier journal (ib_logfileXXX) est ouvert en mode par défaut. Après avoir écrit les données, vous devez appeler la fonction fsync pour vider le disque. ibd) est ouvert en mode O_DIRECT Après l'écriture, les données doivent être vidées en appelant la fonction fsync.
Si innodb_flush_method est défini sur fsync ou non, le fichier de données et le fichier journal sont ouverts en mode par défaut et fsync doit être utilisé pour vider le disque après avoir écrit les données.
Si innodb_flush_method est défini sur O_DIRECT_NO_FSYNC, la méthode d'ouverture de fichier est similaire au mode O_DIRECT. La différence est qu'une fois le fichier de données écrit, la fonction fsync n'est pas appelée pour vider le fichier. Cela est principalement dû au fait que O_DIRECT peut garantir que le fichier est également placé sur le disque dans le système de fichiers.
InnoDB ne prend actuellement pas en charge l'utilisation du mode O_DIRECT pour ouvrir les fichiers journaux, ni l'utilisation du mode O_SYNC pour ouvrir les fichiers de données.
Notez que si vous utilisez un aio natif Linux (voir la section suivante pour plus de détails), innodb_flush_method doit être configuré comme O_DIRECT, sinon il se dégradera en IO synchrone (il n'y aura aucune invite de tâche dans le journal des erreurs).
InnoDB utilise le verrouillage de fichiers du système de fichiers pour garantir qu'un seul processus lit et écrit un fichier (os_file_lock
), et utilise le verrouillage consultatif (Verrouillage consultatif) au lieu du verrouillage obligatoire (Obligatoire verrouillage), car le verrouillage obligatoire présente des bugs sur de nombreux systèmes, y compris Linux. En mode non lecture seule, tous les fichiers sont verrouillés avec des verrous de fichiers après leur ouverture.
Les répertoires dans InnoDB sont créés de manière récursive (os_file_create_subdirs_if_needed
et os_file_create_directory
). Par exemple, si vous devez créer le répertoire /a/b/c/, créez d'abord c, puis b, puis a, créez le répertoire et appelez la fonction mkdir. De plus, la création du niveau supérieur du répertoire nécessite d'appeler la fonction os_file_create_simple_func
au lieu de os_file_create_func
. Veuillez noter cela.
InnoDB a également besoin de fichiers temporaires. La logique de création de fichiers temporaires est relativement simple (os_file_create_tmpfile
), c'est-à-dire qu'après avoir réussi à créer un fichier dans le répertoire tmp, utilisez directement la fonction de dissociation pour libérer le handle, de sorte qu'à la fin du processus (qu'il se termine normalement ou anormalement), ce fichier sera automatiquement libéré. Lorsqu'InnoDB crée un fichier temporaire, il réutilise d'abord la logique de la fonction de couche serveur mysql_tmpfile. Plus tard, parce qu'il doit appeler la fonction de couche serveur pour libérer des ressources, il appelle la fonction dup pour copier un handle.
Si vous avez besoin d'obtenir la taille d'un fichier, InnoDB ne vérifie pas les métadonnées du fichier (fonction stat
), mais utilise la méthode lseek(file, 0, SEEK_END)
pour obtenir la taille du fichier. La raison en est. est d'empêcher les métadonnées. Un retard dans la mise à jour des informations a entraîné la récupération d'une taille de fichier incorrecte.
InnoDB pré-attribuera une taille à tous les fichiers nouvellement créés (y compris les fichiers de données et journaux). Le contenu des fichiers pré-alloués sera mis à zéro (os_file_set_size
). plein, il sera élargi. De plus, lorsque le fichier journal est créé, c'est-à-dire pendant la phase install_db, la progression de l'allocation est affichée dans le journal des erreurs à intervalles de 100 Mo.
En général, les opérations d'E/S conventionnelles et les E/S synchrones sont relativement simples, mais dans InnoDB, les E/S asynchrones sont essentiellement utilisées pour écrire des fichiers de données.
Depuis que MySQL est né avant l'aio natif de Linux, il existe deux solutions pour implémenter les IO asynchrones dans le code IO asynchrone MySQL.
Le premier est l'aio simulé original. InnoDB a simulé un mécanisme aio avant l'importation de l'air natif de Linux et sur certains systèmes qui ne prenaient pas en charge l'air. Lorsqu'une demande de lecture et d'écriture asynchrone est soumise, elle est simplement placée dans une file d'attente puis renvoyée, et le programme peut faire autre chose. Il existe plusieurs threads de traitement d'E/S asynchrones en arrière-plan (contrôlés par les deux paramètres innobase_read_io_threads et innobase_write_io_threads) qui suppriment continuellement les requêtes de cette file d'attente, puis utilisent des E/S synchrones pour terminer les demandes de lecture et d'écriture et le travail après la lecture et l'écriture est complété.
L'autre est Native aio. Actuellement, il est complété en utilisant io_submit, io_getevents et d'autres fonctions sous Linux (la glibc aio n'est pas utilisée, ceci est également simulé). Soumettez les demandes en utilisant io_submit et attendez les demandes en utilisant io_getevents. De plus, la plate-forme Windows a également son propre aio correspondant, qui ne sera pas présenté ici. Si vous utilisez la pile technologique Windows, la base de données doit utiliser sqlserver. Actuellement, les autres plateformes (sauf Linux et Windows) ne peuvent utiliser Simulate aio.
Tout d'abord, nous présenterons quelques fonctions et structures communes, puis nous présenterons en détail Simulate alo et Native aio sur Linux.
Les tableaux globaux sont définis dans os0file.cc, de type os_aio_array_t
Ces tableaux sont les files d'attente utilisées par Simulate aio pour mettre en cache les requêtes de lecture et d'écriture. Chaque élément du tableau est de type os_aio_slot_t
, qui enregistre chaque IO. . Le type de requête, le fd du fichier, le décalage, la quantité de données à lire, l'heure à laquelle la requête IO a été lancée, si la requête IO a été terminée, etc. De plus, la structure iocb dans Linux native io est également dans os_aio_slot_t
. Dans la structure du tableau os_aio_slot_t
, certaines informations statistiques sont enregistrées, telles que le nombre d'éléments de données (os_aio_slot_t
) qui ont été utilisés, s'ils sont vides, s'ils sont pleins, etc. Il existe un total de 5 tableaux globaux de ce type, qui sont utilisés pour stocker les requêtes asynchrones de lecture de fichiers de données (os_aio_read_array
), les requêtes asynchrones d'écriture de fichiers de données (os_aio_write_array
), les requêtes asynchrones d'écriture de fichiers journaux (os_aio_log_array
) et l'insertion. tampon d'écritures asynchrones (os_aio_ibuf_array
), demande de lecture et d'écriture de synchronisation de fichier de données (os_aio_sync_array
). L'écriture du bloc de données du fichier journal est une E/S synchrone, mais pourquoi devons-nous allouer une file d'attente de requêtes asynchrone (os_aio_log_array
) à l'écriture du journal ici ? La raison en est que les informations du point de contrôle doivent être enregistrées dans l'en-tête du fichier journal InnoDB. Actuellement, la lecture et l'écriture des informations du point de contrôle sont toujours implémentées à l'aide d'E/S asynchrones, car ce n'est pas très urgent. Dans la plate-forme Windows, si des E/S asynchrones sont utilisées pour un fichier spécifique, le fichier ne peut pas utiliser d'E/S synchrones, donc la file d'attente des demandes de lecture et d'écriture synchrones du fichier de données (os_aio_sync_array
) est introduite. Le fichier journal n'a pas besoin d'être lu à partir de la file d'attente des requêtes asynchrones, car le journal doit être lu uniquement pendant la récupération sur incident, et lors de la récupération sur incident, la base de données n'est pas encore disponible, il n'est donc pas nécessaire d'entrer en mode de lecture asynchrone. . Une chose à noter ici est que quels que soient les deux paramètres des variables innobase_read_io_threads et innobase_write_io_threads, il n'y en a qu'un os_aio_read_array
et os_aio_write_array
, mais les éléments os_aio_slot_t
dans les données augmenteront en conséquence. Sous Linux, le nombre d'éléments cat /sys/block/sda/queue/nr_requests
dans les données augmentera en conséquence. la variable augmente de 1 et l'élément Le nombre augmente de 256. Par exemple, innobase_read_io_threads=4, alors le tableau os_aio_read_array est divisé en quatre parties, chaque partie contient 256 éléments et chaque partie a son propre verrou indépendant, son sémaphore et ses variables statistiques, utilisées pour simuler 4 threads, innobase_write_io_threads est similaire. De là, nous pouvons également voir qu'il existe une limite supérieure aux requêtes de lecture et d'écriture que chaque thread de lecture/écriture asynchrone peut mettre en cache, qui est de 256. Si ce nombre est dépassé, les requêtes asynchrones suivantes doivent attendre. 256 peut être compris comme le contrôle de la couche InnoDB sur le nombre de concurrences d'E/S asynchrones, et il existe également des restrictions de longueur au niveau de la couche du système de fichiers et du disque, qui peuvent être interrogées en utilisant respectivement cat /sys/block/sdb/queue/nr_requests
et
. os_aio_init
os_aio_free
est appelé au démarrage d'InnoDB pour initialiser diverses structures, y compris le tableau global mentionné ci-dessus, ainsi que les verrous et mutex utilisés dans Simulate aio. os_aio_print_XXX
libère la structure correspondante. La série de fonctions show engine innodb status
est utilisée pour afficher l'état du sous-système aio et est principalement utilisée dans l'instruction
os_aio_func
La fonction de saisie est
Une fois la vérification réussie, os_aio_array_reserve_slot
est appelé, ce qui consiste à allouer cette requête IO à un certain thread de traitement io en arrière-plan (alloué par innobase_xxxx_io_threads, mais en fait dans le même tableau global), et enregistrez les informations pertinentes de la requête io pour faciliter le traitement du thread io en arrière-plan. Si le type de requête IO est le même, le même fichier est demandé et le décalage est relativement proche (par défaut, la différence de décalage est inférieure à 1M), InnoDB allouera les deux requêtes au même thread io pour faciliter les étapes suivantes Medium IO. fusionner.
Après avoir soumis la demande d'E/S, vous devez réveiller le thread de traitement des E/S en arrière-plan, car si le thread d'arrière-plan détecte qu'il n'y a pas de demande d'E/S, il entrera dans l'état d'attente (os_event_wait
).
À ce stade, la fonction revient, le programme peut faire autre chose et le traitement des E/S ultérieur est transmis au thread d'arrière-plan.
Présentez comment le thread IO en arrière-plan est traité.
Lorsque InnoDB démarre, le thread IO en arrière-plan sera démarré (io_handler_thread
). Il appellera os_aio_simulated_handle
pour retirer la requête IO du tableau global, puis utilisera IO synchrone pour la traiter. Après cela, le travail final doit être effectué. Par exemple, s'il s'agit d'une requête d'écriture, la page de données correspondante. doit être supprimé de la page sale dans le pool de mémoire tampon. Supprimé de la liste.
os_aio_simulated_handle
Tout d'abord, vous devez sélectionner une requête IO dans le tableau à exécuter. L'algorithme de sélection n'est pas un simple premier entré, premier sorti. Il sélectionne la requête avec. le plus petit décalage parmi toutes les demandes à traiter en premier, ceci est fait pour faciliter le calcul de la fusion des E/S ultérieures. Cependant, cela peut aussi facilement conduire à ce que certaines requêtes isolées avec des décalages particulièrement importants ne soient pas exécutées pendant une longue période, c'est-à-dire mourir de faim. Afin de résoudre ce problème, avant de sélectionner les requêtes IO, InnoDB effectuera d'abord une traversée If. une requête est trouvée il y a 2 secondes. Si elle est poussée (c'est-à-dire qu'elle a attendu 2 secondes) mais n'a pas encore été exécutée, la requête la plus ancienne sera exécutée en premier pour éviter que ces requêtes ne soient vidées. S'il y a deux requêtes avec le. même temps d'attente, la demande avec le décalage le plus petit sera sélectionnée.
os_aio_simulated_handle
L'étape suivante consiste à effectuer la fusion des E/S. Par exemple, la requête de lecture 1 demande file1, 200 octets à partir de offset100, et la requête de lecture 2 demande file1, 100 octets à partir de. à partir de offset300, ces deux requêtes peuvent être fusionnées en une seule requête : file1, 300 octets à partir de offset100. Après le retour de l'IO, copiez simplement les données dans le tampon de la requête d'origine. La demande d'écriture est similaire. Avant l'opération d'écriture, les données à écrire sont copiées dans un espace temporaire, puis écrites en une seule fois. Notez que les IO ne seront fusionnées que si les décalages sont continus. S'il y a des interruptions ou des chevauchements, ils ne seront pas fusionnés. Les demandes IO identiques ne seront pas fusionnées, cela peut donc être considéré comme un point d'optimisation.
os_aio_simulated_handle
S'il s'avère qu'il n'y a pas de demande d'E/S maintenant, il entrera dans l'état d'attente et attendra d'être réveillé
Pour résumer, vous pouvez voir que les demandes d'E/S sortantes sont à l'opposé d'une poussée une par une. Chaque poussée entre dans un thread d'arrière-plan et est traitée. Si la priorité du thread d'arrière-plan est relativement élevée, l'effet de fusion des E/S peut être médiocre. Pour résoudre ce problème, Simulate aio fournit une fonction de soumission de groupe similaire, c'est-à-dire qu'après la soumission d'un groupe de demandes d'E/S, le thread d'arrière-plan est réveillé et traité uniformément, de sorte que l'effet de la fusion des E/S soit meilleur. Mais il y a encore un léger problème avec cela. Si le thread d'arrière-plan est relativement occupé, il n'entrera pas dans l'état d'attente, ce qui signifie que tant que la requête entre dans la file d'attente, elle sera traitée. Ce problème peut être résolu dans l'aio natif ci-dessous.
En général, le mécanisme de simulation implémenté par InnoDB est relativement sûr et fiable. Si la plateforme ne prend pas en charge Native aio, ce mécanisme sera utilisé pour lire et écrire des fichiers de données.
Si la bibliothèque libaio est installée sur le système et que innodb_use_native_aio=on est défini dans le fichier de configuration, Native aio sera utilisé au démarrage.
La fonction de saisie est toujours os_aio_func
. En mode débogage, les paramètres entrants seront toujours vérifiés. Il ne vérifiera pas non plus si le fichier est ouvert en mode O_DIRECT. peu risqué. Point, si l'utilisateur ne sait pas que l'aio natif de Linux doit utiliser le mode O_DIRECT pour ouvrir les fichiers afin de profiter de l'aio, alors les performances ne répondront pas aux attentes. Il est recommandé de vérifier ici et d'afficher tout problème dans le journal des erreurs.
Une fois la vérification réussie, tout comme l'aio simulé, appelez os_aio_array_reserve_slot
pour allouer la requête IO au thread d'arrière-plan. L'algorithme d'allocation prend également en compte la fusion IO ultérieure, de la même manière que. Aio simulé. La principale différence est que la structure iocb doit être initialisée avec les paramètres de la requête IO. En plus d'initialiser l'iocb, les informations pertinentes de la requête IO doivent également être enregistrées dans le slot du tableau global, principalement pour la commodité des statistiques dans la série de fonctions os_aio_print_XXX
.
Appelez io_submit pour soumettre la demande.
À ce stade, la fonction revient, le programme peut faire autre chose et le traitement des E/S ultérieur est transmis au thread d'arrière-plan.
Vient ensuite le thread IO en arrière-plan.
Semblable à Simulate aio, le thread IO en arrière-plan est également démarré au démarrage d'InnoDB. S'il s'agit d'un aio natif Linux, cette fonction os_aio_linux_handle
sera appelée plus tard. La fonction de cette fonction est similaire à os_aio_simulated_handle
, mais l'implémentation sous-jacente est relativement simple. Elle appelle uniquement la fonction io_getevents pour attendre que la requête IO soit terminée. Le délai d'attente est de 0,5 s, ce qui signifie que si aucune requête IO n'est terminée dans un délai de 0,5 seconde, la fonction reviendra et continuera d'appeler io_getevents pour attendre. Bien sûr, avant d'attendre, elle déterminera si le serveur est fermé, et si c'est le cas, sortie.
Lors de la distribution de threads IO, essayez de placer les IO adjacentes dans un seul thread. Ceci est similaire à Simulate aio, mais pour les opérations de fusion d'IO ultérieures, Simulate aio l'implémente par lui-même, Native aio l'est. complété par le noyau, le code est donc relativement simple.
Une autre différence est que lorsqu'il n'y a pas de requêtes IO, Simulate aio entrera en état d'attente, tandis que Native aio se réveillera toutes les 0,5 secondes, effectuera quelques vérifications, puis continuera à attendre. Par conséquent, lorsqu'une nouvelle requête arrive, Simulated aio nécessite que le thread utilisateur se réveille, mais pas Native aio. De plus, Simulate aio doit également se réveiller lorsque le serveur est arrêté, ce qui n'est pas le cas de Native aio.
On peut constater que Native aio est similaire à Simulate aio. Les demandes sont soumises une par une puis traitées une par une, ce qui entraînera un mauvais effet de fusion des IO. L'équipe Facebook a soumis une optimisation de soumission de groupe aio natif : mettez d'abord en cache les requêtes IO, puis appelez la fonction io_submit pour soumettre toutes les requêtes précédentes en une seule fois (io_submit peut soumettre plusieurs requêtes à la fois), afin que le noyau soit plus pratique. pour faire l'optimisation des E/S. Lorsque Simulate aio est soumis à une forte pression sur le thread IO, l'optimisation de la soumission de groupe échouera, mais pas Native aio. Notez que la soumission de groupe est optimisée et que vous ne pouvez pas en soumettre trop à la fois. Si la longueur de la file d'attente aio est dépassée, un io_submit sera forcé d'être lancé.
Cet article présente en détail l'implémentation du sous-système IO dans InnoDB et les points auxquels il faut prêter attention lors de son utilisation. Les journaux InnoDB utilisent des E/S synchrones, les données utilisent des E/S asynchrones et l'ordre d'écriture des E/S asynchrones n'est pas le mode premier entré, premier sorti. Ces points doivent être pris en compte. Bien que Simulate aio ait une valeur d’apprentissage relativement importante, dans les systèmes d’exploitation modernes, il est recommandé d’utiliser Native aio.
Ce qui précède est une introduction détaillée de MySQL · Fonctionnalités du moteur · Sous-système InnoDB IO Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !