Wir betreiben eine Website (Moodle), die die Benutzer derzeit als langsam empfinden. Ich glaube, ich habe das Problem damit aufgespürt, dass MySQL temporäre Tabellen auf der Festplatte erstellt. Ich beobachte die Variable created_tmp_disk_tables
in der Mysql Workbench-Serververwaltung und die Anzahl steigt mit ungefähr 50 Tabellen / s. Nach einem Tagesgebrauch created_tmp_disk_tables
ist> 100k. Auch scheint der Speicher nicht freigegeben zu werden. Die Nutzung nimmt weiter zu, bis das System praktisch unbrauchbar wird und wir MySQL neu starten müssen. Ich muss es fast jeden Tag neu starten und es beginnt damit, dass ich ungefähr 30-35% des verfügbaren Speichers verwende und den Tag mit 80% beende.
Ich habe keine Blobs in der Datenbank und auch keine Kontrolle über die Abfragen, sodass ich nicht versuchen kann, sie zu optimieren. Ich habe auch den Percona-Konfigurationsassistenten verwendet , um eine Konfigurationsdatei zu generieren, aber meine.ini hat auch mein Problem nicht gelöst.
Fragen
Was sollte ich ändern, um zu verhindern, dass MySQL temporäre Tabellen auf der Festplatte erstellt? Gibt es Einstellungen, die ich ändern muss? Soll ich mehr Speicher darauf werfen?
Wie kann ich verhindern, dass MySQL mein Gedächtnis aufzehrt?
Bearbeiten
Ich habe das slow_queries
Protokoll aktiviert und festgestellt, dass die Abfrage SELECT GET_LOCK()
als langsam protokolliert wurde. Eine schnelle Suche ergab, dass ich dauerhafte Verbindungen in der PHP-Konfiguration zugelassen hatte ( mysqli.allow_persistent = ON
). Ich habe das ausgeschaltet. Dies reduzierte die Rate, mit der MySQL Speicher verbraucht. Es werden jedoch immer noch temporäre Tabellen erstellt.
Ich habe auch nachgesehen, dass das key_buffer size
groß genug ist. Ich schaute auf die Variable key_writes
. Dies sollte Null sein. Wenn nicht, erhöhen Sie die key_buffer_size
.Ich habe Null key_reads
und Null, key_writes
so dass ich davon ausgehe , dass die key_buffer_size
groß genug ist.
Ich habe das tmp_table_size
und max-heap-table-size
auf 1024 MB erhöht, da eine Erhöhung in created_tmp_disk_tables möglicherweise darauf hinweist, dass die Tabellen nicht in den Speicher passen. Das hat es nicht gelöst.
Bearbeiten 2
Wenn sort_merge_passes
in der Ausgabe von SHOW GLOBAL STATUS viele pro Sekunde angezeigt werden, können Sie den sort_buffer_size
Wert erhöhen . Ich hatte 2 sort_merge_passes
in einer Stunde, also halte ich das sort_buffer_size
für groß genug.
Ref: MySQL Handbuch auf sort_buffer_size
Bearbeiten 3
Ich habe die Sortier- und Verknüpfungspuffer geändert, wie von @RolandoMySQLDBA vorgeschlagen. Das Ergebnis wird in der folgenden Tabelle angezeigt, aber ich denke, das created_tmp_tables_on_disk
ist immer noch hoch. Ich habe den MySQL-Server neu gestartet, nachdem ich den Wert geändert und created_tmp_tables_on_disk
nach einem Tag (8 Stunden) überprüft und den Durchschnitt berechnet habe. Irgendwelche anderen Vorschläge? Es scheint mir, dass es etwas gibt, das nicht in eine Art Behälter passt, aber ich kann nicht herausfinden, was es ist.
+---------------------+-------------+-------------+--------------------+
| 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 |
+---------------------+-------------+-------------+--------------------+
Das ist meine Konfiguration:
+-----------------------+-----------------------+
|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 |
+-----------------------+-----------------------+
Zusätzliche Information
+--------------------+---------+
|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|
+--------------------+---------+
Dieses Setup wurde mir gegeben, damit ich nur begrenzte Kontrolle darüber habe. Der Webserver verwendet sehr wenig CPU und RAM, daher habe ich diesen Computer als Engpass ausgeschlossen. Ein Großteil der MySQL-Einstellungen stammt aus einem Konfigurationswerkzeug zur automatischen Generierung.
Ich habe das System über einige repräsentative Tage hinweg mit PerfMon überwacht. Daraus schließe ich, dass nicht das Betriebssystem auf die Festplatte wechselt.
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