Recommandé (gratuit) : Tutoriel vidéo MySQL
Lorsque les utilisateurs rencontrent des problèmes de mémoire en utilisant n'importe quel logiciel (y compris MySQL), notre premier la réaction est une fuite de mémoire. Comme le montre cet article, ce n’est pas toujours le cas.
Cet article explique un bug concernant la mémoire.
Tous les clients du support Percona sont éligibles aux corrections de bogues, mais leurs options varient. Par exemple, les clients Advanced+ se voient proposer une version HotFix avant la sortie publique du logiciel avec le correctif
Tous les clients pris en charge par Percona sont tous. éligibles aux corrections de bugs, mais ils ont également des options différentes. Par exemple, les clients VIP peuvent obtenir la version hotfiix avant la publication officielle du correctif logiciel. Les clients Premium n'ont même pas besoin d'utiliser le logiciel Percona. Nous pouvons également diffuser le correctif en amont pour eux. Mais pour les produits Percona, tous les niveaux de support ont droit à des corrections de bugs.
Même ainsi, cela ne signifie pas que nous corrigerons chaque comportement inattendu, même si nous acceptons que ce comportement soit un bug valide. L'une des raisons d'une telle décision pourrait être que même si le comportement est clairement mauvais. Produits Percona, il s'agit toujours d'une demande de fonctionnalité.
Même ainsi, cela ne signifie pas que nous corrigerons toutes les situations inattendues, même si nous acceptons cette situation comme un bug valide. L'une des raisons pour lesquelles on a pris une telle décision peut être que bien que cette situation inattendue soit clairement fausse, il s'agit bien d'une exigence du produit percona lui-même
en tant que bug en tant que cas d'apprentissage
Un bon exemple récent d'un tel cas est PS-5312 – le bogue est reproductible en amont et signalé sur bugs.mysql.com/95065
Un bon exemple récent est PS-5312— —This le bogue peut être reproduit en amont et documenté sur bugs.mysql.com/95065.
Cela rapporte une situation dans laquelle l'accès aux index de texte intégral InnoDB entraîne une augmentation de l'utilisation de la mémoire. Cela commence lorsque quelqu'un interroge un index de texte intégral, augmente jusqu'à un maximum et n'est pas libéré pendant une période assez longue.
Ce rapport décrit une situation qui entraîne une augmentation de l'utilisation de la mémoire lors de l'accès à l'index de texte intégral d'InnoDB. Cette situation se produit dans certaines requêtes d'index en texte intégral. La mémoire continuera à croître jusqu'à atteindre la valeur maximale et ne sera pas libérée avant longtemps.
Yura Sorokin de l'équipe d'ingénierie de Percona a enquêté s'il s'agissait d'une fuite de mémoire et a découvert que ce n'était pas le cas.
Lorsque InnoDB résout une requête en texte intégral, il crée un tas de mémoire dans la fonction fts_query_phrase_search. Ce tas peut atteindre 80 Mo. De plus, il comporte un grand nombre de blocs ( mem_block_t ) qui ne sont pas toujours utilisés en continu et ce. , à son tour, conduit à une fragmentation de la mémoire.
Lorsque InnoDB analyse une requête en texte intégral, il crée un tas de mémoire dans la fonction
, qui peut atteindre 80 Mo. De plus, ce processus utilisera également un grand nombre de blocs non contigus (), entraînant une fragmentation de la mémoire. fts_query_phrase_search
mem_block_t
Dans la fonction exit , le tas de mémoire est libéré. InnoDB fait cela pour chacun des blocs alloués, il appelle free() qui appartient à l'une des bibliothèques d'allocation de mémoire, telle. comme malloc ou jemalloc. Du point de vue de mysqld, tout est fait correctement : il n'y a pas de fuite de mémoire.
A la sortie de la fonction, ces tas de mémoire seront libérés. InnoDB fait cela pour chaque bloc qu'il alloue. À la fin de l'exécution de la fonction, appelez une opération
dans la bibliothèque d'allocation de mémoire, telle que ou free()
. Du point de vue de MySQL lui-même, cela ne pose aucun problème et il n'y a pas de fuite de mémoire. malloc
jemalloc
Cependant, même si free() doit libérer de la mémoire lorsqu'il est appelé, il n'est pas nécessaire de la restituer au système d'exploitation. Si l'allocateur de mémoire décide que les mêmes blocs de mémoire seront bientôt requis, il peut toujours les conserver. pour le processus mysqld. Cela explique pourquoi vous constaterez peut-être que mysqld utilise encore beaucoup de mémoire une fois le travail terminé et toutes les désallocations effectuées.
Cependant, la fonction free() devrait effectivement être libérée lorsque cela s'appelle de la mémoire, mais il n'est pas nécessaire de la restituer au système d'exploitation. Si l'allocateur de mémoire constate que ces blocs de mémoire sont nécessaires immédiatement, ils seront réservés au processus mysqld. Cela explique pourquoi mysqld occupe encore beaucoup de mémoire après avoir terminé son travail et libéré la mémoire.
En pratique, ce n'est pas un gros problème et ne devrait pas causer de dommages. Mais si vous avez besoin que la mémoire soit restituée plus rapidement au système d'exploitation, vous pouvez essayer des allocateurs de mémoire alternatifs, tels que jemalloc. Ce dernier a fait ses preuves. le problème avec le PS-5312.
Ce n'est pas un gros problème dans la production réelle, et cela ne devrait pas provoquer d'accidents. Mais si vous avez besoin de restituer de la mémoire au système d'exploitation plus rapidement, vous pouvez essayer un allocateur de mémoire non traditionnel, quelque chose comme jemallolc
. Il est prouvé qu'il résout le problème du PS-5312.
Un autre facteur qui améliore la gestion de la mémoire est le nombre de cœurs de processeur : plus nous en avons utilisé pour le test, plus la mémoire a été restituée au système d'exploitation rapidement. Cela peut probablement s'expliquer par le fait que si. vous disposez de plusieurs processeurs, l'allocateur de mémoire peut alors en consacrer un uniquement pour libérer de la mémoire au système d'exploitation.
Un autre facteur qui améliore la gestion de la mémoire est le nombre de cœurs de processeur : lors des tests, plus il y a de cœurs de processeur, la mémoire sera restituée au système d'exploitation plus rapidement. Il est possible que vous disposiez de plusieurs processeurs et que l'un d'eux puisse être utilisé exclusivement comme allocateur de mémoire pour libérer de la mémoire pour le système d'exploitation.
La toute première implémentation des index de texte intégral InnoDB a introduit cette faille comme l'a découvert notre ingénieur Yura Sorokin :
Le tout premier commit 5.6 qui introduit le texte intégral. Fonctionnalité de recherche pour InnoDB WL#5538 : prise en charge de la recherche en texte intégral InnoDB – https://dev.mysql.com/worklog/task/?id=5538
Implement WL #5538 InnoDB Prise en charge de la recherche en texte intégral, fusion – https://github.com/mysql/mysql-server/commit/b6169e2d944 – présente également ce problème.
Comme nos ingénieurs Yura Sorokin
Comme constaté, les deux points suivants illustrent que la première implémentation de l'index de texte intégral InnoDB a introduit cette faille :
La première introduction de la fonction d'index de texte intégral InnoDB WL dans la version 5.6 de MySQL : #5538 : Prise en charge de la recherche en texte intégral InnoDB – https://dev.mysql.com/worklog/task/?id=5538
Implémentation de WL #5538 InnoDB complet -prise en charge de la recherche de texte et fusion – https ://github.com/mysql/mysql-server/commit/b6169e2d944 - Le même problème existe également
Méthode de réparation
Nous avons quelques options pour résoudre ce problème :
Modifier l'implémentation de l'index de texte intégral InnoDB
Utiliser une bibliothèque de mémoire personnalisée comme jemalloc
Les deux ont leurs avantages et leurs inconvénients.
Nous avons deux façons de résoudre ce problème :
1. Modifier l'implémentation de l'index de texte intégral InnoDB
<.>2. Utilisez une bibliothèque de mémoire personnalisée, telle quejemalloc
Conclusion
Si vous constatez une utilisation élevée de la mémoire par le processus mysqld, ce n'est pas toujours le symptôme d'une fuite de mémoire. Vous pouvez utiliser l'instrumentation de mémoire dans Performance. Schéma pour savoir comment la mémoire allouée est utilisée. Essayez des bibliothèques de mémoire alternatives pour un meilleur traitement des allocations et une libération de mémoire. Recherchez LD_PRELOAD dans le manuel d'utilisation pour savoir comment le configurer sur ces pages ici et ici.Si vous constatez que le processus mysqld occupe beaucoup de mémoire, cela ne signifie pas forcément qu'il y a une fuite de mémoire. Nous pouvons utiliser l'instrumentation de la mémoire dans Performance Schema pour comprendre comment le processus utilise la mémoire allouée. Vous pouvez également essayer de remplacer la bibliothèque de mémoire pour mieux gérer l'allocation et la désallocation de mémoire. Pour savoir comment configurer LD_RELOAD, veuillez vous référer aux pages correspondantes du manuel d'utilisation MySQL mysqld-safe et using-system.
Pour plus de connaissances liées à la programmation, veuillez visiter : Enseignement de la programmation ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!