Mysql
 sql >> Database >  >> RDS >> Mysql

Foglio informativo sulle prestazioni di MySQL

MySQL è ampio e ha molte aree da ottimizzare e modificare per ottenere le prestazioni desiderate. Alcune modifiche possono essere eseguite dinamicamente, altre richiedono il riavvio del server. È abbastanza comune trovare un'installazione MySQL con una configurazione predefinita, anche se quest'ultima potrebbe non essere appropriata di per sé dal carico di lavoro e dalla configurazione.

Ecco le aree chiave in MySQL che ho preso da diverse fonti esperte nel mondo MySQL, così come le nostre esperienze qui a Diversinines. Questo blog fungerà da cheat sheet per ottimizzare le prestazioni e rendere di nuovo eccezionale il tuo MySQL :-)

Diamo un'occhiata a questi delineando le aree chiave in MySQL.

Variabili di sistema

MySQL ha molte variabili che puoi considerare di cambiare. Alcune variabili sono dinamiche, il che significa che possono essere impostate utilizzando l'istruzione SET. Altri richiedono il riavvio del server, dopo che sono stati impostati nel file di configurazione (ad es. /etc/my.cnf, etc/mysql/my.cnf). Tuttavia, esaminerò le cose comuni che sono abbastanza comuni da ottimizzare per ottimizzare il server.

ordina_dimensione_buffer

Questa variabile controlla la dimensione del buffer di filesort, il che significa che ogni volta che una query deve ordinare le righe, il valore di questa variabile viene utilizzato per limitare la dimensione che deve essere allocata. Tieni presente che questa variabile è per query che viene elaborata (o per connessione), il che significa che sarebbe affamato di memoria quando lo imposti più alto e se hai più connessioni che richiedono l'ordinamento delle tue righe. Tuttavia, puoi monitorare le tue esigenze controllando la variabile di stato globale Sort_merge_passes. Se questo valore è grande, dovresti considerare di aumentare il valore della variabile di sistema sort_buffer_size. Altrimenti, portalo al limite moderato di cui hai bisogno. Se lo imposti troppo basso o se hai query di grandi dimensioni da elaborare, l'effetto dell'ordinamento delle righe può essere più lento del previsto perché i dati vengono recuperati in modo casuale eseguendo immersioni su disco. Ciò può causare un degrado delle prestazioni. Tuttavia, è meglio risolvere le tue domande. In caso contrario, se l'applicazione è progettata per eseguire query di grandi dimensioni e richiede l'ordinamento, è efficiente utilizzare strumenti che gestiscono la memorizzazione nella cache delle query come Redis. Per impostazione predefinita, in MySQL 8.0, il valore corrente impostato è 256 KiB. Impostalo di conseguenza solo quando hai query che utilizzano o chiamano in modo intensivo gli ordinamenti.

read_buffer_size

La documentazione di MySQL menziona che per ogni richiesta che esegue una scansione sequenziale di una tabella, alloca un buffer di lettura. La variabile di sistema read_buffer_size determina la dimensione del buffer. È utile anche per MyISAM, ma questa variabile interessa anche tutti i motori di archiviazione. Per le tabelle MEMORY, viene utilizzato per determinare la dimensione del blocco di memoria.

Fondamentalmente, ogni thread che esegue una scansione sequenziale per una tabella MyISAM alloca un buffer di questa dimensione (in byte) per ogni tabella che scansiona. Si applica anche a tutti i motori di archiviazione (che include InnoDB), quindi è utile per le query che ordinano le righe utilizzando ORDER BY e memorizzano nella cache i suoi indici in un file temporaneo. Se esegui molte scansioni sequenziali, inserisci in blocco le tabelle delle partizioni, memorizzando nella cache i risultati delle query nidificate, quindi considera di aumentarne il valore. Il valore di questa variabile dovrebbe essere un multiplo di 4 KB. Se è impostato su un valore che non è un multiplo di 4 KB, il suo valore verrà arrotondato per difetto al multiplo di 4 KB più vicino. Tieni presente che impostarlo su un valore più alto consumerà una grossa fetta della memoria del tuo server. Suggerisco di non usarlo senza un adeguato benchmarking e monitoraggio del tuo ambiente.

read_rnd_buffer_size

