Ist es möglich, dass MySQL mehr als einen Kern verwendet?

131

Ich habe einige dedizierte MySQL-Server kennengelernt, die nie mehr als einen Kern verwenden. Ich bin mehr Entwickler als DBA für MySQL, brauche also etwas Hilfe

Konfiguration

Die Server sind mit einer Last vom Typ OLAP / DataWarehouse (DW) recht voll:

  • Primär: 96 GB RAM, 8 Kerne + einzelnes RAID 10-Array
  • Test: 32 GB RAM mit 4 Kernen
  • Die größte Datenbank hat 540 GB, die Gesamtgröße liegt bei 1,1 TB, hauptsächlich InnoDB-Tabellen
  • Solaris 10 Intel-64
  • MySQL 5.5.x

Hinweis: Die größte Datenbank ist die vom OLTP-DR-Server replizierte, von der der DW geladen wird. Es ist keine vollständige DW: Sie dauert nur 6 Monate bis 6 Wochen, ist also kleiner als die OLTP-DB.

Beobachtungen auf einem Testserver

  • 3 getrennte Anschlüsse
  • jeder hat eine gleichzeitige (und unterschiedliche) ALTER TABLE...DROP KEY...ADD INDEX
  • Die 3 Tabellen haben 2,5, 3,8 und 4,5 Millionen Zeilen
  • Die CPU-Auslastung steigt auf 25% (ein Kern ist maximal) und nicht höher
  • die 3 ÄNDERUNGEN dauern 12-25 Minuten (eine einzelne dauert 4,5)

Fragen

  1. Welche Einstellung oder welcher Patch ist erforderlich, um die Verwendung mehrerer Kerne zu ermöglichen?
    Das heißt, warum verwendet MySQL nicht alle verfügbaren Kerne? (wie andere RDBMS)
  2. Ist es eine Folge der Replikation?

Weitere Hinweise

  • Ich verstehe den Unterschied zwischen einem RDBMS-Thread und einem Betriebssystem-Thread
  • Ich frage nicht nach irgendeiner Form von Parallelität
  • Einige der Systemvariablen für InnoDB und Threads sind nicht optimal
    (auf der Suche nach einem schnellen Gewinn)
  • Kurzfristig kann ich das Festplattenlayout nicht ändern
  • Das Betriebssystem kann bei Bedarf angepasst werden
  • Ein einziger ALTER TABLE auf dem kleinsten Tisch dauert 4,5 Minuten (schockierende IMO)

Bearbeiten 1

  • innodb_thread_concurrency ist auf beiden auf 8 gesetzt. Ja, es ist falsch, aber MySQL verwendet nicht mehrere Kerne
  • innodb_buffer_pool_size beträgt 80 GB bei primären und 10 GB bei einem Test (eine andere Instanz wird heruntergefahren). Dies ist vorerst in Ordnung.
  • innodb_file_per_table = ON

Bearbeiten 2

Zu testen

  • innodb_flush_method wird nicht als O_DIRECT angezeigt, wenn es sein sollte
  • Folgen Sie den Einstellungen von RolandoMySQLDBA

Lassen Sie mich wissen, wenn ich etwas Wichtiges verpasst habe

Prost

Aktualisieren

Geänderte innodb_flush_method + 3 x Thread-Einstellungen in RolandoMySQLDBAs Antwort
Ergebnis:> 1 für die Tests verwendeter Core = positives Ergebnis

