Używanie wielu rdzeni do pojedynczych zapytań MySQL na Debianie

10

Używam serwera MySQL do testów na maszynie wirtualnej (VMWare) z Debianem jako systemem-gościem. Gość ma cztery emulowane rdzenie procesora, więc ustawiłem thread_concurrency na cztery.

Robię drogie połączenia na dużych stołach, co może zająć kilka minut, ale widzę w systemie gościa, że ​​używany jest tylko jeden rdzeń na raz. Dzieje się tak niezależnie od silnika pamięci używanego dla danych tabel (testowane z MyISAM i InnoDB). Dodatkowo cała baza danych wydaje się być zablokowana podczas wykonywania tych dużych zapytań, nie mogę wykonywać żadnych dodatkowych zapytań równolegle. Dziwnie htop pokazuje, że rdzeń użyty do zapytania zmienia się w czasie wykonywania zapytania!

Dlaczego to się dzieje?

To jest odpowiedni wpis z SHOW FULL PROCESSLIST;(nie ma innych zapytań):

| 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 

Brak innych oczekujących zapytań. Innym interesującym spostrzeżeniem jest to, że MySQL odpowie na to pytanie za sekundę, jeśli pominę tę ORDER BYczęść.

To SHOW ENGINE INNODB STATUS;pokazuje:

=====================================
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
============================
Tomasz
źródło
Prześlij wyniki SHOW FULL PROCESSLIST (prawdopodobnie zdezynfekowany) i SHOW ENGINE INNODB STATUS, aby pomóc nam zdiagnozować, dlaczego „cała baza danych” jest zablokowana.
Aaron Brown
Dziękuję, zaktualizowałem pytanie o wymagane informacje.
Thomas
1
Jeśli nie są uruchomione żadne inne zapytania, nie ma dowodów na to, że cała baza danych jest zablokowana. Czy potrafisz odtworzyć ten warunek i opublikować, co się dzieje, gdy długo działające zapytanie najwyraźniej blokuje innym?
Baron Schwartz
Ok, sprawdziłem to. Możliwe jest wykonywanie innych zapytań w konsoli mysql, nawet gdy uruchomione jest duże zapytanie. Jednak phpmyadmin w ogóle nie odpowiada, nawet na proste próby logowania podczas wykonywania zapytania. Sam czas wykonania jest często krótszy niż 10 sekund, ale zapytanie pozostaje w stanie „wysyłania danych” przez kilka minut.
Thomas

Odpowiedzi:

10

Może Cię to zaskoczyć, ale powinieneś ustawić innodb_thread_concurrency na 0 (co jest nieskończoną współbieżnością). Pozwoli to silnikowi pamięci InnoDB zdecydować, ile biletów współbieżności ma zostać wydanych.

Napisałem post o zaangażowaniu InnoDB w wiele rdzeni (MySQL 5.5, także MySQL 5.1.38 InnoDB Plugin) 26 maja 2011 r .

Zgodnie z dokumentacją MySQL zmienna thread_concurrency działa tylko w systemie Solaris .

Mam jeszcze jedną obawę: czy wasze JOIN z udziałem MyISAM i InnoDB razem? Blokowanie przez całą tabelę MyISAM unieważnia blokowanie InnoDB na poziomie wiersza i MVCC .

Jeśli nie korzystasz z MySQL 5.5, zaktualizuj jak najszybciej, aby skonfigurować opcje zaangażowania rdzeni InnoDB .

AKTUALIZACJA 2012-03-19 08:30 EDT

Począwszy od MySQL 5.1.38, możesz zainstalować wtyczkę InnoDB, aby używać nowych ustawień dla angażowania wielordzeniowego. Musisz jednak odpowiednio wyregulować ustawienia.

W rzeczywistości pozostawiono nieskonfigurowane

RolandoMySQLDBA
źródło
Dziękuję Ci bardzo. Czy twoja odpowiedź sugeruje, że używanie wielu rdzeni nie jest zaimplementowane w wersji 5.1.X?
Thomas
Tak i nie. Mówię TAK, ponieważ InnoDB 5.1.x nie ma ustawień wielordzeniowych. Mówię NIE, ponieważ możesz zainstalować wtyczkę InnoDB dla tych nowych ustawień, ale jest ona dostępna tylko dla MySQL 5.1.38 i nowszych.
RolandoMySQLDBA
@RolandoMySQLDBA: Przykro mi, wiem, że ten post jest stary, ale odkryłem, że mysql na moim serwerze (który ma 24 rdzenie) używa tylko 1 rdzenia. Sprawdziłem, innodb_thread_cuncurrencyjak wspomniałeś, i jest ustawiony na 0, więc zastanawiałem się, dlaczego mysql nie używa więcej rdzeni?
monamona
1
@monamona To nie jedyne ustawienie do zabawy. Musisz także ustawić innodb_read_io_threads i innodb_write_io_threads wyżej (Try 8, 16, 32 i 64).
RolandoMySQLDBA
@monamona Proszę przeczytać mój stary post dba.stackexchange.com/questions/2918/... po więcej szczegółów
RolandoMySQLDBA
2

MySQL, żadna wersja, nie ma żadnego kodu do używania wielu rdzeni w jednym połączeniu.

Percona lepiej wykorzystuje wiele rdzeni na wielu połączeniach w swoim Xtradb. InnoDB zabrakło pary w około 8 rdzeniach; Xtradb spłaszcza się przy 32 lub więcej.

„Duże zapytanie” może blokować tabelę (lub wiersze tabeli), której potrzebuje inne połączenie. Spójrzmy na zapytanie i POKAŻ TWORZENIE TABELI.

Rick James
źródło