Die einfügungsintensive InnoDB-Tabelle verwendet nicht meine gesamte CPU


8

Ich habe eine Paketprotokolldatenbank, die fast nie abgefragt wird. Es muss nur schnell auf Einsätzen sein. Ich verwende InnoDB, weil ich die ACID-Konformität beibehalten möchte, da selbst der Verlust eines einzelnen Pakets unseren Kunden schaden kann. In einem Leistungsoptimierungsszenario sende ich 1.000.000 Pakete über mehrere DB-Verbindungen an den Server. Unabhängig davon, welche Einstellungen ich in my.cnf verwende, kann der mysqld-Prozess auf einem System mit 12 Kernen nicht mehr als 900% CPU verwenden. (Auf der Box läuft nichts anderes.)

Ich habe folgendes eingestellt

  • innodb_file_per_table = 1
  • innodb_write_io_threads = 64
  • innodb_read_io_threads = 64
  • innodb_thread_concurrency = 0

Wenn ich MyISAM verwende, kann ich alle Pakete in ca. 6 Sekunden schreiben lassen. InnoDB benötigt jedoch ungefähr 25. Kann ich MySQL dazu bringen, den Rest der Systemressourcen zu nutzen und schneller einzufügen?

Bearbeiten: Hier ist das Schema für die Tabelle:

+-------+----------------------+------+-----+---------+-------+
| Field | Type                 | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+-------+
| t     | bigint(20) unsigned  | YES  |     | NULL    |       |
| a     | char(1)              | YES  |     | NULL    |       |
| sa    | int(10) unsigned     | YES  |     | NULL    |       |
| sb    | int(10) unsigned     | YES  |     | NULL    |       |
| sc    | int(10) unsigned     | YES  |     | NULL    |       |
| sd    | int(10) unsigned     | YES  |     | NULL    |       |
| sp    | smallint(5) unsigned | YES  |     | NULL    |       |
| da    | int(10) unsigned     | YES  |     | NULL    |       |
| db    | int(10) unsigned     | YES  |     | NULL    |       |
| dc    | int(10) unsigned     | YES  |     | NULL    |       |
| dd    | int(10) unsigned     | YES  |     | NULL    |       |
| dp    | smallint(5) unsigned | YES  |     | NULL    |       |
+-------+----------------------+------+-----+---------+-------+

edit2: Ich habe mehr Einfügungen zusammengestellt, sodass eine einzelne Abfrage nahe der maximalen Länge liegt (ca. 16.000.000 Zeichen). Die Datenbank steigt jetzt für zwei Sekunden auf 1100% und für den Rest der Zeit auf 100%. Die Gesamtzeit beträgt jetzt 21 Sekunden oder ungefähr 16% schneller als zu Beginn.

Antworten:


7

Sie müssen auch innodb_io_capacity hochdrehen .

Der Standardwert ist 200. Erhöhen Sie ihn zunächst auf 5000. Ich würde zu 20000 gehen.

Sie können auch sicherstellen möchten , ib_logfile0und ib_logfile1sind ausreichend groß. Der Standardwert für innodb_log_file_size ist 5M. Ich würde das für den Anfang auf 1G erhöhen.

Ein größerer InnoDB-Pufferpool würde ebenfalls helfen, vielleicht 4G.

Verwenden Sie zur Zusammenfassung diese zusätzlichen Einstellungen:

[mysqld]
innodb_io_capacity=5000
innodb_buffer_pool_size=4G
innodb_log_file_size=1G

Nachdem Sie diese Einstellungen zu my.cnf hinzugefügt haben, gehen Sie wie folgt vor, um die Größe von ib_logfile0 / ib_logfile1 zu ändern

service mysql stop
rm -f /var/log/mysql/ib_logfile[01]
service mysql start

Die Dateien ib_logfile0 und ib_logfile1 werden neu erstellt. Keine Sorge, ich habe das schon oft gemacht .

Möglicherweise müssen Sie für InnoDB etwas Außergewöhnliches tun

Versuche Folgendes:

  • Vollständige Tabellensperre für die InnoDB-Tabelle
  • Führen Sie die Massenladung durch
  • Lassen Sie die Sperre los

Wäre es hilfreich, mehrere Pufferpools zu haben? Oder wäre es wichtig, da es nur ein Tisch ist?
September 332

Nur ein Pufferpool. Auf diese Weise gibt es keine virtuelle Grenze. Ich habe einen Client mit MySQL 5.5.9, der einen einzelnen 162-GB-Pufferpool verwendet, und er läuft einfach großartig.
RolandoMySQLDBA

Damit habe ich ungefähr 950% CPU erreicht, aber es scheint nicht schneller zu sein.
September 332

Versuchen Sie vor dem Massenladen eine vollständige Tabellensperre für die InnoDB-Tabelle.
RolandoMySQLDBA

3

Es gibt eine Reihe von Faktoren, die sich auf die Fähigkeit auswirken, die Verwendung mehrerer Kerne zu maximieren.

  • Einige Mutexe wirken sich auf mehrere CPUs aus und lassen einige warten, bevor sie fortfahren können.
  • Sie benötigen so viele aktive Threads wie Sie CPUs haben. Wenn Ihre Arbeitslast zu 9 parallelen Threads führt, können Sie 12 Kerne nicht füllen.
  • Die E / A-Kapazität muss ausreichen, um genügend Arbeit für alle CPUs bereitzustellen. Wenn Sie sich auf der Festplatten-E / A in der Warteschlange befinden oder auf Netzwerknachrichten warten, können Sie die CPUs nicht füllen.

Mit Tools wie SAR können Sie feststellen, ob es Engpässe gibt, die Ihre Kapazität verringern. Seien Sie gewarnt, wenn Sie einen Engpass beseitigen, wird der Engpass nur verschoben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.