Questa variabile si occupa della lettura delle righe da una tabella MyISAM in ordine ordinato dopo un'operazione di ordinamento delle chiavi, le righe vengono lette attraverso questo buffer per evitare ricerche sul disco. La documentazione dice, quando si leggono le righe in una sequenza arbitraria o da una tabella MyISAM in ordine ordinato dopo un'operazione di ordinamento delle chiavi, le righe vengono lette attraverso questo buffer (e determinate attraverso questa dimensione del buffer) per evitare ricerche sul disco. L'impostazione della variabile su un valore elevato può migliorare notevolmente le prestazioni di ORDER BY. Tuttavia, questo è un buffer allocato per ogni client, quindi non dovresti impostare la variabile globale su un valore grande. Modificare invece la variabile di sessione solo da quei client che devono eseguire query di grandi dimensioni. Tuttavia, dovresti tenere conto del fatto che questo non si applica a MariaDB, specialmente quando si sfrutta MRR. MariaDB usa mrr_buffer_size mentre MySQL usa read_buffer_size read_rnd_buffer_size.

join_buffer_size

Per impostazione predefinita, il valore è di 256K. La dimensione minima del buffer utilizzato per scansioni di indici semplici, scansioni di indici di intervallo e join che non utilizzano indici e quindi eseguono scansioni di tabelle complete. Utilizzato anche dall'ottimizzazione BKA (disabilitata per impostazione predefinita). Aumenta il suo valore per ottenere join completi più rapidi quando l'aggiunta di indici non è possibile. Avvertimento, tuttavia, potrebbero essere problemi di memoria se lo si imposta su un valore troppo alto. Ricorda che viene allocato un buffer di join per ogni join completo tra due tabelle. Per un join complesso tra più tabelle per le quali non vengono utilizzati gli indici, potrebbero essere necessari più buffer di join. È meglio lasciare basso a livello globale e impostare alto nelle sessioni (usando la sintassi SET SESSION) che richiedono full join di grandi dimensioni. Nelle piattaforme a 64 bit, Windows tronca i valori superiori a 4 GB a 4 GB-1 con un avviso.

max_heap_table_size

Questa è la dimensione massima in byte per cui le tabelle MEMORY create dall'utente possono crescere. Ciò è utile quando l'applicazione gestisce le tabelle del motore di archiviazione MEMORY. L'impostazione della variabile mentre il server è attivo non ha alcun effetto sulle tabelle esistenti a meno che non vengano ricreate o modificate. Il più piccolo di max_heap_table_size e tmp_table_size limita anche le tabelle in memoria interne. Questa variabile è anche unita a tmp_table_size per limitare la dimensione delle tabelle interne in memoria (questo differisce dalle tabelle create esplicitamente come Engine=MEMORY in quanto si applica solo max_heap_table_size), il più piccolo viene applicato tra i due.

tmp_table_size

La dimensione più grande per le tabelle temporanee in memoria (non le tabelle MEMORY), anche se se max_heap_table_size è inferiore verrà applicato il limite inferiore. Se una tabella temporanea in memoria supera il limite, MySQL la converte automaticamente in una tabella temporanea su disco. Aumenta il valore di tmp_table_size (e max_heap_table_size se necessario) se esegui molte query GROUP BY avanzate e hai ampio spazio di memoria disponibile. È possibile confrontare il numero di tabelle temporanee interne su disco create con il numero totale di tabelle temporanee interne create confrontando i valori delle variabili Created_tmp_disk_tables e Created_tmp_tables. In ClusterControl, puoi monitorarlo tramite Dashboard -> Grafico Oggetti temporanei.

table_open_cache

