MySQL 5.7 Tuning

Sul tuning di MySQL sono state pubbicate innumerevoli pagine nel web... ma MySQL ha avuto una continua evoluzione con nuovi algoritmi, nuovi parametri di tuning e variazioni sulle impostazioni di default. Con le ultime versioni 5.6 e 5.7 le variazioni sono state ancora piu' evidenti e quindi la maggior parte delle pagine sul tuning di MySQL nel web non sono piu' aggiornate ed affidabili!
Poiche' sono colpevole anch'io d'avere distribuito nel tempo su web esempi di my.cnf inaffidabili, ho deciso di rimediare con questo documento piu' aggiornato.

Questa semplice e pragmatica paginetta riporta quelli che sono i principali parametri di tuning di MySQL in versione 5.7 evitando di riportare i parametri non piu' significativi poiche' obsoleti.

Nel seguito sono riportate alcune informazioni di interesse organizzate in paragrafi specifici: Introduzione, Parametri principali, E se... (MyISAM, Query Cache, Replication), Varie ed eventuali.

Le indicazioni che seguono sono per un pubblico DBA adulto, per i minori o junior consigliamo la lettura di questo documento introduttivo, mentre le novita' della versione 5.7 sono riassunte in questo documento.

Introduzione

Il tuning di una base dati e' un'attivita' che richiede competenza ed esperienza. Se non sapete a cosa serve un parametro... non modificatelo!

Il tuning si fa se... serve. Se una base dati e' di modeste dimensioni, le applicazioni consolidate ed i sistemi correttamente dimensionati e' sufficiente un'impostazione iniziale ragionevole dei parametri e niente piu'.

Nessun tuning si sostituisce ad un disegno corretto della base dati e dell'SQL. Prima di qualsiasi altra attivita' vanno controllati evenuali statement di lunga durata e corretti quelli errati, vanno creati tutti gli indici necessari e, nei casi in cui opportuno, va utilizzato il partitioning e lo sharding.

Misurare, misurare, misurare! Misurare le prestazioni prima delle attivita' di tuning, misurare tutti i test eseguiti e continuare a misurare effettuata una modifica di parametri. Senza misure non si fa tuning. Quali misure? Tutte quelle che servono! In generale dipendono dall'applicazione e dall'utilizzo dei MySQL: TPS, MRT, #utenti, active threads, ... e dai sistemi ospite: %CPU, %IOW, LA, ... senza dimenticare le due principali: lo spazio ed il tempo (che come e' noto sono fisicamente legate tra loro :).

Parametri principali

Ecco l'elenco dei parametri in ordine di importanza! Naturalmente secondo il mio fallace personale giudizio...

E se...

Come cambiare la configurazione per ottimizzare le prestazioni se si utilizza...

Varie ed eventuali

Manca qualcosa? No: abbiamo descritto tutti i parametri utili!

