it-swarm.it

È possibile fare in modo che MySQL utilizzi più di un core?

Sono stato presentato con alcuni server MySQL dedicati che non usano mai più di un singolo core. Sono più sviluppatore di DBA per MySQL, quindi ho bisogno di aiuto

Impostare

I server sono piuttosto pesanti con un carico di tipo OLAP/DataWarehouse (DW):

  • Primario: 96 GB di RAM, 8 core + singolo array RAID 10
  • Test: 32 GB RAM con 4 core
  • Il DB più grande è 540 GB, il totale è di circa 1,1 TB e principalmente tabelle InnoDB
  • Solaris 10 Intel-64
  • MySQL 5.5.x

Nota: il DB più grande è quello replicato dal OLTP e il DW viene caricato da questo. Non è un DW completo: dura solo da 6 mesi a 6 settimane, quindi è più piccolo rispetto al OLTP DB.

Osservazioni su un server di prova

  • 3 connessioni separate
  • ognuno ha un concorrente (e diverso) ALTER TABLE...DROP KEY...ADD INDEX
  • le 3 tabelle hanno 2,5, 3,8 e 4,5 milioni di righe
  • L'utilizzo della CPU arriva fino al 25% (un core è al massimo) e non più in alto
  • i 3 ALTER impiegano 12-25 minuti (uno solo sul più piccolo dura 4,5)

Domande

  1. Quale impostazione o patch è richiesta per consentire l'utilizzo di più di un core?
    Cioè, perché MySQL non utilizza tutti i core disponibili? (come altri RDBMS)
  2. È una conseguenza della replica?

Altre note

  • Comprendo la differenza tra un "thread" RDBMS e un "thread" del sistema operativo
  • Non sto chiedendo alcuna forma di parallelismo
  • Alcune delle variabili di sistema per InnoDB e thread non sono ottimali
    (alla ricerca di una rapida vittoria)
  • A breve termine, non riesco a modificare il layout del disco
  • Il sistema operativo può essere modificato, se necessario
  • Una singola tabella ALTER sul tavolo più piccolo richiede 4,5 minuti (IMO scioccante)