È possibile aumentare il valore di questa variabile se si dispone di un numero elevato di tabelle a cui si accede frequentemente nel set di dati. Verrà applicato a tutti i thread, ovvero per base di connessione. Il valore indica il numero massimo di tabelle che il server può mantenere aperte in una qualsiasi istanza della cache delle tabelle. Sebbene l'aumento di questo valore aumenti il ​​numero di descrittori di file richiesti da mysqld, potresti anche considerare di controllare il tuo valore open_files_limit o controllare quanto è grande il limite SOFT e HARD impostato nel tuo sistema operativo *nix. Puoi monitorarlo se devi aumentare la cache della tabella controllando la variabile di stato Opened_tables. Se il valore di Opened_tables è grande e non usi FLUSH TABLES spesso (che forza semplicemente la chiusura e la riapertura di tutte le tabelle), allora dovresti aumentare il valore della variabile table_open_cache. Se si dispone di un valore basso per table_open_cache e si accede frequentemente a un numero elevato di tabelle, ciò può influire sulle prestazioni del server. Se noti molte voci nell'elenco dei processi MySQL con lo stato "Tabelle di apertura" o "Tabelle di chiusura", è il momento di regolare il valore di questa variabile, ma prendi nota dell'avvertenza menzionata in precedenza. In ClusterControl, puoi verificarlo in Dashboard -> Table Open Cache Status o Dashboard -> Open Tables. Puoi controllarlo qui per maggiori informazioni.

table_open_cache_instances

L'impostazione di questa variabile aiuterebbe a migliorare la scalabilità e, naturalmente, le prestazioni che ridurrebbero la contesa tra le sessioni. Il valore impostato qui limita il numero di istanze cache di tabelle aperte. La cache delle tabelle aperte può essere partizionata in diverse istanze cache più piccole di dimensioni table_open_cache/table_open_cache_instances. Una sessione deve bloccare solo un'istanza per accedervi per le istruzioni DML. Questo segmenta l'accesso alla cache tra le istanze, consentendo prestazioni più elevate per le operazioni che utilizzano la cache quando ci sono molte sessioni che accedono alle tabelle. (Le istruzioni DDL richiedono ancora un blocco dell'intera cache, ma tali istruzioni sono molto meno frequenti delle istruzioni DML.) Un valore di 8 o 16 è consigliato sui sistemi che utilizzano abitualmente 16 o più core.

table_definition_cache

Definizioni delle tabelle della cache, ad esempio qui è dove vengono memorizzate nella cache CREATE TABLE per accelerare l'apertura delle tabelle e solo una voce per tabella. Sarebbe ragionevole aumentare il valore se si dispone di un numero elevato di tabelle. La cache di definizione della tabella occupa meno spazio e non utilizza descrittori di file, a differenza della normale cache delle tabelle. Peter Zaitsev di Percona suggerisce se puoi provare l'impostazione della formula seguente,

The number of user-defined tables + 10% unless 50K+ tables

Ma tieni presente che il valore predefinito si basa sulla seguente formula con un limite di 2000.

MIN(400 + table_open_cache / 2, 2000)

Quindi, nel caso in cui tu abbia un numero di tabelle maggiore rispetto a quello predefinito, è ragionevole aumentarne il valore. Tieni presente che con InnoDB, questa variabile viene utilizzata come limite morbido del numero di istanze di tabelle aperte per la cache del dizionario dei dati. Applicherà il meccanismo LRU una volta che supera il valore corrente di questa variabile. Il limite aiuta a risolvere le situazioni in cui quantità significative di memoria verrebbero utilizzate per memorizzare nella cache istanze di tabelle utilizzate raramente fino al successivo riavvio del server. Pertanto, le istanze di tabella padre e figlio con relazioni di chiave esterna non vengono inserite nell'elenco LRU e potrebbero imporre un limite superiore al limite definito da table_definition_cache e non sono soggette a rimozione in memoria durante LRU. Inoltre, table_definition_cache definisce un limite morbido per il numero di tablespace file per tabella InnoDB che possono essere aperti contemporaneamente, anch'esso controllato da innodb_open_files e infatti, viene utilizzata l'impostazione più alta tra queste variabili, se sono impostate entrambe . Se nessuna delle variabili è impostata, viene utilizzata table_definition_cache, che ha un valore predefinito più alto. Se il numero di handle di file tablespace aperti supera il limite definito da table_definition_cache o innodb_open_files, il meccanismo LRU ricerca nell'elenco LRU dei file tablespace i file che sono stati completamente svuotati e non sono attualmente estesi. Questo processo viene eseguito ogni volta che viene aperto un nuovo tablespace. Se non sono presenti tablespace "inattivi", nessun file tablespace viene chiuso. Quindi tienilo a mente.

pacchetto_massimo_consentito