gbn
quelle
@Dtest: innodb_file_per_table = ON. SHOW ENGINE INNODB STATUS \ G ist nur Befehlszeile?
12.
@Dtest: Ich habe keine Ausgabe in SQLyog erhalten und müsste jemanden bitten, dies über die Befehlszeile
auszuführen
1
webyog.com/forums/index.php?showtopic=1290 sollte ohne das funktionieren \G. Ich denke auch, dass SHOW INNODB STATUSes zugunsten von SHOW ENGINE INNODB STATUS5.5 veraltet ist (ich bekomme einen Fehler beim Ausführen des ersteren in der Kommandozeile.
Derek Downey
1
Alle anderen Antworten sind gut, da Sie ein Entwickler sind. Ich würde jedoch empfehlen, einen Blick auf Shard Query code.google.com/p/shard-query zu werfen. Dies kann Ihnen insbesondere in einer Datawarehouse-Umgebung helfen.
Jonathan
Danke, das ist eine Option, über die wir nachgedacht haben. Ich übernehme auch die DBA-Rolle.
14.

Antworten:

123

Ich habe innodb_thread_concurrency bereits im Mai 2011 auf der Percona Live NYC-Konferenz mit einem MySQL-Experten besprochen .

Ich habe etwas Überraschendes erfahren: Trotz der Dokumentation ist es am besten, innodb_thread_concurrencybei 0 zu belassen (unendliche Parallelität). Auf diese Weise entscheidet InnoDB, wie viele innodb_concurrency_ticketsfür ein bestimmtes MySQL-Instanz-Setup am besten geöffnet werden.

Sobald Sie innodb_thread_concurrencyauf 0 gesetzt haben, können Sie innodb_read_io_threadsund innodb_write_io_threads(beide seit MySQL 5.1.38) auf den Maximalwert von 64 setzen. Dies sollte mehr Kerne einbinden.

RolandoMySQLDBA
quelle
Werde es versuchen. Ich wollte innodb_thread_concurrency sowieso auf 0 setzen, basierend auf Sachen, die ich auch gelesen habe
gbn
9
+1 für innodb_thread_concurrency = 0
randomx
3
@gbn - Ein Dankeschön von der Nr. 1 in DBA.SE ist ein Vertrauensschub und wird sehr geschätzt. Danke und gern geschehen !!!
RolandoMySQLDBA
set global innodb_read_io_threads = 8 Fehlercode: 1238. Die Variable 'innodb_read_io_threads' ist eine schreibgeschützte Variable
wgq3g23g
2
@ wgq3g23g Wenn Sie RDS ausführen, ändern Sie dies in der DB-Parametergruppe und starten Sie die Instanz neu. Wenn Sie EC2 oder Bare Metal verwenden, fügen Sie diese Option zu my.cnfmysqld hinzu und starten Sie es neu. Bitte.
RolandoMySQLDBA
29

MySQL verwendet automatisch mehrere Kerne, daher ist entweder Ihre Auslastung von 25% Zufall 1 oder eine mögliche Fehlkonfiguration unter Solaris. Ich werde nicht so tun, als wüsste ich, wie man Solaris einstellt, aber hier ist ein Artikel, der einige Solaris-spezifische Einstellungsinformationen behandelt .

Die InnoDB-Tuning-Seiten wurden in MySQL 5.5 überarbeitet, daher gibt es dort auch einige gute Informationen. Aus den InnoDB-Disk-IO-Tipps :

Wenn das Unix-Top-Tool oder der Windows Task-Manager anzeigt, dass der Prozentsatz der CPU-Auslastung mit Ihrer Arbeitslast weniger als 70% beträgt, ist Ihre Arbeitslast wahrscheinlich festplattengebunden. Möglicherweise führen Sie zu viele Transaktions-Commits durch, oder der Pufferpool ist zu klein. Das Vergrößern des Pufferpools kann hilfreich sein, darf jedoch nicht mehr als 80% des physischen Speichers betragen.

Einige andere Dinge zu überprüfen:

  • Das Umstellen der innodb_flush_method auf O_DIRECT ist einen Test wert. Wenn dies hilft, müssen Sie möglicherweise das Dateisystem mit der forcedirectioOption mounten

  • Ändern Sie den Wert für innodb_flush_log_at_trx_commit von 1 auf 0 (wenn es Ihnen nichts ausmacht, die letzte Sekunde bei einem MySQL-Absturz zu verlieren) oder 2 (wenn es Ihnen nichts ausmacht, die letzte Sekunde bei einem Betriebssystemabsturz zu verlieren).

  • Überprüfen Sie den Wert von innodb_use_sys_malloc . Dieser Artikel enthält weitere Informationen zur Variablen.

    Zu diesem Zeitpunkt gab es keine für Mehrkern-CPUs optimierten Speicherzuweisungsbibliotheken. Aus diesem Grund hat InnoDB einen eigenen Speicherzuweiser im mem-Subsystem implementiert. Dieser Allokator wird von einem einzelnen Mutex geschützt, was zu einem Engpass werden kann.

    Am Ende des Abschnitts finden Sie jedoch einige Einschränkungen, was das Aktivieren der Variablen bedeutet (standardmäßig in 5.5 aktiviert).

    Beachten Sie, dass InnoDB den Wert des Parameters innodb_additional_mem_pool_size ignoriert, wenn die InnoDB-Speicherzuordnung deaktiviert ist.

  • Möglicherweise verursacht die Replikation einen Teil des Problems. Mir ist klar, dass Sie nicht an Parallelität interessiert sind, aber aus der Beschreibung dieses Worklogs :

    Derzeit lässt sich die Replikation auf Multi-Core-Computern nicht gut skalieren. Der einzelne Slave-Thread führt Replikationsereignisse nacheinander aus und kann möglicherweise nicht mit einer Last fertig werden, die durch gleichzeitige Verbindungen mehrerer Clients entsteht, die von der CPU des separaten Masterservers bedient werden.

Letztendlich ist InnoDB aufgrund der auftretenden festplattenbasierten Vorgänge möglicherweise nicht die beste Engine für Datawarehousing. Sie können erwägen, die Datawarehouse-Tabelle (n) so zu ändern, dass sie unter MyISAM komprimiert wird .

1 Ich meine, es gibt zufällig einen Engpass, der verhindert, dass Ihre Auslastung über 25% steigt, aber nicht unbedingt ein erzwungenes Single-Core-Problem ist.

Derek Downey
quelle
Vielen Dank. Einstellungsbereich zur Frage hinzugefügt. Das Problem sind mehrere intensive Abfragen mit einem einzigen Kern: Noch keine Speicher- oder Thread-Einstellungen. Weitere Threads laufen immer noch auf demselben Core
gbn
@gbn danke für das update, suche noch. Ich dachte, es sei ein Zufall. Ich frage mich, ob es sich nur um ein Solaris-Problem handelt ( developers.sun.com/solaris/articles/mysql_perf_tune.html ), weiß aber nicht viel über dieses System.
Derek Downey
1
@Dtest: Ich werde diesen Artikel chuck über auf Solaris Server - Betreiber auch ein paar gute Sachen dort
GBN
1
Jetzt wird die Replikation auf dem Slave (optional) mit mehreren Threads ausgeführt. InnoDB hat sich verbessert, seitdem diese Antwort geschrieben wurde. Ich würde nicht empfehlen, MyISAM zu verwenden, insbesondere nicht, wenn es komprimiert ist.
Rick James
15

Eine einzelne Verbindung verwendet nur einen einzelnen Kern. (OK, InnoDB verwendet für einige E / A-Vorgänge andere Threads, daher Kerne. Dies ist jedoch nicht von Bedeutung.)

Sie hatten 3 ALTERs, also haben Sie nicht viel mehr als 3 Core's verwendet.

Leider verwendet nicht einmal PARTITION mehrere Kerne.

Bis vor kurzem waren nach 4-8 Kernen mehrere Verbindungen maximal. Perconas Xtradb (in MariaDB enthalten) nutzt mehrere Kerne besser, aber immer noch nur einen pro Thread. Sie erreichen ein Maximum von ungefähr 32 Kernen.

Rick James
quelle
(Update in 2015 :) Mehrere Verbindungen mit 5.6 maxes bei ca. 48 Kernen. 5.7 verspricht noch besser zu werden. (So ​​sagt Oracle Benchmarks.) Aber immer noch keine Verwendung mehrerer Kerne für eine einzelne Verbindung.
Rick James
Update (nach dem Besuch von Oracle OpenWorld): Die neue Version 8.x weist keine Parallelität auf.
Rick James
9

IMHO und im beschriebenen Anwendungsfall werden Sie nie mehr als einen Kern verwenden. Der Grund dafür ist, dass Ihre Workload nicht an die CPU, sondern an die E / A gebunden ist. Da Ihre 3 Verbindungen einen neuen Index erstellen, muss jeder von ihnen die gesamte Tabelle von der Festplatte lesen: Dies ist das, was Zeit in Anspruch nimmt, nicht das Berechnen der Indizes.

jfg956
quelle
8

Bedenken Sie, dass Ihr Engpass die IO-Leistung Ihres Dateisystems sein könnte.

Zusätzlich zu den von @RolandoMySQLDBA vorgeschlagenen Einstellungen habe ich auch die noatimeMount-Einstellungen /etc/fstabfür die Partition festgelegt, in der sich mein MySQL-Datenverzeichnis befindet ( /data01/mysqlin meinem Fall mit Mount /dev/sdb1to /data01).

Standardmäßig zeichnet Linux die Zugriffszeit für JEDES Lesen oder Schreiben von Datenträgern auf, was sich negativ auf die E / A-Leistung auswirkt, insbesondere für Anwendungen mit hohem E / A-Aufwand wie Datenbanken. Dies bedeutet, dass selbst das Lesen von Daten aus einer Datei ein Schreiben auf die Festplatte auslöst ... WAT!

Um dies zu deaktivieren, fügen Sie die noatimeMount-Option /etc/fstabfür den gewünschten Mount-Punkt wie folgt hinzu (Beispiel in meinem Fall):

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

Hängen Sie dann die Partition erneut ein:

mount -o,remount /data01

Dies sollte die Lese- / Schreibleistung von Anwendungen verbessern, die diese Partition verwenden. ABER ... nichts geht über das Speichern all Ihrer Daten.

OkezieE
quelle