In generale le configurazioni di default presenti nella 5.7 per tutti gli altri parametri sono gia' ottimali...
table_open_cache: era un parametro molto importante per il tuning ma il default e' passato a 2000 dalla 5.6 che e' un valore generalmente sufficiente; table_open_cache_instances: riduce le contese sui latch delle tabelle ma in 5.7 il default e' 16, adatto per sfruttare anche i piu' recenti processori multi-core; innodb_file_per_table: e' assolutamente conveniente abilitarlo, ma e' gia' cosi' per default; innodb_data_file_path: consente di specificare i file e la dimensione di cui e' composta la partizione InnoDB; era importante quando si aveva il limite dei 2GB sui file e non si poteva utilizzare innodb_file_per_table, ora non si ha la necessita' di utilizzarlo; log_bin: e' giustamente disabilitato (rallenta) per default, e' pero' necessario per la replica o il PITR, quindi se serve si abilita altrimenti lo si lascia disabilitato: e' inutile riportalo come parametro di tuning; binlog_format: tranne in rari casi l'impostazione piu' efficiente e' quella ROW che e' gia' il default nella 5.7, le alternative sono STATEMENT (utile per le prestazioni in qualche specifico caso) e MIXED; tmp_table_size e max_heap_table_size: vanno aumentati rispetto al default (16M) solo se il rapporto CREATED_TMP_DISK_TABLES / CREATED_TMP_TABLES e' elevato e comunque dopo aver corretto eventuali query mal scritte; sync_relay_log: ha un forte impatto prestazionale sullo slave se viene impostato =1 ma il default e' 10000; innodb_flush_method: non cambiatelo! la scelta del metodo di flush puo' essere importante per le prestazioni in alcuni casi ma per valutare se cambiare rispetto al default fsync (eg. impostandolo a O_DIRECT che evita il double buffering) e' opportuno un benchmark specifico sui dischi ed una conoscenza esatta del comportamento dello storage e del sistema operativo, alcune impostazioni sono corrette su versioni e file system specifici (eg. O_DIRECT_NO_FSYNC 5.7.25+)... insomma io non lo cambio o ne sapete piu' di me o non cambiatelo; innodb_buffer_pool_instances: indica il numero di regioni in cui il buffer pool e' diviso per ridurre le contese dei latch. E' un'ottimizzazione significativa... ma il valore di default e' gia' adatto alla maggioranza dei casi; innodb_deadlock_detect: e' un nuovo parametro di tuning disponibile nella 5.7. Di default e' ad ON ed e' consigliato nella maggior parte dei casi. Su un benchmark si puo' disattivare ma non e' tipicamente il caso su un sistema di produzione perche' piu' efficace del classico timeout; innodb_doublewrite: non cambiatelo! a meno che non stiate eseguendo un benchmark non e' il caso di rischiare la corruzione del DB; performance_schema: e' vero che ha un peso per le prestazioni, ma non e' consigliabile impostarlo ad OFF su un ambiente di produzione a meno che non siate certi della buona qualita' dell'SQL di tutte le applicazioni ospitate [NdA non sono tutti di questa opinione: su MariaDB per default e' disabilitato e lo stesso avviene con MySQL su Amazon RDS; al contrario Percona, benchmark alla mano, lo ritiene poco invasivo]; quando Qcache_lowmem_prunes e' elevato manca memoria alla query cache; oltre alla query_cache_size si puo' impostare la dimensione dell'allocazione per query query_cache_min_res_unit; il default e' 4KB, se le query hanno un risultato di dimensioni ridotte si puo' abbassare ma il tuning richiede l'analisi dei valori di Qcache_total_blocks e Qcache_queries_in_cache nel tempo... innodb_lru_scan_depth: il default (1024) va bene anche se ammetto di averlo abbassato a 256 in un paio di casi, toccare altri parametri (eg. innodb_io_capacity_max, innodb_io_capacity, innodb_page_cleaners, ...) va fatto dopo prove specifiche e si conosce esattamente come agiscono; spesso sono presenti attese su lock che attendono fino a innodb_lock_wait_timeout, anche se e' possibile monitorarle con INNODB_ROW_LOCK_TIME, INNODB_ROW_LOCK_WAITS, INNODB_ROW_LOCK_CURRENT_WAITS, ... tipicamente non si puo' fare molto dal punto di vista del tuning ma solo agire sull'applicazione; max_allowed_packet: e' un parametro che spesso si modifica, ma non e' un parametro prestazionale; vm.swappiness: da impostare sempre a 1 su un DB server, ma e' un parametro del sistema operativo! ...


Manca qualcosa? Sicuramente si!

Sarebbe un grave errore pensare di poter riassumere tutto in una paginetta. I parametri MySQL della versione 5.7 sono centinaia e sono tutti importanti per sfruttare le funzionalita' ed ottenere le massime performance con MySQL.


Titolo: MySQL 5.7 Tuning
Livello: Esperto (4/5)
Data: 1 Aprile 2015
Versione: 1.0.7 - 14 Febbraio 2019 ❤️ San Valentino
Autore: mail [AT] meo.bogliolo.name