Questa è la dimensione massima per connessione di una query SQL o di una riga restituita. Il valore è stato aumentato l'ultima volta in MySQL 5.6. Tuttavia in MySQL 8.0 (almeno su 8.0.3), il valore predefinito corrente è 64 MiB. Potresti considerare di modificarlo se hai righe BLOB di grandi dimensioni che devono essere estratte (o lette), altrimenti puoi lasciare queste impostazioni predefinite con 8.0 ma nelle versioni precedenti, l'impostazione predefinita è 4 MiB, quindi potresti occupartene nel caso in cui tu incontra l'errore ER_NET_PACKET_TOO_LARGE. Il pacchetto più grande possibile che può essere trasmesso da o verso un server o client MySQL 8.0 è 1 GB.

skip_name_resolve Il server MySQL gestisce le connessioni in entrata in base alla risoluzione del nome host. Per impostazione predefinita, MySQL non disabilita alcuna risoluzione del nome host, il che significa che eseguirà una ricerca DNS e, per caso, se il DNS è lento, potrebbe essere la causa di prestazioni pessime per il tuo database. Prendi in considerazione l'attivazione se non hai bisogno della risoluzione DNS e sfrutta il miglioramento delle prestazioni di MySQL quando questa ricerca DNS è disabilitata. Tieni presente che questa variabile non è dinamica, quindi è necessario un riavvio del server se lo imposti nel tuo file di configurazione MySQL. Puoi facoltativamente avviare il demone mysqld, passando l'opzione --skip-name-resolve per abilitarlo.

max_connessioni

Questo è il numero di connessioni consentite per il tuo server MySQL. Se trovi l'errore in MySQL "Troppe connessioni", potresti considerare di impostarlo su un valore più alto. Di default il valore di 151 non è sufficiente soprattutto su un database di produzione, e considerando che hai maggiori risorse del server (non sprecare le risorse del tuo server soprattutto se si tratta di un server MySQL dedicato). Tuttavia, devi avere abbastanza descrittori di file, altrimenti li esaurirai. In tal caso, considera la possibilità di modificare il limite SOFT e HARD dei tuoi sistemi operativi *nix e impostare un valore più alto di open_files_limit in MySQL (5000 è il limite predefinito). Tieni presente che è molto frequente che l'applicazione non chiuda correttamente le connessioni al database e l'impostazione di un max_connections elevato può comportare una mancata risposta o un carico elevato del server. L'utilizzo di un pool di connessioni a livello di applicazione può aiutare a risolvere il problema qui.

thread_cache_size

Questa è la cache per impedire la creazione eccessiva di thread. Quando un client si disconnette, i thread del client vengono inseriti nella cache se sono presenti meno thread thread_cache_size. Le richieste di thread vengono soddisfatte riutilizzando i thread presi dalla cache, se possibile, e solo quando la cache è vuota viene creato un nuovo thread. Questa variabile può essere aumentata per migliorare le prestazioni se hai molte nuove connessioni. Normalmente, questo non fornisce un notevole miglioramento delle prestazioni se si dispone di una buona implementazione del thread. Tuttavia, se il tuo server vede centinaia di connessioni al secondo, dovresti normalmente impostare thread_cache_size sufficientemente alto in modo che la maggior parte delle nuove connessioni utilizzi thread memorizzati nella cache. Esaminando la differenza tra le variabili di stato Connections e Threads_created, puoi vedere quanto è efficiente la cache dei thread. Utilizzando la formula indicata nella documentazione, 8 + (max_connections / 100) è abbastanza buono.

query_cache_size

Per alcune impostazioni, questa variabile è il loro peggior nemico. Per alcuni sistemi che subiscono un carico elevato e sono impegnati con letture elevate, questa variabile ti impantanerà. Ci sono stati benchmark che sono stati ben testati, ad esempio, da Percona. Questa variabile deve essere impostata su 0 insieme a query_cache_type =0 per disattivarla. La buona notizia in MySQL 8.0 è che il team MySQL ha smesso di supportarlo, poiché questa variabile può davvero causare problemi di prestazioni. Devo concordare sul loro blog che è improbabile che migliori la prevedibilità delle prestazioni. Se sei impegnato a utilizzare la cache delle query, ti suggerisco di utilizzare Redis o ProxySQL.

Motore di archiviazione - InnoDB

