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