Stiamo gestendo un sito (Moodle) che gli utenti attualmente trovano lento. Penso di aver rintracciato il problema su MySQL creando tabelle temporanee su disco. Osservo la variabile created_tmp_disk_tables
nell'amministrazione del server Mysql Workbench e il numero aumenta con circa 50 tabelle / s. Dopo un giorno di utilizzo, created_tmp_disk_tables
è> 100k. Inoltre, la memoria non sembra essere stata rilasciata. L'utilizzo continua ad aumentare fino a quando il sistema diventa praticamente inutilizzabile e dobbiamo riavviare MySQL. Ho bisogno di riavviarlo quasi ogni giorno e inizia con l'utilizzo di circa il 30-35% di memoria disponibile e terminando la giornata con l'80%.
Non ho BLOB nel database né controllo sulle query, quindi non posso tentare di ottimizzarle. Ho anche usato la procedura guidata di configurazione di Percona per generare un file di configurazione ma che my.ini non ha risolto il mio problema.
Domande
Cosa devo modificare per impedire a MySQL di creare tabelle temporanee su disco? Ci sono impostazioni che devo modificare? Devo buttargli più memoria?
Come posso impedire a MySQL di consumare la mia memoria?
modificare
Ho abilitato il slow_queries
registro e ho scoperto che la query SELECT GET_LOCK()
era registrata come lenta. Una rapida ricerca ha rivelato che avevo consentito connessioni persistenti nella configurazione di PHP ( mysqli.allow_persistent = ON
). L'ho spento. Ciò ha ridotto la velocità con cui MySQL consuma memoria, ma sta comunque creando tabelle temporanee.
Ho anche verificato che key_buffer size
sia abbastanza grande. Ho guardato la variabile key_writes
. Questo dovrebbe essere zero. In caso contrario, aumentare il key_buffer_size
. Ho zero key_reads
e zero, key_writes
quindi presumo che key_buffer_size
sia abbastanza grande.
Ho aumentato i tmp_table_size
e max-heap-table-size
a 1024M poiché un aumento di Created_tmp_disk_tables potrebbe indicare che le tabelle non possono essere contenute nella memoria. Questo non l'ha risolto.
Modifica 2
Se ne vedi molti sort_merge_passes
al secondo nell'output SHOW GLOBAL STATUS, puoi considerare di aumentare il sort_buffer_size
valore. Ne avevo 2 sort_merge_passes
in un'ora, quindi ritengo sort_buffer_size
che sia abbastanza grande.
Rif: Mysql Manual on sort_buffer_size
Modifica 3
Ho modificato l'ordinamento e l'aggiunta dei buffer come suggerito da @RolandoMySQLDBA. Il risultato è visualizzato nella tabella qui sotto ma penso che created_tmp_tables_on_disk
sia ancora alto. Ho riavviato il server mysql dopo aver modificato il valore e verificato il created_tmp_tables_on_disk
dopo un giorno (8h) e calcolato la media. Altri suggerimenti? Mi sembra che ci sia qualcosa che non rientra in una sorta di contenitore ma non riesco a capire di cosa si tratti.
+---------------------+-------------+-------------+--------------------+
| 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 |
+---------------------+-------------+-------------+--------------------+
Questa è la mia configurazione:
+-----------------------+-----------------------+
|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 |
+-----------------------+-----------------------+
Informazioni aggiuntive
+--------------------+---------+
|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|
+--------------------+---------+
Questa configurazione mi è stata fornita, quindi ho un controllo limitato su di essa. Il web server utilizza pochissima CPU e RAM, quindi ho escluso quella macchina come un collo di bottiglia. La maggior parte delle impostazioni di MySQL proviene da uno strumento di generazione automatica di configurazione.
Ho monitorato il sistema usando PerfMon per alcuni giorni rappresentativi. Da ciò, concludo che non è il sistema operativo che sta scambiando su disco.
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