Utiliser plusieurs cœurs pour des requêtes MySQL uniques sur Debian

10

J'utilise un serveur MySQL pour des tests sur une machine virtuelle (VMWare) avec Debian comme OS invité. L'invité a quatre cœurs CPU émulés, j'ai donc défini thread_concurrency sur quatre.

Je fais des jointures coûteuses sur de grandes tables, ce qui peut prendre plusieurs minutes, mais je vois sur le système d'exploitation invité, qu'un seul cœur est utilisé à la fois. Cela se produit quel que soit le moteur de stockage utilisé pour les tables impliquées (testé avec MyISAM et InnoDB). De plus, toute la base de données semble être bloquée lors de ces grandes requêtes, je ne peux pas faire de requêtes supplémentaires en parallèle. Étrangement htop montre que le noyau utilisé pour la requête change pendant l'exécution de la requête!

Pourquoi cela arrive-t-il?

Il s'agit de l'entrée pertinente de SHOW FULL PROCESSLIST;(il n'y a pas d'autres requêtes):

| 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 

Aucune autre requête n'est en attente. Une autre observation intéressante est que MySQL répondra à cette requête dans une seconde, si je laisse de côté la ORDER BYpartie.

C'est ce que SHOW ENGINE INNODB STATUS;montre:

=====================================
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
============================
Thomas
la source
Veuillez publier la sortie de SHOW FULL PROCESSLIST (éventuellement nettoyé) et SHOW ENGINE INNODB STATUS pour nous aider à diagnostiquer pourquoi "toute la base de données" est verrouillée.
Aaron Brown
Merci, j'ai mis à jour la question avec les informations demandées.
Thomas
1
S'il n'y a aucune autre requête en cours d'exécution, il n'y a aucune preuve que la base de données entière est verrouillée. Pouvez-vous reproduire cette condition et publier ce qui se passe lorsque la requête de longue durée bloque apparemment les autres?
Baron Schwartz
Ok, j'ai vérifié ça. Il est possible de faire d'autres requêtes dans la console mysql, même lorsque la grande requête est en cours d'exécution. Cependant, phpmyadmin ne répond pas du tout, même aux simples tentatives de connexion, pendant l'exécution de la requête. Le temps d'exécution lui-même est souvent inférieur à 10 secondes, mais la requête reste dans l'état "envoi de données" pendant plusieurs minutes.
Thomas

Réponses:

10

Cela peut vous surprendre, mais vous devez définir la valeur innodb_thread_concurrency sur 0 (qui est une concurrence infinie). Cela permettra au moteur de stockage InnoDB de décider du nombre de tickets d'accès simultané à émettre.

J'ai écrit un article sur l'engagement multicœur d'InnoDB (MySQL 5.5, également MySQL 5.1.38 InnoDB Plugin) le 26 mai 2011 .

Selon la documentation MySQL, la variable thread_concurrency ne fonctionne que pour Solaris .

J'ai une autre préoccupation: vos JOIN impliquent-ils MyISAM et InnoDB ensemble? Le comportement de verrouillage de table complète de MyISAM annule le verrouillage de niveau ligne d'InnoDB et MVCC .

Si vous n'utilisez pas MySQL 5.5, veuillez mettre à niveau dès que possible afin de configurer les options d'engagement multicœur d'InnoDB .

MISE À JOUR 2012-03-19 08:30 EDT

À partir de MySQL 5.1.38, vous pouvez installer le plug-in InnoDB pour utiliser de nouveaux paramètres pour l'engagement multicœur. Cependant, vous devez régler les paramètres correctement.

En fait, non configuré

RolandoMySQLDBA
la source
Merci beaucoup. Votre réponse implique-t-elle que l'utilisation de plusieurs cœurs n'est pas implémentée dans la version 5.1.X?
Thomas
Oui et non. Je dis OUI car InnoDB 5.1.x n'a pas de paramètres multicœurs. Je dis NON car vous pouvez installer le plug-in InnoDB pour ces nouveaux paramètres, mais il n'est disponible que pour MySQL 5.1.38 et supérieur.
RolandoMySQLDBA
@RolandoMySQLDBA: Désolé, je sais que ce message est ancien, mais j'ai trouvé que mysql sur mon serveur (qui a 24 cœurs) n'utilise qu'un seul cœur. J'ai vérifié le innodb_thread_cuncurrencycomme vous le mentionnez et il est réglé sur 0, donc je me demandais pourquoi mysql n'utilise pas plus de cœurs?
monamona
1
@monamona Ce n'est pas le seul paramètre avec lequel jouer. Vous devez également définir innodb_read_io_threads et innodb_write_io_threads plus haut (essayez 8, 16, 32 et 64).
RolandoMySQLDBA
@monamona Veuillez lire mon ancien article dba.stackexchange.com/questions/2918/… pour plus de détails
RolandoMySQLDBA
2

MySQL, quelle que soit sa version, n'a pas de code pour utiliser plusieurs cœurs dans une seule connexion.

Percona fait un meilleur travail en utilisant plusieurs cœurs sur plusieurs connexions dans son Xtradb. InnoDB s'essouffle à environ 8 cœurs; Xtradb s'aplatit à environ 32.

Une «grande requête» pourrait verrouiller la table (ou les lignes de la table) dont une autre connexion a besoin. Regardons la requête et le SHOW CREATE TABLE.

Rick James
la source