InnoDB è un motore di archiviazione conforme ad ACID con varie funzionalità da offrire insieme al supporto per chiavi esterne (Dichiarative Referential Integrity). Questo ha molte cose da dire qui, ma alcune variabili da considerare per l'ottimizzazione:

innodb_buffer_pool_size

Questa variabile agisce come un buffer chiave di MyISAM ma ha molte cose da offrire. Poiché InnoDB fa molto affidamento sul pool di buffer, potresti considerare di impostare questo valore in genere sul 70% -80% della memoria del tuo server. È inoltre vantaggioso disporre di uno spazio di memoria maggiore rispetto al set di dati e impostare un valore più elevato per il pool di buffer, ma non di troppo. In ClusterControl, questo può essere monitorato utilizzando il nostro grafico Dashboards -> InnoDB Metrics -> InnoDB Buffer Pool Pages. Puoi anche monitorarlo con SHOW GLOBAL STATUS usando le variabili Innodb_buffer_pool_pages*.

innodb_buffer_pool_instances

Per il carico di lavoro della concorrenza, l'impostazione di questa variabile può migliorare la concorrenza e ridurre la contesa come thread diversi di lettura/scrittura su pagine memorizzate nella cache. Il minimo innodb_buffer_pool_instances dovrebbe essere compreso tra 1 (minimo) e 64 (massimo). Ogni pagina memorizzata o letta dal pool di buffer viene assegnata a una delle istanze del pool di buffer in modo casuale, utilizzando una funzione di hashing. Ciascun pool di buffer gestisce le proprie liste libere, flush list, LRU e tutte le altre strutture dati connesse a un pool di buffer ed è protetto dal proprio mutex del pool di buffer. Tieni presente che questa opzione ha effetto solo quando innodb_buffer_pool_size>=1GiB e la sua dimensione è divisa tra le istanze del pool di buffer.

innodb_log_file_size

Questa variabile è il file di registro in un gruppo di registri. La dimensione combinata dei file di registro (innodb_log_file_size * innodb_log_files_in_group) non può superare un valore massimo leggermente inferiore a 512 GB. Secondo Vadim, una dimensione del file di registro più grande è migliore per le prestazioni, ma ha uno svantaggio (importante) di cui devi preoccuparti:il tempo di ripristino dopo un arresto anomalo. È necessario bilanciare i tempi di ripristino nel raro caso di un ripristino in caso di arresto anomalo rispetto alla massimizzazione del throughput durante le operazioni di picco. Questa limitazione può tradursi in un processo di ripristino da arresto anomalo 20 volte più lungo!

Per elaborarlo, un valore maggiore sarebbe utile per i registri delle transazioni InnoDB e sono fondamentali per prestazioni di scrittura buone e stabili. Maggiore è il valore, minore è l'attività di svuotamento del checkpoint nel pool di buffer, salvando l'I/O del disco. Tuttavia, il processo di ripristino è piuttosto lento una volta che il database è stato arrestato in modo anomalo (arresto anomalo o arresto, OOM o accidentale). Idealmente, puoi avere 1-2GiB in produzione, ma ovviamente puoi regolarlo. Il benchmarking di queste modifiche può essere un grande vantaggio per vedere come si comporta, specialmente dopo un arresto anomalo.

innodb_log_buffer_size

Per salvare l'I/O del disco, InnoDB scrive i dati di modifica nel buffer di log di lt e utilizza il valore di innodb_log_buffer_size con un valore predefinito di 8 MiB. Ciò è vantaggioso soprattutto per le transazioni di grandi dimensioni in quanto non è necessario scrivere il registro delle modifiche su disco prima del commit della transazione. Se il tuo traffico di scrittura è troppo elevato (inserimenti, eliminazioni, aggiornamenti), l'aumento del buffer consente di risparmiare l'I/O del disco.

innodb_flush_log_at_trx_commit

Quando innodb_flush_log_at_trx_commit è impostato su 1, il buffer di registro viene svuotato su ogni transazione eseguita sul file di registro su disco e fornisce la massima integrità dei dati, ma ha anche un impatto sulle prestazioni. Impostarlo su 2 significa che il buffer di registro viene scaricato nella cache dei file del sistema operativo su ogni commit di transazione. L'implicazione di 2 è ottimale e migliora le prestazioni se puoi rilassare i tuoi requisiti ACID e puoi permetterti di perdere transazioni per l'ultimo secondo o due in caso di arresti anomali del sistema operativo.

