Usare più core per singole query MySQL su Debian


10

Sto eseguendo un server MySQL per i test su una VM (VMWare) con Debian come SO guest. Il guest ha quattro core CPU emulati, quindi ho impostato thread_concurrency su quattro.

Sto eseguendo costosi join su tavoli di grandi dimensioni, che possono richiedere diversi minuti, ma vedo sul sistema operativo guest che viene utilizzato solo un core alla volta. Ciò accade indipendentemente dal motore di archiviazione utilizzato per le tabelle coinvolte (testato con MyISAM e InnoDB). Inoltre, l'intero database sembra essere bloccato quando si eseguono queste query di grandi dimensioni, non posso eseguire ulteriori query in parallelo. Stranamente htop mostra che il core utilizzato per la query cambia durante il runtime della query!

Perché succede?

Questa è la voce pertinente da SHOW FULL PROCESSLIST;(non ci sono altre domande):

| 153 | root       | localhost | pulse_stocks  | Query   |   50 | Copying to tmp table | 
SELECT DISTINCT * FROM 
`pulse_stocks`.`stocks` sto,
`pulse_new`.`security` sec
WHERE
(sto.excntry = sec.excntry AND sto.stock_id = sec.ibtic) OR
( sto.isin = sec.isin AND sto.isin <> "" AND sec.isin <> "" )
ORDER BY
sto.id
LIMIT 0, 30 

Non ci sono altre domande in sospeso. Un'altra osservazione interessante è che MySQL risponderà a questa domanda in un secondo, se lascio fuori la ORDER BYparte.

Questo che SHOW ENGINE INNODB STATUS;mostra:

=====================================
120316  9:55:56 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 49 seconds
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 47258, signal count 47258
Mutex spin waits 0, rounds 10260, OS waits 39
RW-shared spins 94442, OS waits 47210; RW-excl spins 1, OS waits 1
------------
TRANSACTIONS
------------
Trx id counter 0 5381
Purge done for trx's n:o < 0 1810 undo n:o < 0 0
History list length 2
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, process no 7503, OS thread id 140316748777216
MySQL thread id 154, query id 654 localhost root
SHOW ENGINE INNODB STATUS
---TRANSACTION 0 5380, ACTIVE 105 sec, process no 7503, OS thread id 140316748977920
 fetching rows, thread declared inside InnoDB 429
mysql tables in use 2, locked 0
MySQL thread id 153, query id 623 localhost root Copying to tmp table
SELECT DISTINCT * FROM 
    `pulse_stocks`.`stocks` sto,
    `pulse_new`.`security` sec
WHERE
    (sto.excntry = sec.excntry AND sto.stock_id = sec.ibtic) OR
    ( sto.isin = sec.isin AND sto.isin <> "" AND sec.isin <> "" )
ORDER BY
    sto.id
LIMIT 0, 30

Trx read view will not see trx with id >= 0 5381, sees < 0 5381
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (write thread)
Pending normal aio reads: 0, aio writes: 0,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
116089 OS file reads, 7 OS file writes, 7 OS fsyncs
1063.16 reads/s, 117085 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 5, seg size 7,
0 inserts, 0 merged recs, 0 merges
Hash table size 17393, node heap has 1 buffer(s)
0.00 hash searches/s, 14.73 non-hash searches/s
---
LOG
---
Log sequence number 0 38201270
Log flushed up to   0 38201270
Last checkpoint at  0 38201270
0 pending log writes, 0 pending chkp writes
10 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 20638760; in additional pool allocated 994816
Dictionary memory allocated 162680
Buffer pool size   512
Free buffers       0
Database pages     511
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages read 816631, created 0, written 1
7597.72 reads/s, 0.00 creates/s, 0.00 writes/s
Buffer pool hit rate 964 / 1000
--------------
ROW OPERATIONS
--------------
1 queries inside InnoDB, 0 queries in queue
2 read views open inside InnoDB
Main thread process no. 7503, id 140316711446272, state: waiting for server activity
Number of rows inserted 0, updated 0, deleted 0, read 160338394
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 1495933.31 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================

