Utilisation maximale de la mémoire MySQL


111

Je voudrais savoir comment il est possible de fixer une limite supérieure à la quantité de mémoire utilisée par MySQL sur un serveur Linux.

À l'heure actuelle, MySQL continuera à prendre de la mémoire à chaque nouvelle requête demandée, de sorte qu'il finisse par manquer de mémoire. Existe-t-il un moyen de placer une limite pour que MySQL n'utilise pas plus de ce montant?


4
MySQL "n'occupe pas de mémoire pour chaque nouvelle requête et finit par s'épuiser". L'utilisation de la mémoire est beaucoup plus complexe que cela.
Rick James

Réponses:


183

L'utilisation maximale de la mémoire de MySQL dépend beaucoup du matériel, de vos paramètres et de la base de données elle-même.

Matériel

Le matériel est la partie évidente. Plus il y a de RAM, plus les disques sont fous, plus rapides sont les ftw . Ne croyez pas ces lettres d'information mensuelles ou hebdomadaires. MySQL ne s'adapte pas de manière linéaire, même pas sur le matériel Oracle. C'est un peu plus compliqué que ça.

L'essentiel est: il n'y a pas de règle générale pour ce qui est recommandé pour votre configuration MySQL. Tout dépend de l'utilisation actuelle ou des projections.

Paramètres et base de données

MySQL propose d'innombrables variables et commutateurs pour optimiser son comportement. Si vous rencontrez des problèmes, vous devez vraiment vous asseoir et lire le manuel (f'ing).

Quant à la base de données - quelques contraintes importantes:

  • moteur de table ( InnoDB, MyISAM, ...)
  • Taille
  • indices
  • usage

La plupart des conseils MySQL sur le stackoverflow vous indiqueront environ 5 à 8 paramètres dits importants. Tout d'abord, ils n'ont pas tous d'importance - par exemple, allouer beaucoup de ressources à InnoDB et ne pas utiliser InnoDB n'a pas beaucoup de sens parce que ces ressources sont gaspillées.

Ou - beaucoup de gens suggèrent d'augmenter la max_connectionvariable - eh bien, ils ne savent pas que cela implique également que MySQL allouera plus de ressources pour répondre à ces besoins max_connections- si jamais nécessaire. La solution la plus évidente peut être de fermer la connexion à la base de données dans votre DBAL ou d'abaisser le wait_timeoutpour libérer ces threads.

Si vous comprenez ma dérive - il y a vraiment beaucoup, beaucoup de choses à lire et à apprendre.

Moteurs

Les moteurs de table sont une décision assez importante, beaucoup de gens les oublient très tôt et se retrouvent soudainement à se battre avec une MyISAMtable de 30 Go qui verrouille et bloque toute leur application.

Je ne veux pas dire que MyISAM est nul , mais InnoDBpeut être modifié pour répondre presque ou presque aussi vite que MyISAMet offre des choses telles que le verrouillage de ligne UPDATEalors que MyISAMverrouille toute la table lorsqu'elle est écrite.

Si vous êtes libre d'exécuter MySQL sur votre propre infrastructure, vous voudrez peut-être également consulter le serveur percona, car parmi les nombreuses contributions d'entreprises comme Facebook et Google (elles savent rapidement), il inclut également la propre goutte de Percona. en remplacement de InnoDB, appelé XtraDB.

Voir mon essentiel pour la configuration du serveur percona (et du client) (sur Ubuntu): http://gist.github.com/637669

Taille

La taille de la base de données est très, très importante - croyez-le ou non, la plupart des utilisateurs d'Intarwebs n'ont jamais manipulé une configuration MySQL volumineuse et intense, mais celles-ci existent vraiment. Certaines personnes vont troller et dire quelque chose comme «Utilisez PostgreSQL! 111», mais ignorons-les pour le moment.

L'essentiel est: à en juger par la taille, la décision concernant le matériel doit être prise. Vous ne pouvez pas vraiment faire fonctionner une base de données de 80 Go rapidement sur 1 Go de RAM.

Les indices

Ce n'est pas: plus on est de fous. Seuls les indices nécessaires doivent être définis et l'utilisation doit être vérifiée avec EXPLAIN. Ajoutez à cela que MySQL EXPLAINest vraiment limité, mais c'est un début.

Configurations suggérées

À propos de ceux-ci my-large.cnfet des my-medium.cnffichiers - je ne sais même pas pour qui ils ont été écrits. Roulez le vôtre.

Apprêt de réglage

Un bon début est l' amorce de réglage . C'est un script bash (indice: vous aurez besoin de linux) qui prend la sortie de SHOW VARIABLESet SHOW STATUSet l'enveloppe dans une recommandation, espérons-le utile. Si votre serveur a fonctionné un certain temps, la recommandation sera meilleure car il y aura des données sur lesquelles les baser.

Cependant, l'amorce d'accord n'est pas une sauce magique. Vous devriez toujours lire toutes les variables qu'il suggère de changer.

En train de lire

J'aime vraiment recommander le mysqlperformanceblog . C'est une excellente ressource pour toutes sortes de conseils liés à MySQL. Et ce n'est pas seulement MySQL, ils en savent aussi beaucoup sur le bon matériel ou recommandent des configurations pour AWS, etc. Ces types ont des années et des années d'expérience.

Une autre excellente ressource est , bien sûr, planet-mysql .


Je ne sais pas tuning primer, comment ça se compare mysqltuner?
greg0ire

38

Nous utilisons ces paramètres:

etc/my.cnf
innodb_buffer_pool_size = 384M
key_buffer = 256M
query_cache_size = 1M
query_cache_limit = 128M
thread_cache_size = 8
max_connections = 400
innodb_lock_wait_timeout = 100

pour un serveur avec les spécifications suivantes:

Dell Server
CPU cores: Two
Processor(s): 1x Dual Xeon
Clock Speed: >= 2.33GHz
RAM: 2 GBytes
Disks: 1×250 GB SATA

16
Je pense que vous (et l'auteur vers lequel vous créez un lien) avez query_cache_size et query_cache_limit dans le mauvais sens. Vous dites à MySQL: allouez un cache de 1 Mo mais n'y mettez aucune requête supérieure à 128 Mo. dev.mysql.com/doc/refman/5.0/en/query-cache-configuration.html
agtb

Je réduirais max_connections. Je déciderais quel moteur utiliser et n'allouerais pas beaucoup d'espace pour les deux.
Rick James

19

L'utilisation de la mémoire de la base de données est un sujet complexe. Le blog des performances MySQL fait un bon travail pour couvrir votre question et énumère de nombreuses raisons pour lesquelles il est extrêmement peu pratique de «réserver» de la mémoire.

Si vous voulez vraiment imposer une limite stricte, vous pouvez le faire, mais vous devrez le faire au niveau du système d'exploitation car il n'y a pas de paramètre intégré. Sous Linux, vous pouvez utiliser ulimit , mais vous devrez probablement modifier la façon dont MySQL démarre pour l'imposer.


La meilleure solution est de régler votre serveur, de sorte qu'une combinaison des paramètres habituels de la mémoire MySQL se traduise par une utilisation de la mémoire généralement inférieure par votre installation MySQL. Cela aura bien sûr un impact négatif sur les performances de votre base de données, mais certains des paramètres que vous pouvez modifier my.inisont:

key_buffer_size
query_cache_size
query_cache_limit
table_cache
max_connections
tmp_table_size
innodb_buffer_pool_size

Je commencerais par là et voir si vous pouvez obtenir les résultats que vous souhaitez. Il existe de nombreux articles sur l'ajustement des paramètres de mémoire MySQL.


Éditer:

Notez que certains noms de variables ont changé dans les nouvelles versions 5.1.x de MySQL .

Par exemple:

table_cache

Est maintenant:

table_open_cache

2
Salut! Merci pour votre réponse. J'ai remarqué que l'équation que les gens citent est la suivante: key_buffer_size + (read_buffer_size + sort_buffer_size) * max_connections = Mémoire totale. J'ai défini ce qui suit: key_buffer_size = 128M, read_buffer_size = 1M, sort_buffer_size = 2M, max_connections = 120, et la mémoire totale sur le serveur est de 512M. Cependant, après de nombreuses requêtes, la mémoire libre est descendue jusqu'à 12 Mo et continuerait probablement de diminuer avec une utilisation ultérieure. Y a-t-il une raison pour laquelle il en est ainsi et peut-on l'empêcher? Merci!

Ou peut-être que je dois prendre en considération non pas la mémoire totale sur le serveur (512M) mais la mémoire libre (c'est-à-dire la mémoire disponible après le chargement de tous les programmes liés au système d'exploitation et autres)?

1
Si vous allez modifier tmp_table_size dans le but d'augmenter la taille des tables temporaires qui peuvent être stockées dans la RAM, n'oubliez pas d'augmenter également max_heap_table_size - car MySQL utilise le minimum des deux ...
Dave Rix

1
@TimothyMilsud - Aucune formule comme celle-là ne fonctionne vraiment. Et la plupart des serveurs fonctionnent très bien lorsqu'une formule prétend que trop de RAM est utilisée.
Rick James

19

mysqld.exe utilisait 480 Mo de RAM. J'ai trouvé que j'ai ajouté ce paramètre à my.ini

table_definition_cache = 400

qui a réduit l'utilisation de la mémoire de plus de 400 000 Ko à 105 000 Ko


Dans quelle section cela va-t-il? Je l'ai ajouté au mien et le service a refusé de démarrer.
Erreur de syntaxe

Peu importe, je l'ai déplacé sous [wampmysqld] et cela a très bien fonctionné et a réduit considérablement la mémoire que j'utilisais. Je pense que cela a peut-être aussi accéléré mes pageloadhost local dans le processus, ils semblent plus rapides maintenant.
Erreur de syntaxe

Bien que la valeur par défaut et minimum soit de 400, qu'est-ce qui l'a amené à dépasser 400 dans votre cas?
Wadih M.

5

dans /etc/my.cnf:

[mysqld]
...

performance_schema = 0

table_cache = 0
table_definition_cache = 0
max-connect-errors = 10000

query_cache_size = 0
query_cache_limit = 0

...

Bon travail sur serveur avec 256 Mo de mémoire.


Pourquoi le table_definition_cache= 0? Une explication serait bien. Et en gros, vous ne mettez pas en cache les requêtes ... même effet si vous query_cache_type = 0:)
Khom Nazid

0

Si vous cherchez à optimiser votre conteneur docker mysql, la commande ci-dessous peut vous aider. J'ai pu exécuter le conteneur de docker mysql à partir d'un 480 Mo par défaut à seulement 100 Mo

docker run -d -p 3306: 3306 -e MYSQL_DATABASE = test -e MYSQL_ROOT_PASSWORD = tooor -e MYSQL_USER = test -e MYSQL_PASSWORD = test -v / mysql: / var / lib / mysql - mysqldb mysql --table_definition_cache = 100 --performance_schema = 0 --default-authentication-plugin = mysql_native_password

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.