innodb_thread_concurrency

Con i miglioramenti al motore InnoDB, si consiglia di consentire al motore di controllare la concorrenza mantenendolo sul valore predefinito (che è zero). Se vedi problemi di concorrenza, puoi ottimizzare questa variabile. Un valore consigliato è 2 volte il numero di CPU più il numero di dischi. La sua variabile dinamica significa che può essere impostata senza riavviare il server MySQL.

innodb_flush_method

Questa variabile però deve essere provata e testata su quale hardware si adatta meglio a te. Se stai utilizzando un RAID con cache con batteria tampone, DIRECT_IO aiuta ad alleviare la pressione di I/O. L'I/O diretto non è memorizzato nella cache, quindi evita il doppio buffering con il pool di buffer e la cache del filesystem. Se il tuo disco è archiviato in SAN, O_DSYNC potrebbe essere più veloce per un carico di lavoro pesante in lettura con principalmente istruzioni SELECT.

innodb_file_per_table

innodb_file_per_table è attivo per impostazione predefinita da MySQL 5.6. Questo è solitamente consigliato in quanto evita di avere un enorme tablespace condiviso e in quanto consente di recuperare spazio quando si elimina o si tronca una tabella. Anche il tablespace separato offre vantaggi per lo schema di backup parziale di Xtrabackup.

innodb_stats_on_metadata

Questo tenta di tenere sotto controllo la percentuale di pagine sporche e, prima del plug-in Innodb, questo era davvero l'unico modo per ottimizzare lo svuotamento del buffer sporco. Tuttavia, ho visto server con buffer sporchi del 3% e stanno raggiungendo l'età massima del checkpoint. Il modo in cui questo aumenta lo svuotamento del buffer sporco, inoltre, non si adatta bene ai sottosistemi ad alto io, in effetti raddoppia semplicemente lo svuotamento del buffer sporco al secondo quando la % di pagine sporche supera questa quantità.

innodb_io_capacity

Questa impostazione, nonostante tutte le nostre grandi speranze che permetta a Innodb di fare un uso migliore del nostro IO in tutte le operazioni, controlla semplicemente la quantità di svuotamento delle pagine sporche al secondo (e altre attività in background come read-ahead). Rendilo più grande, scarichi di più al secondo. Questo non si adatta, fa semplicemente tanti iops ogni secondo se ci sono buffer sporchi da svuotare. Eliminerà efficacemente qualsiasi ottimizzazione del consolidamento IO se si dispone di un carico di lavoro di scrittura sufficientemente basso (ovvero, le pagine sporche vengono svuotate quasi immediatamente, in questo caso potremmo stare meglio senza un registro delle transazioni). Può anche affamare rapidamente le letture e le scritture dei dati nel registro delle transazioni se lo imposti troppo alto.

innodb_write_io_threads

Controlla quanti thread avranno scritture in corso sul disco. Non sono sicuro del motivo per cui questo è ancora utile se puoi utilizzare AIO nativo di Linux. Questi possono anche essere resi inutili da filesystem che non consentono la scrittura parallela sullo stesso file da più di un thread (in particolare se hai relativamente poche tabelle e/o usi i tablespace globali)

innodb_adaptive_flushing

Specifica se regolare dinamicamente la velocità di svuotamento delle pagine sporche nel pool di buffer InnoDB in base al carico di lavoro. La regolazione dinamica della velocità di lavaggio ha lo scopo di evitare esplosioni di attività I/O. In genere, questo è abilitato per impostazione predefinita. Questa variabile, quando abilitata, cerca di essere più intelligente riguardo allo svuotamento in modo più aggressivo in base al numero di pagine sporche e al tasso di crescita del registro delle transazioni.

server_innodb_dedicated

Questa variabile è nuova in MySQL 8.0 che viene applicata a livello globale e richiede un riavvio di MySQL poiché non è una variabile dinamica. Tuttavia, poiché la documentazione afferma che questa variabile deve essere abilitata solo se il tuo MySQL è in esecuzione su un server dedicato. In caso contrario, non abilitarlo su un host condiviso o condividere le risorse di sistema con altre applicazioni. Quando è abilitato, InnoDB eseguirà una configurazione automatica per la quantità di memoria rilevata per le variabili innodb_buffer_pool_size, innodb_log_file_size, innodb_flush_method. L'unico aspetto negativo è che non puoi avere la possibilità di applicare i valori desiderati alle variabili rilevate menzionate.