Si prega di pubblicare l'output di SHOW FULL PROCESSLIST (possibilmente sterilizzato) e SHOW ENGINE INNODB STATUS per aiutarci a diagnosticare perché "l'intero database" è bloccato.
Aaron Brown,

Grazie, ho aggiornato la domanda con le informazioni richieste.
Thomas

1
Se non ci sono altre query in esecuzione, non ci sono prove che l'intero database sia bloccato. Riesci a riprodurre questa condizione e pubblicare cosa succede quando la query di lunga durata sembra bloccare gli altri?
Barone Schwartz

Ok, l'ho verificato. È possibile eseguire altre query nella console mysql, anche quando è in esecuzione la query di grandi dimensioni. Tuttavia, phpmyadmin non risponde affatto, nemmeno ai semplici tentativi di accesso, mentre la query viene eseguita. Il tempo di esecuzione stesso è spesso inferiore a 10 secondi, ma la query rimane nello stato "invio dati" per diversi minuti.
Thomas,

Risposte:


10

Potresti trovare questo sorprendente, ma dovresti impostare innodb_thread_concurrency su 0 (che è concorrenza infinita). Ciò consentirà a InnoDB Storage Engine di decidere quanti ticket di concorrenza emettere.

Ho scritto un post sull'impegno multicore di InnoDB (MySQL 5.5, anche MySQL 5.1.38 Plugin InnoDB) il 26 maggio 2011 .

Secondo la documentazione MySQL, la variabile thread_concurrency funziona solo per Solaris .

Ho un'altra preoccupazione: i tuoi JOIN coinvolgono MyISAM e InnoDB insieme? Il comportamento di blocco della tabella completa di MyISAM annulla il blocco a livello di riga di InnoDB e MVCC .

Se non si utilizza MySQL 5.5, aggiornare al più presto per configurare le opzioni di coinvolgimento multicore di InnoDB .

AGGIORNAMENTO 2012-03-19 08:30 EDT

A partire da MySQL 5.1.38, è possibile installare il plug-in InnoDB per utilizzare le nuove impostazioni per il coinvolgimento multicore. Tuttavia, è necessario ottimizzare le impostazioni in modo corretto.

In effetti, lasciato non configurato


Grazie mille. La tua risposta implica che l'utilizzo di più core non è implementato nella versione 5.1.X?
Thomas

Sì e no. Dico SÌ perché InnoDB 5.1.x non ha impostazioni multicore. Dico NO perché è possibile installare il plug-in InnoDB per queste nuove impostazioni, ma è disponibile solo per MySQL 5.1.38 e versioni successive.
RolandoMySQLDBA

@RolandoMySQLDBA: Siamo spiacenti, so che questo post è vecchio, ma ho scoperto che mysql sul mio server (che ha 24 core) utilizza solo 1 core. Ho controllato innodb_thread_cuncurrencycome hai detto ed è impostato su 0, quindi mi chiedevo perché mysql non utilizza più core?
monamona,

1
@monamona Non è l'unica impostazione con cui giocare. È inoltre necessario impostare innodb_read_io_threads e innodb_write_io_threads su un valore superiore (provare 8, 16, 32 e 64).
RolandoMySQLDBA,

@monamona Per favore leggi il mio vecchio post dba.stackexchange.com/questions/2918/… per maggiori dettagli
RolandoMySQLDBA

2

MySQL, qualsiasi versione, non ha alcun codice per utilizzare più core in una singola connessione.

Percona fa un lavoro migliore usando più core su più connessioni nel suo Xtradb. InnoDB esaurisce il vapore a circa 8 core; Xtradb si appiattisce a 32 o giù di lì.

Una "query di grandi dimensioni" potrebbe bloccare la tabella (o le righe della tabella) di cui necessita qualche altra connessione. Diamo un'occhiata alla query e SHOW CREATE TABLE.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.