Modifica 1

  • innodb_thread_concurrency è impostato su 8 su entrambi. Sì, è sbagliato ma MySQL non utilizzerà più core
  • innodb_buffer_pool_size è 80 GB su primario, 10 GB su un test (un'altra istanza viene chiusa). Questo va bene per ora.
  • innodb_file_per_table = ON

Modifica 2

Testare

  • innodb_flush_method non viene mostrato come O_DIRECT quando dovrebbe essere
  • seguirà le impostazioni di RolandoMySQLDBA

Fammi sapere se ho perso qualcosa di importante

Saluti

Aggiornare

Modificato innodb_flush_method + 3 x impostazioni thread nella risposta di RolandoMySQLDBA
Risultato:> 1 core utilizzato per i test = risultato positivo

136
gbn

In realtà ho discusso innodb_thread_concurrency con un esperto MySQL alla conferenza Percona Live di New York nel maggio 2011 .

Ho imparato qualcosa di sorprendente: nonostante la documentazione, è meglio lasciare innodb_thread_concurrency a 0 (concorrenza infinita). In questo modo, InnoDB decide il numero migliore di innodb_concurrency_tickets da aprire per una determinata configurazione dell'istanza MySQL.

Dopo aver impostato innodb_thread_concurrency a 0, è possibile impostare innodb_read_io_threads e innodb_write_io_threads (entrambi da MySQL 5.1.38) al valore massimo di 64. Questo dovrebbe coinvolgere più core.

130
RolandoMySQLDBA

MySQL utilizzerà automaticamente più core, quindi il tuo carico del 25% è una coincidenza1 o una potenziale configurazione errata su Solaris. Non pretendo di sapere come sintonizzare Solaris, ma ecco un articolo che analizza alcuni informazioni sulla messa a punto specifiche di Solaris .

Le pagine di ottimizzazione di InnoDB sono state revisionate in MySQL 5.5, quindi ci sono anche delle buone informazioni. Dal disco InnoDB IO :

Se lo strumento principale Unix o il Task Manager di Windows mostrano che la percentuale di utilizzo della CPU con il carico di lavoro è inferiore al 70%, il carico di lavoro è probabilmente associato al disco. Forse stai eseguendo troppi commit di transazioni o il pool di buffer è troppo piccolo. Fare il pool di buffer più grande può aiutare, ma non impostarlo uguale a più dell'80% della memoria fisica.

Alcune altre cose da controllare:

  • Vale la pena testare il innodb_flush_method su O_DIRECT. Se questo aiuta, potresti dover montare il filesystem con l'opzione forcedirectio

  • Cambia innodb_flush_log_at_trx_commit da 1 a 0 (se non ti dispiace perdere l'ultimo secondo in caso di arresto anomalo di mysql) o 2 (se non ti dispiace perdere l'ultimo secondo in caso di arresto anomalo del sistema operativo).

  • Controlla il valore di innodb_use_sys_malloc . Questo articolo ha lteriori informazioni sulla variabile.

    A quel tempo, non c'erano librerie di allocatori di memoria ottimizzate per CPU multi-core. Pertanto, InnoDB ha implementato il proprio allocatore di memoria nel sottosistema mem. Questo allocatore è protetto da un singolo mutex, che può diventare un collo di bottiglia.

    Ma ci sono alcuni avvertimenti alla fine della sezione su cosa significa attivare la variabile (è attivata di default in 5.5).

    Notare che quando l'allocatore di memoria InnoDB è disabilitato, InnoDB ignorerà il valore del parametro innodb_additional_mem_pool_size.

  • È possibile che la replica stia causando alcuni dei problemi. Mi rendo conto che non sei interessato al parallelismo, ma dalla descrizione di questo worklog :

    Attualmente, la replica non si adatta bene alle macchine multi-core. Il singolo thread slave esegue gli eventi di replica uno alla volta e potrebbe non far fronte a un carico prodotto da connessioni simultanee a più client servite da CPU del server principale separato.

In definitiva, InnoDB potrebbe non essere il miglior motore per il datawarehousing, a causa delle operazioni basate su disco che si verificano. Potresti considerare di modificare le tabelle del datawarehouse come MyISAM compresso .

1Per coincidenza, intendo dire che c'è un collo di bottiglia che impedisce al carico di aumentare oltre il 25%, ma non è necessariamente un problema single-core forzato.

31
Derek Downey

Nota: questa risposta riguarda una singola connessione che utilizza più core. La domanda dell'OP era ambigua; presupponeva erroneamente che MySQL nel suo insieme non potesse usare più di un core. Le altre Risposte sottolineano correttamente che il 3-Alter il test case è realmente legato all'I/O, quindi non è in grado di provare la domanda del titolo.

Una singola connessione utilizzerà solo un singolo core. (OK, InnoDB utilizza altri thread, quindi core, per alcune elaborazioni I/O, ma questo non è significativo.)

Avevi 3 ALTER, quindi non usavi molto più di 3 core.

Purtroppo, nemmeno la PARTITION utilizza più core.

Fino a poco tempo fa, le connessioni multiple avrebbero raggiunto il massimo dopo 4-8 core. Xtradb di Percona (incluso in MariaDB) fa un uso migliore di più core, ma solo uno per thread. Massimizzano a circa 32 core.

(Aggiornamento nel 2015 :) Connessioni multiple con 5.6 massimi a circa 48 core. 5.7 promette di essere ancora migliore. (Così dice i benchmark Oracle.) Ma ancora nessun uso di più core per una singola connessione.

Aggiornamento (dopo essere andato su Oracle OpenWorld): la nuova versione 8.x non avrà alcun parallelismo.

Ulteriore aggiornamento - 8.0.17 ha casi in cui utilizzerà più core su pochissime query selezionate. (Cioè, non emozionarti.)

17
Rick James

IMHO e nel caso d'uso descritto, non userete mai più di un core. Il motivo è che il tuo carico di lavoro è IO associato, non associato alla CPU. Poiché le tue 3 connessioni stanno creando un nuovo indice, ognuna di queste deve leggere l'intera tabella dal disco: questo è ciò che sta prendendo tempo, non calcolare gli indici.

10
jfg956

Considera che il tuo collo di bottiglia potrebbe essere IO del tuo filesystem).

Oltre a le impostazioni suggerite da @RolandoMySQLDBA , ho anche impostato le impostazioni di montaggio noatime in /etc/fstab per la partizione contenente la mia directory di dati mysql (/data01/mysql nel mio caso, con /dev/sdb1 montato su /data01).

Di default linux registra il tempo di accesso per OGNI lettura o scrittura del disco che influisce negativamente su IO, specialmente per applicazioni alte IO come i database. Ciò significa che anche la lettura i dati da un file innesca una scrittura su disco ... WAT!

Per disabilitarlo, aggiungi l'opzione noatime mount in /etc/fstab per il punto di montaggio desiderato come segue (esempio nel mio caso):

/dev/sdb1  /data01  ext4  defaults,noatime  0  2

Quindi rimontare la partizione:

mount -o,remount /data01

Ciò dovrebbe aumentare le prestazioni di lettura/scrittura delle applicazioni che utilizzano quella partizione. MA ... niente di meglio che conservare tutti i tuoi dati in memoria.

9
OkezieE