Nous gérons un site (Moodle) que les utilisateurs trouvent actuellement lent. Je pense que j'ai trouvé le problème de la création de tables temporaires sur disque par MySQL. Je regarde la variable created_tmp_disk_tables
dans l'administration du serveur Mysql Workbench et le nombre augmente avec environ 50 tables / s. Après une utilisation de jours, created_tmp_disk_tables
est> 100k. De plus, la mémoire ne semble pas être libérée. L'utilisation continue d'augmenter jusqu'à ce que le système devienne à peu près inutilisable et que nous devions redémarrer MySQL. Je dois le redémarrer presque tous les jours et cela commence par utiliser environ 30 à 35% de la mémoire disponible et terminer la journée à 80%.
Je n'ai aucun blob dans la base de données et aucun contrôle sur les requêtes non plus, je ne peux donc pas essayer de les optimiser. J'ai également utilisé l' assistant de configuration de Percona pour générer un fichier de configuration, mais mon.ini n'a pas non plus résolu mon problème.
Des questions
Que dois-je changer pour empêcher MySQL de créer des tables temporaires sur le disque? Y a-t-il des paramètres que je dois modifier? Dois-je y jeter plus de mémoire?
Comment puis-je empêcher MySQL de manger ma mémoire?
modifier
J'ai activé le slow_queries
journal et découvert que la requête SELECT GET_LOCK()
était enregistrée comme lente. Une recherche rapide a révélé que j'avais autorisé des connexions persistantes dans la configuration PHP ( mysqli.allow_persistent = ON
). J'ai désactivé cela. Cela a réduit la vitesse à laquelle MySQL consomme de la mémoire, mais crée toujours des tables temporaires.
J'ai également vérifié que la key_buffer size
taille est suffisamment grande. J'ai regardé la variable key_writes
. Cela devrait être nul. Sinon, augmentez le . J'ai key_buffer_size
zéro key_reads
et zéro key_writes
donc je suppose que le key_buffer_size
est assez grand.
J'ai augmenté le tmp_table_size
et max-heap-table-size
à 1024M car une augmentation de created_tmp_disk_tables peut indiquer que les tables ne peuvent pas tenir en mémoire. Cela ne l'a pas résolu.
Modifier 2
Si vous voyez plusieurs sort_merge_passes
par seconde dans la sortie SHOW GLOBAL STATUS, vous pouvez envisager d'augmenter la sort_buffer_size
valeur. J'en ai eu 2 sort_merge_passes
en une heure donc je considère que sort_buffer_size
c'est assez grand.
Ref: Manuel Mysql sur sort_buffer_size
Modifier 3
J'ai modifié les tampons de tri et de jointure comme suggéré par @RolandoMySQLDBA. Le résultat est affiché dans le tableau ci-dessous mais je pense que le created_tmp_tables_on_disk
reste est élevé. J'ai redémarré le serveur mysql après avoir changé la valeur et vérifié created_tmp_tables_on_disk
après une journée (8h) et calculé la moyenne. D'autres suggestions? Il me semble qu'il y a quelque chose qui ne rentre pas dans une sorte de récipient mais je ne peux pas comprendre ce que c'est.
+---------------------+-------------+-------------+--------------------+
| Tmp_table_size, | Sort_buffer | Join_buffer | No of created |
| max_heap_table_size | | | tmp_tables on disk |
+---------------------+-------------+-------------+--------------------+
| 125M | 256K | 256K | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 512K | 512K | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 1M | 1M | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 4M | 4M | 100k/h |
+---------------------+-------------+-------------+--------------------+
Voici ma configuration:
+-----------------------+-----------------------+
|DATABASE SERVER |WEB SERVER |
+-----------------------+-----------------------+
|Windows Server 2008 R2 |Windows Server 2008 R2 |
+-----------------------+-----------------------+
|MySQL 5.1.48 |IIS 7.5 |
+-----------------------+-----------------------+
|4 Core CPU |4 Core CPU |
+-----------------------+-----------------------+
|4GB RAM |8GB RAM |
+-----------------------+-----------------------+
Information additionnelle
+--------------------+---------+
|PARAM |VALUE |
+--------------------+---------+
|Num of tables in Db |361 |
+--------------------+---------+
|Size of database |2.5G |
+--------------------+---------+
|Database engine |InnoDB |
+--------------------+---------+
|Read/write ratio |3.5 |
|(Innodb_data_read/ | |
|innodb_data_written)| |
+--------------------+---------+
|Avg table size |15k rows |
+--------------------+---------+
|Max table size |744k rows|
+--------------------+---------+
Cette configuration m'a été donnée, j'ai donc un contrôle limité sur elle. Le serveur Web utilise très peu de CPU et de RAM, j'ai donc exclu cette machine comme goulot d'étranglement. La majorité des paramètres MySQL provient d'un outil de génération automatique de configuration.
J'ai surveillé le système à l'aide de PerfMon pendant quelques jours représentatifs. De là, je conclus que ce n'est pas le système d'exploitation qui échange sur le disque.
My.ini
[client]
port=3306
[mysql]
default-character-set=utf8
[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.1/"
datadir="D:/DBs/Data/"
default-character-set=utf8
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=125
query_cache_size=350M
table_cache=1520
tmp_table_size=125M
table-definition-cache= 1024
max-heap-table-size= 32M
thread_cache_size=38
MyISAM Specific options
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=125M
key_buffer_size=55M
read_buffer_size=1024K
read_rnd_buffer_size=256K
sort_buffer_size=1024K
join_buffer_size=1024K
INNODB Specific options
innodb_data_home_dir="D:/DBs/"
innodb_additional_mem_pool_size=32M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=16M
innodb_buffer_pool_size=2G
innodb_log_file_size=407M
innodb_thread_concurrency=8
Réponses:
En regardant le
my.ini
, j'ai deux suggestionsSUGGESTION # 1
Je voudrais augmenter les paramètres suivants dans votre
my.ini
Cela fera que certaines jointures et tri resteront en mémoire. Bien sûr, une fois que a
JOIN
ou aORDER BY
besoin de plus4M
, il se paginera sur le disque en tant que table MyISAM.Si vous ne pouvez pas vous connecter en tant que
root@localhost
, redémarrez mysql avecSi vous pouvez vous connecter en tant que root @ localhost, vous n'avez pas besoin de redémarrer mysql pour utiliser ces paramètres.
Exécutez simplement ceci dans le client MySQL:
SUGGESTION # 2
Étant donné que vos données sont sur le lecteur
D:
, vous pouvez avoir des E / S disque sur le lecteurC:
.Veuillez exécuter cette requête:
Puisque j'exécute mysql sur mon bureau avec des valeurs par défaut, mes tables temporaires sont écrites sur Drive
C:
. Si le lecteur D est un meilleur disque que lecteurC:
, vous pouvez peut - être mapper des tables temporaires à disqueD:
en définissant tmpdir dans lamy.ini
manière suivante:Vous devrez redémarrer mysql car tmpdir n'est pas une variable dynamique.
Essaie !!!
MISE À JOUR 2013-11-29 10:09 EST
SUGGESTION # 3
Étant donné que MySQL fonctionne sous Windows et que vous ne pouvez pas toucher aux requêtes dans le package de base, j'ai deux idées à faire ensemble.
IDÉE # 1: déplacer la base de données vers une machine Linux
Tu devrais être capable de
IDÉE # 2: Reconfigurez Moodle pour pointer vers la machine Linux
Moodle a été conçu pour LAMP en premier lieu. Modifiez simplement les fichiers de configuration pour pointer vers la machine Linux au lieu de localhost.
Voici un lien vers un ancien document Moodle 2.3 sur la configuration de MySQL: http://docs.moodle.org/23/en/Installing_Moodle#Create_an_empty_database
Je suis sûr que les derniers documents sont également disponibles.
Quel est l'intérêt de déplacer la base de données vers Linux ???
Comment cela aide-t-il la situation de la table temporaire ???
Je suggérerais alors de configurer un disque RAM comme dossier cible pour vos tables temporaires
Jan 04, 2013
: Existe - t-il un moteur MySQL ou une astuce pour éviter d'écrire autant de tables temporaires sur le disque?Dec 17, 2012
: Pourquoi MySQL produit-il autant de fichiers temporaires MYD? (Instructions réelles)Nov 30, 2012
: Est-il mauvais de créer plusieurs tables temporaires mysql simultanément?La création de la table temporaire se fera toujours, mais elle sera écrite sur la RAM plutôt que sur le disque. réduction des E / S disque.
MISE À JOUR 2013-11-29 11:24 EST
SUGGESTION # 4
Je suggérerais de revoir SUGGESTION # 2 avec un disque RAID-0 rapide (32+ Go), en le configurant comme lecteur T: (T pour Temp). Après avoir installé un tel disque, ajoutez ceci à
my.ini
:Un redémarrage de MySQL serait nécessaire, en utilisant
BTW J'ai dit RAID-0 exprès afin que vous puissiez obtenir de bonnes performances d'écriture sur un RAID-1, RAID-10. Un disque de table tmp n'est pas quelque chose que je rendrais redondant.
Sans optimiser les requêtes comme @RaymondNijland l'a commenté, vous ne pouvez en aucun cas réduire le nombre de création de table temporaire.
SUGGESTION #3
etSUGGESTION #4
proposent d'accélérer la création de tables temporaires et les E / S de tables temporaires comme seule alternative.la source
Je réponds à ma propre question ici pour être complet
Je vais sélectionner @RolandoMySQLDBA comme réponse préférée car cela m'a donné le plus d'indices même si cela n'a pas vraiment résolu mon problème.
Voici les résultats de mon enquête
Conclusion
MySQL sur Windows crée juste beaucoup de tables temporaires et le réglage de MySQL en modifiant le contenu des fichiers de configuration n'a pas aidé.
Détails
Le tableau détaille les paramètres que j'ai modifiés dans my.ini respectivement avant d'exécuter les requêtes. MySQL a été redémarré entre chaque test.
J'ai utilisé le my.ini trouvé dans la question d'origine comme modèle et j'ai ensuite changé la valeur des paramètres un par un selon le tableau ci-dessous.
J'ai utilisé JMeter pour générer 100 requêtes Web simultanées (car cela représentait notre utilisation) répétées 10 dix fois. Chacun
Test
consistait donc en 1 000 demandes au total. Cela a entraîné des appels de base de données ultérieurs. Cela a montré que MySQL créerait de nombreuses tables temporaires quels que soient les paramètres de configuration que nous avons modifiés.* Moyenne de trois runs
Les images ci-dessous illustrent la quantité de mémoire et de CPU requise par le serveur de base de données pour les différentes configurations. Les lignes noires indiquent les valeurs minimale et maximale et les barres bleues indiquent les valeurs de début et de fin. La mémoire maximale était
4096M
celle indiquée dans la question.la source