Il mioISAM

key_buffer_size

InnoDB è ora il motore di archiviazione predefinito di MySQL, il valore predefinito per key_buffer_size può probabilmente essere ridotto a meno che non si utilizzi MyISAM in modo produttivo come parte della propria applicazione (ma chi utilizza MyISAM in produzione ora?). Suggerirei qui di impostare forse l'1% di RAM o 256 MiB all'inizio se hai una memoria più grande e di dedicare la memoria rimanente per la cache del tuo sistema operativo e il pool di buffer InnoDB.

Altre disposizioni per la prestazione

log_query_lento

Naturalmente, questa variabile non aiuta a potenziare il tuo server MySQL. Tuttavia, questa variabile può aiutarti ad analizzare le query a prestazioni lente. Il valore può essere impostato su 0 o OFF per disabilitare la registrazione. Impostandolo su 1 o su ON per abilitarlo. Il valore predefinito dipende dal fatto che sia specificata l'opzione --slow_query_log. La destinazione per l'output del registro è controllata dalla variabile di sistema log_output; se tale valore è NONE, non vengono scritte voci di registro anche se il registro è abilitato. Puoi impostare il nome del file o la destinazione del file di registro della query impostando la variabile slow_query_log_file.

tempo_interrogativo_lungo

Se una query richiede più tempo di questo numero di secondi, il server incrementa la variabile di stato Slow_queries. Se il registro delle query lente è abilitato, la query viene registrata nel file di registro delle query lente. Questo valore viene misurato in tempo reale, non in tempo di CPU, quindi una query che è al di sotto della soglia su un sistema leggermente caricato potrebbe essere al di sopra della soglia su uno pesantemente caricato. I valori minimo e predefinito di long_query_time sono rispettivamente 0 e 10. Tieni inoltre presente che se la variabile min_examined_row_limit è impostata> 0, non registrerà le query anche se impiega troppo tempo se il numero di righe restituite è inferiore al valore impostato in min_examined_row_limit.

Per ulteriori informazioni sull'ottimizzazione della registrazione lenta delle query, consulta la documentazione qui.

sync_binlog

Questa variabile controlla la frequenza con cui MySQL sincronizzerà i binlog sul disco. Per impostazione predefinita (>=5.7.7), questo è impostato su 1, il che significa che si sincronizzerà su disco prima che le transazioni vengano salvate. Tuttavia, ciò impone un impatto negativo sulle prestazioni a causa dell'aumento del numero di scritture. Ma questa è l'impostazione più sicura se vuoi rispettare rigorosamente l'ACID insieme ai tuoi schiavi. In alternativa, puoi impostarlo su 0 se desideri disabilitare la sincronizzazione del disco e fare affidamento sul sistema operativo per scaricare di tanto in tanto il registro binario sul disco. Impostandolo su un valore superiore a 1, il binlog viene sincronizzato su disco dopo che sono stati raccolti N gruppi di commit del log binario, dove N è> 1.

Scarica/ripristina il pool di buffer

È abbastanza comune che il database di produzione debba riscaldarsi da un avvio/riavvio a freddo. Scaricando il pool di buffer corrente prima di un riavvio, salverebbe il contenuto dal pool di buffer e, una volta terminato, caricherà il contenuto di nuovo nel pool di buffer. Pertanto, questo evita la necessità di riscaldare il database su la cache. Tieni presente che questa versione è stata introdotta da allora nella 5.6 ma Percona Server 5.5 l'ha già disponibile, nel caso te lo chieda. Per abilitare questa funzione, imposta entrambe le variabili innodb_buffer_pool_dump_at_shutdown =ON e innodb_buffer_pool_load_at_startup =ON.

Hardware

Siamo ora nel 2019, ci sono stati molti nuovi miglioramenti hardware. In genere, non è necessario che MySQL richieda un hardware specifico, ma questo dipende da ciò che è necessario che il database faccia. Mi aspetto che tu non stia leggendo questo blog perché stai facendo un test se funziona su un Intel Pentium 200 MHz.

Per la CPU, processori più veloci con più core saranno ottimali per MySQL nelle versioni più recenti almeno dalla 5.6. I processori Intel Xeon/Itanium possono essere costosi ma testati per piattaforme di elaborazione scalabili e affidabili. Amazon ha spedito le proprie istanze EC2 in esecuzione su architettura ARM. Anche se personalmente non ho provato a eseguire o ricordare l'esecuzione di MySQL su architettura ARM, ci sono benchmark che erano stati realizzati anni fa. Le moderne CPU possono aumentare e diminuire le frequenze in base a temperatura, carico e criteri di risparmio energetico del sistema operativo. Tuttavia, è possibile che le impostazioni della CPU nel tuo sistema operativo Linux siano impostate su un governatore diverso. Puoi verificarlo o impostarlo con il governatore "performance" procedendo come segue:

echo performance | sudo tee /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor

Per la memoria, è molto importante che la tua memoria sia grande e possa eguagliare la dimensione del tuo set di dati. Assicurati di avere swappiness =1. Puoi verificarlo controllando sysctl o controllando il file in procfs. Ciò si ottiene effettuando le seguenti operazioni:

$ sysctl -e vm.swappiness
vm.swappiness = 1

Oppure impostandolo su un valore di 1 come segue

$ sudo sysctl vm.swappiness=1
vm.swappiness = 1

Un'altra grande cosa da considerare per la gestione della memoria è considerare la possibilità di disattivare THP (Transparrent Huge Pages). In passato, ricordo che abbiamo riscontrato alcuni strani problemi con l'utilizzo della CPU e ho pensato che fosse dovuto all'I/O del disco. Si è scoperto che il problema era con il thread khugepaged del kernel che alloca la memoria in modo dinamico durante il runtime. Non solo, durante la deframmentazione del kernel, la tua memoria verrà allocata rapidamente mentre la passa a THP. La memoria standard di HugePages è preallocata all'avvio e non cambia durante il runtime. Puoi verificarlo e disabilitarlo procedendo come segue:

$ cat /sys/kernel/mm/transparent_hugepage/enabled
$ echo "never" > /sys/kernel/mm/transparent_hugepage/enabled

Per Disk, è importante avere un buon throughput. L'uso di RAID10 è la configurazione migliore per un database con un'unità di backup della batteria. Con l'avvento delle unità flash che offrono un'elevata velocità effettiva del disco e un elevato I/O del disco per lettura/scrittura, è importante che possa gestire l'utilizzo elevato del disco e l'I/O del disco.

Sistema operativo

La maggior parte dei sistemi di produzione in esecuzione su MySQL funziona su Linux. È perché MySQL è stato testato e confrontato su Linux e sembra che sia lo standard de facto per un'installazione MySQL. Tuttavia, ovviamente, non c'è nulla che ti impedisca di usarlo su piattaforma Unix o Windows. Sarebbe più facile se la tua piattaforma fosse stata testata e ci fosse un'ampia community a disposizione per aiutarti, in caso di problemi. La maggior parte delle configurazioni funziona su sistemi RHEL/Centos/Fedora e Debian/Ubuntu. In AWS, Amazon ha il suo Amazon Linux che, a mio avviso, viene utilizzato in produzione da alcuni.

La cosa più importante da considerare con la tua configurazione è che il tuo file system sta usando XFS o Ext4. Di sicuro, ci sono pro e contro tra questi due file system, ma non entrerò nei dettagli qui. Alcuni sostengono che XFS superi Ext4, ma ci sono anche rapporti che Ext4 supera XFS. ZFS sta anche emergendo come un buon candidato per un file system alternativo. Jervin Real (di Percona) ha una grande risorsa su questo, puoi controllare questa presentazione durante la conferenza ZFS.

Link esterni

https://developer.okta.com/blog/2015/05/22/tcmalloc

https://www.percona.com/blog/2012/07/05/impact-of-memory-allocators-on-mysql-performance/

https://www.percona.com/live/18/sessions/benchmark-noise-reduction-how-to-configure-your-machines-for-stable-results

https://zfs.datto.com/2018_slides/real.pdf

https://docs.oracle.com/en/database/oracle/oracle-database/12.2/ladbi/disabling-transparent-hugepages.html#GUID-02E9147D-D565-4AF8-B12A-8E6E9F74BEEA