MySQL-Instanz blockiert "SYNC-Index ausführen"

12

Problem

Eine Instanz von MySQL 5.6.20, die (meistens nur) eine Datenbank mit InnoDB-Tabellen ausführt, zeigt gelegentliche Verzögerungen für alle Aktualisierungsvorgänge für die Dauer von 1 bis 4 Minuten an, wobei alle INSERT-, UPDATE- und DELETE-Abfragen im Status "Abfrageende" verbleiben. Das ist natürlich sehr unglücklich. Das langsame MySQL-Abfrageprotokoll protokolliert selbst die trivialsten Abfragen mit wahnsinnigen Abfragezeiten, von denen Hunderte den gleichen Zeitstempel haben, der dem Zeitpunkt entspricht, zu dem der Stillstand behoben wurde:

# Query_time: 101.743589  Lock_time: 0.000437 Rows_sent: 0  Rows_examined: 0
SET timestamp=1409573952;
INSERT INTO sessions (redirect_login2, data, hostname, fk_users_primary, fk_users, id_sessions, timestamp) VALUES (NULL, NULL, '192.168.10.151', NULL, 'anonymous', '64ef367018099de4d4183ffa3bc0848a', '1409573850');

Die Gerätestatistiken werden erhöht angezeigt, obwohl in diesem Zeitraum keine übermäßige E / A-Belastung aufgetreten ist (in diesem Fall wurden die Aktualisierungen gemäß den Zeitstempeln aus der obigen Anweisung zwischen 14:17:30 und 14:19:12 blockiert):

# sar -d
[...]
02:15:01 PM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
02:16:01 PM    dev8-0     41.53    207.43   1227.51     34.55      0.34      8.28      3.89     16.15
02:17:01 PM    dev8-0     59.41    137.71   2240.32     40.02      0.39      6.53      4.04     24.00
02:18:01 PM    dev8-0    122.08   2816.99   1633.44     36.45      3.84     31.46      1.21      2.88
02:19:01 PM    dev8-0    253.29   5559.84   3888.03     37.30      6.61     26.08      1.85      6.73
02:20:01 PM    dev8-0    101.74   1391.92   2786.41     41.07      1.69     16.57      3.55     36.17
[...]
# sar
[...]
02:15:01 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
02:16:01 PM     all     15.99      0.00     12.49      2.08      0.00     69.44
02:17:01 PM     all     13.67      0.00      9.45      3.15      0.00     73.73
02:18:01 PM     all     10.64      0.00      6.26     11.65      0.00     71.45
02:19:01 PM     all      3.83      0.00      2.42     24.84      0.00     68.91
02:20:01 PM     all     20.95      0.00     15.14      6.83      0.00     57.07

In den meisten Fällen stelle ich im langsamen mysql-Protokoll fest, dass die älteste Abfrage ein INSERT in eine große Tabelle (~ 10 M Zeilen) mit einem VARCHAR-Primärschlüssel und einem Volltextsuchindex ist:

CREATE TABLE `files` (
  `id_files` varchar(32) NOT NULL DEFAULT '',
  `filename` varchar(100) NOT NULL DEFAULT '',
  `content` text,
  PRIMARY KEY (`id_files`),
  KEY `filename` (`filename`),
  FULLTEXT KEY `content` (`content`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Weitere Untersuchungen (zB SHOW ENGINE INNODB STATUS) haben gezeigt, dass es sich in der Tat immer um eine Aktualisierung einer Tabelle unter Verwendung von Volltextindizes handelt, die den Stillstand verursacht. Der entsprechende TRANSACTIONS-Abschnitt von "SHOW ENGINE INNODB STATUS" enthält Einträge wie diese beiden für die ältesten ausgeführten Transaktionen:

---TRANSACTION 162269409, ACTIVE 122 sec doing SYNC index
6 lock struct(s), heap size 1184, 0 row lock(s), undo log entries 19942
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_1" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_2" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_3" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_4" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_5" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_6" trx id 162269409 lock mode IX
---TRANSACTION 162269408, ACTIVE (PREPARED) 122 sec committing
mysql tables in use 1, locked 1
1 lock struct(s), heap size 360, 0 row lock(s), undo log entries 1
MySQL thread id 165998, OS thread handle 0x7fe0e239c700, query id 91208956 192.168.10.153 root query end
INSERT INTO files (id_files, filename, content) VALUES ('f19e63340fad44841580c0371bc51434', '1237716_File_70380a686effd6b66592bb5eeb3d9b06.doc', '[...]
TABLE LOCK table `vw`.`files` trx id 162269408 lock mode IX

Es wird also eine schwere Volltextindex-Aktion ausgeführt ( doing SYNC index) , mit der ALLE FOLGENDEN Aktualisierungen für JEDE Tabelle gestoppt werden.

Aus den Protokollen geht hervor, dass die undo log entriesZahl doing SYNC indexbei ~ 150 / s voranschreitet, bis sie 20.000 erreicht. Zu diesem Zeitpunkt ist der Vorgang abgeschlossen.

Die FTS-Größe dieser Tabelle ist beeindruckend:

# du -c FTS_000000000000224a_00000000000036b9_*
614404  FTS_000000000000224a_00000000000036b9_INDEX_1.ibd
2478084 FTS_000000000000224a_00000000000036b9_INDEX_2.ibd
1576964 FTS_000000000000224a_00000000000036b9_INDEX_3.ibd
1630212 FTS_000000000000224a_00000000000036b9_INDEX_4.ibd
1978372 FTS_000000000000224a_00000000000036b9_INDEX_5.ibd
1159172 FTS_000000000000224a_00000000000036b9_INDEX_6.ibd
9437208 total

Obwohl das Problem auch von Tabellen mit einer wesentlich geringeren FTS-Datengröße wie der folgenden ausgelöst wird:

# du -c FTS_0000000000002467_0000000000003a21_INDEX*
49156   FTS_0000000000002467_0000000000003a21_INDEX_1.ibd
225284  FTS_0000000000002467_0000000000003a21_INDEX_2.ibd
147460  FTS_0000000000002467_0000000000003a21_INDEX_3.ibd
135172  FTS_0000000000002467_0000000000003a21_INDEX_4.ibd
155652  FTS_0000000000002467_0000000000003a21_INDEX_5.ibd
106500  FTS_0000000000002467_0000000000003a21_INDEX_6.ibd
819224  total

Auch in diesen Fällen ist die Standzeit in etwa gleich. Ich habe einen Bug auf bugs.mysql.com geöffnet, damit die Entwickler sich darum kümmern können.

Die Art der Stalls hat mich zunächst verdächtigt, dass das Löschen von Protokollen der Schuldige ist. In diesem Percona-Artikel zu Problemen mit der Leistung beim Löschen von Protokollen in MySQL 5.5 werden sehr ähnliche Symptome beschrieben sind ebenfalls vom Stall betroffen, daher scheint dies kein reines InnoDB-Problem zu sein.

Trotzdem habe ich beschlossen, alle 10 Sekunden die Werte der Log sequence numberund Pages flushed up tovon den Ausgaben des Abschnitts "LOG" zu verfolgen SHOW ENGINE INNODB STATUS. Es sieht tatsächlich so aus, als ob während des Stalls eine Spülaktivität stattfindet, da die Spreizung zwischen den beiden Werten abnimmt:

Mon Sep 1 14:17:08 CEST 2014 LSN: 263992263703, Pages flushed: 263973405075, Difference: 18416 K
Mon Sep 1 14:17:19 CEST 2014 LSN: 263992826715, Pages flushed: 263973811282, Difference: 18569 K
Mon Sep 1 14:17:29 CEST 2014 LSN: 263993160647, Pages flushed: 263974544320, Difference: 18180 K
Mon Sep 1 14:17:39 CEST 2014 LSN: 263993539171, Pages flushed: 263974784191, Difference: 18315 K
Mon Sep 1 14:17:49 CEST 2014 LSN: 263993785507, Pages flushed: 263975990474, Difference: 17377 K
Mon Sep 1 14:17:59 CEST 2014 LSN: 263994298172, Pages flushed: 263976855227, Difference: 17034 K
Mon Sep 1 14:18:09 CEST 2014 LSN: 263994670794, Pages flushed: 263978062309, Difference: 16219 K
Mon Sep 1 14:18:19 CEST 2014 LSN: 263995014722, Pages flushed: 263983319652, Difference: 11420 K
Mon Sep 1 14:18:30 CEST 2014 LSN: 263995404674, Pages flushed: 263986138726, Difference: 9048 K
Mon Sep 1 14:18:40 CEST 2014 LSN: 263995718244, Pages flushed: 263988558036, Difference: 6992 K
Mon Sep 1 14:18:50 CEST 2014 LSN: 263996129424, Pages flushed: 263988808179, Difference: 7149 K
Mon Sep 1 14:19:00 CEST 2014 LSN: 263996517064, Pages flushed: 263992009344, Difference: 4402 K
Mon Sep 1 14:19:11 CEST 2014 LSN: 263996979188, Pages flushed: 263993364509, Difference: 3529 K
Mon Sep 1 14:19:21 CEST 2014 LSN: 263998880477, Pages flushed: 263993558842, Difference: 5196 K
Mon Sep 1 14:19:31 CEST 2014 LSN: 264001013381, Pages flushed: 263993568285, Difference: 7270 K
Mon Sep 1 14:19:41 CEST 2014 LSN: 264001933489, Pages flushed: 263993578961, Difference: 8158 K
Mon Sep 1 14:19:51 CEST 2014 LSN: 264004225438, Pages flushed: 263993585459, Difference: 10390 K

Und um 14:19:11 hat der Spread sein Minimum erreicht, so dass die Spülaktivität hier aufgehört zu haben scheint und nur mit dem Ende des Stalls zusammenfällt. Aufgrund dieser Punkte habe ich das Leeren des InnoDB-Protokolls als Ursache verworfen:

  • Damit der Löschvorgang alle Aktualisierungen der Datenbank blockiert, muss er "synchron" sein, dh, 7/8 des Protokollspeicherplatzes müssen belegt sein
  • es würde eine "asynchrone" Spülphase ab innodb_max_dirty_pages_pctFüllstand vorausgehen - was ich nicht sehe
  • Die LSNs steigen auch während des Stalls weiter an, sodass die Protokollaktivität nicht vollständig aufhört
  • Auch die INSERTs der MyISAM-Tabelle sind betroffen
  • Der page_cleaner-Thread für das adaptive Leeren scheint seine Arbeit zu erledigen und die Protokolle zu leeren, ohne dass DML-Abfragen beendet werden:

LSN - PagesFlushed

(Zahlen sind ([Log Sequence Number] - [Pages flushed up to]) / 1024von SHOW ENGINE INNODB STATUS)

Das Problem scheint durch das Einstellen etwas gelindert zu werden innodb_adaptive_flushing_lwm=1, wodurch die Bereinigung der Seite gezwungen wird, mehr Arbeit als zuvor zu leisten.

Der error.loghat keine Einträge, die mit den Ständen übereinstimmen. SHOW INNODB STATUSAuszüge nach ca. 24 Betriebsstunden sehen so aus:

SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 789330
OS WAIT ARRAY INFO: signal count 1424848
Mutex spin waits 269678, rounds 3114657, OS waits 65965
RW-shared spins 941620, rounds 20437223, OS waits 442474
RW-excl spins 451007, rounds 13254440, OS waits 215151
Spin rounds per wait: 11.55 mutex, 21.70 RW-shared, 29.39 RW-excl
------------------------
LATEST DETECTED DEADLOCK
------------------------
2014-09-03 10:33:55 7fe0e2e44700
[...]
--------
FILE I/O
--------
[...]
932635 OS file reads, 2117126 OS file writes, 1193633 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 17.00 writes/s, 1.20 fsyncs/s
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
0 read views open inside InnoDB
Main thread process no. 54745, id 140604272338688, state: sleeping
Number of rows inserted 528904, updated 1596758, deleted 99860, read 3325217158
5.40 inserts/s, 10.40 updates/s, 0.00 deletes/s, 122969.21 reads/s

Ja, die Datenbank hat Deadlocks, aber sie sind sehr selten (das "Neueste" wurde ungefähr 11 Stunden vor dem Lesen der Statistiken behandelt).

Ich habe versucht, die Werte des Abschnitts "SEMAPHORES" über einen bestimmten Zeitraum zu verfolgen, insbesondere in einer normalen Betriebssituation und während eines Stillstands (ich habe ein kleines Skript geschrieben, das die Prozessliste des MySQL-Servers überprüft und für den Fall einige Diagnosebefehle in eine Protokollausgabe eingibt von einem offensichtlichen Stall). Da die Zahlen über verschiedene Zeiträume hinweg aufgenommen wurden, habe ich die Ergebnisse auf Ereignisse / Sekunde normalisiert:

                          normal   stall
                          1h avg  1m avg
OS WAIT ARRAY INFO: 
    reservation count      5,74    1,00
    signal count          24,43    3,17
Mutex spin waits           1,32    5,67
    rounds                 8,33   25,85
    OS waits               0,16    0,43
RW-shared spins            9,52    0,76
    rounds               140,73    13,39
    OS waits               2,60    0,27
RW-excl spins              6,36    1,08
    rounds               178,42   16,51
    OS waits               2,38    0,20

Ich bin mir nicht ganz sicher, was ich hier sehe. Die meisten Zahlen sind um eine Größenordnung gesunken - wahrscheinlich aufgrund eingestellter Aktualisierungsvorgänge, "Mutex Spin Waits" und "Mutex Spin Rounds" haben sich jedoch beide um den Faktor 4 erhöht.

Um dies weiter zu untersuchen, enthält die Liste von mutexes ( SHOW ENGINE INNODB MUTEX) ~ 480 mutex-Einträge, die sowohl im normalen Betrieb als auch während eines Stillstands aufgelistet sind. Ich habe aktiviert, um innodb_status_output_lockszu sehen, ob es mir mehr Details geben wird.

Konfigurationsvariablen

(Ich habe mit den meisten von ihnen ohne bestimmten Erfolg gebastelt):

mysql> show global variables where variable_name like 'innodb_adaptive_flush%';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_adaptive_flushing     | ON    |
| innodb_adaptive_flushing_lwm | 1     |
+------------------------------+-------+
mysql> show global variables where variable_name like 'innodb_max_dirty_pages_pct%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_max_dirty_pages_pct     | 50    |
| innodb_max_dirty_pages_pct_lwm | 10    |
+--------------------------------+-------+
mysql> show global variables where variable_name like 'innodb_log_%';
+-----------------------------+-----------+
| Variable_name               | Value     |
+-----------------------------+-----------+
| innodb_log_buffer_size      | 8388608   |
| innodb_log_compressed_pages | ON        |
| innodb_log_file_size        | 268435456 |
| innodb_log_files_in_group   | 2         |
| innodb_log_group_home_dir   | ./        |
+-----------------------------+-----------+
mysql> show global variables where variable_name like 'innodb_double%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_doublewrite | ON    |
+--------------------+-------+
mysql> show global variables where variable_name like 'innodb_buffer_pool%';
+-------------------------------------+----------------+
| Variable_name                       | Value          |
+-------------------------------------+----------------+
| innodb_buffer_pool_dump_at_shutdown | OFF            |
| innodb_buffer_pool_dump_now         | OFF            |
| innodb_buffer_pool_filename         | ib_buffer_pool |
| innodb_buffer_pool_instances        | 8              |
| innodb_buffer_pool_load_abort       | OFF            |
| innodb_buffer_pool_load_at_startup  | OFF            |
| innodb_buffer_pool_load_now         | OFF            |
| innodb_buffer_pool_size             | 29360128000    |
+-------------------------------------+----------------+
mysql> show global variables where variable_name like 'innodb_io_capacity%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_io_capacity     | 200   |
| innodb_io_capacity_max | 2000  |
+------------------------+-------+
mysql> show global variables where variable_name like 'innodb_lru_scan_depth%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_lru_scan_depth | 1024  |
+-----------------------+-------+

Sachen schon ausprobiert

  • Deaktivieren des Abfragecaches durch SET GLOBAL query_cache_size=0
  • Erhöhung innodb_log_buffer_sizeauf 128M
  • das Spiel mit innodb_adaptive_flushing, innodb_max_dirty_pages_pctund die jeweiligen _lwmWerte (sie auf die Standardwerte gesetzt wurden , um meine Änderungen vor)
  • ansteigend innodb_io_capacity(2000) und innodb_io_capacity_max(4000)
  • Rahmen innodb_flush_log_at_trx_commit = 2
  • Laufen mit innodb_flush_method = O_DIRECT (ja, wir verwenden ein SAN mit einem persistenten Schreibcache)
  • Setzen Sie den / sys / block / sda / queue / scheduler auf noopoderdeadline
syneticon-dj
quelle
Was sind die Werte von innodb_io_capacity, innodb_io_capacity_max und innodb_lru_scan_depth? Wenn Sie für diese Werte höhere (geeignetere) Werte festlegen, bleibt der Protokollspeicherplatz frei.
Morgan Tocker
Standardeinstellungen - 200, 2000 und 1024. Ich habe sie jetzt in 2000, 4000 und 2000 geändert und die Spanne zwischen den LSN- und Pages Flushed-Werten hat sich erneut auf <1.000 K verringert. Ich bin mir jedoch nicht sicher, ob dies eine Frage der Protokollierung ist Platz an erster Stelle.
syneticon-dj
In der Tat scheint es nicht zu sein. Ich sehe immer noch Stände - sie haben sich in Bezug auf Dauer und Häufigkeit des Auftretens nicht wesentlich verändert. Meine LSN / Checkpoint-Protokollierung zeigt signifikant niedrigere absolute Spread-Zahlen an, die während des Stalls auf etwa 3 Millionen in 1 bis 2 Minuten etwas ansteigen (wahrscheinlich die nicht abgeschlossenen Transaktionen, die zu einer nicht löschbaren Protokollnutzung führen) und das anschließende erfolgreiche Leeren auf einen Spread nahe Null zwischen LSN und Checkpoint ab dem Zeitpunkt, an dem der Stall aufgelöst wurde.
syneticon-dj
Ich bin nicht sicher, ob Sie innodb_adaptive_flushing_lwm auf 1 setzen sollten - dies ist ein Prozentsatz des Protokollspeicherplatzes, bei dem das adaptive Leeren einsetzt (Standard: 10).
Morgan Tocker
@MorganTocker Ich habe dies festgelegt, um sicherzustellen, dass das adaptive Leeren die meiste Zeit alles leert, da ich vermutete, dass die Verwendung des Protokollspeicherplatzes Teil des Problems war. Das Problem trat auch mit dem Standardwert 10 auf. Ich habe ihn zu Zwecken der Fehlerbehebung geändert.
syneticon-dj

Antworten:

6

Das gleiche Problem trat auf zwei Servern in den Versionen 5.6.12 und 5.6.16 auf, die unter Windows mit jeweils zwei Slaves ausgeführt wurden. Wir waren fast zwei Monate wie Sie ratlos.

Lösung :

set global binlog_order_commits = 0;

Weitere Informationen zur Variablen finden Sie unter https://dev.mysql.com/doc/refman/5.6/de/replication-options-binary-log.html#sysvar_binlog_order_commits .

Erklärung :

InnoDB-Volltext verwendet einen Cache (standardmäßig 8 MB groß), der Änderungen enthält, die auf den tatsächlichen Volltextindex auf der Festplatte angewendet werden müssen.

Sobald der Cache voll ist, werden einige Transaktionen erstellt, mit denen die im Cache enthaltenen Daten zusammengeführt werden. Dies ist in der Regel eine große Menge an zufälligen E / A-Vorgängen, es sei denn, der gesamte Volltextindex kann in den Cache geladen werden Der Pufferpool ist eine lange und langsame Transaktion.

Wenn binlog_order_commits auf true gesetzt ist, müssen alle Transaktionen mit Einfügungen und Aktualisierungen, die nach der lang laufenden Transaktion fts_sync_index gestartet wurden, warten, bis sie abgeschlossen sind, bevor sie festgeschrieben werden können.

Dies ist nur dann ein Problem, wenn die binäre Protokollierung aktiviert ist

Daniel Golding
quelle
Das sieht sehr danach aus, als könnte es auch die Lösung für das Problem sein, das ich sah. Wie sind Sie auf die Problemumgehung gekommen? In meinem Fall auch der Volltextindex würde passen in den Pufferpool hat (die ~ 30G groß ist) , aber die Operation schien stark latenz gebunden zu sein. Ich habe den Eindruck, dass der I / O-Stack von MySQL im Umgang mit der Speicherlatenz äußerst ineffizient ist. Daher ist dieses Problem wahrscheinlich eine Kombination aus beidem - die Ineffizienz zusammen mit einem schlechten Standard für Konfigurationen für die binäre Protokollierung.
syneticon-dj
Ich frage mich, wie es so lange unbemerkt bleiben konnte. Sicherlich gibt es mehr Leute, die InnoDB mit aktiviertem FTS und Binlog auf Nicht-SSD-Speichern ausführen?
syneticon-dj
Glück. Ich war an dem Punkt angelangt, an dem ich es geschafft hatte, den "show engine innodb status" während der Überbrückungen zu erfassen. Ich habe ein kleines Programm geschrieben, das viele Zeilen in eine Tabelle mit einem FTS-Index einfügt, und ein anderes, das eine zweite Tabelle aktualisiert und die Aktualisierungszeiten aufzeichnet. Es war mir nicht möglich, die Pausen zum Leeren des FTS-Cache zu erhalten, um die Aktualisierungen für eine Weile zu blockieren, bis ich die Unterschiede in der Einrichtung nacheinander zwischen meinem lokalen Computer und den Live-Servern durchgesehen habe. Durch das Einschalten des Binlogs wurde das Problem neu erstellt, sodass ich nur die Binlog-Optionen durchgelesen habe.
Daniel Golding
1
Es ist erwähnenswert, dass das MySQL - Entwickler - Team schließlich (nach 15 Monaten in der Warteschlange!) , Um den eingestellte gemeldeten Fehler ‚s Status auf‚ überprüft‘und zumindest jemand aus dem Entwicklerteam Gedanken über Lösungen zu sein scheint. Selbstverständlich bin ich mit MySQL fertig. Zum Guten, hoffe ich.
syneticon-dj
4

Lassen Sie mich vielleicht versuchen, das historische Problem beim Löschen von Protokollen und die Funktionsweise des adaptiven Löschens zu beschreiben:

  • Die Redo-Logs sind ringgepuffert . Sie werden immer nur geschrieben (im normalen Betrieb niemals gelesen) und sorgen für eine Wiederherstellung nach einem Absturz. Ich beschreibe einen Ringpuffer gerne als ähnlich wie die Lauffläche eines Panzers.

  • InnoDB kann den Protokolldateibereich nicht überschreiben, wenn er Änderungen enthält, die noch nicht auf der Festplatte geändert wurden. Historisch gesehen würde es passieren, dass InnoDB eine bestimmte Menge an Arbeit pro Sekunde versucht (konfiguriert von innodb_io_capacity), und wenn dies nicht ausreicht, würden Sie den vollen Protokollspeicher erreichen. Ein Stillstand würde eintreten, wenn eine synchrone Spülung stattfinden müsste, um plötzlich Speicherplatz freizugeben, was normalerweise eine Hintergrundaufgabe ist, die plötzlich in den Vordergrund tritt.

  • Um dieses Problem zu beheben, wurde die adaptive Spülung eingeführt. Wenn 10% (Standard) des Protokollspeicherplatzes belegt sind, wird die Hintergrundarbeit zunehmend aggressiver. Das Ziel ist eher ein plötzlicher Stillstand als ein kurzer Leistungsabfall.

  • Unabhängig von adaptiver Spülung ist es wichtig , genügend Protokollspeicherbereich für Ihre Arbeit zu haben ( innodb_log_file_sizeWerte von 4G sind jetzt ganz sicher), und stellen Sie sicher , dass innodb_io_capacityund innodb_lru_scan_depthsind auf realistische Werte gesetzt. Die adaptive Spülung von 10% innodb_adaptive_flushing_lwmist etwas, in das man sich nicht sehr weit hinein streckt, sondern eher ein Abwehrmechanismus gegen zu wenig Platz.

Morgan Tocker
quelle
2

Nur um InnoDB ein wenig von Konflikten zu entlasten, könnten Sie damit spielen innodb_purge_threads.

Vor MySQL 5.6 hat der Master-Thread alle Seiten geleert. In MySQL 5.6 kann ein separater Thread damit umgehen. Der Standardwert für innodb_purge_threadsin MySQL 5.5 war 0 mit einem Maximum von 1. In MySQL 5.6 ist der Standardwert 1 mit einem Maximum von 32.

Was macht innodb_purge_threadseigentlich die Einstellung ?

Bei Werten ungleich Null wird die Löschoperation in einem oder mehreren Hintergrundthreads ausgeführt, wodurch interne Konflikte in InnoDB reduziert und die Skalierbarkeit verbessert werden können. Wenn Sie den Wert auf mehr als 1 erhöhen, werden so viele separate Bereinigungsthreads erstellt, dass die Effizienz auf Systemen verbessert werden kann, auf denen DML-Vorgänge für mehrere Tabellen ausgeführt werden.

Ich würde damit beginnen, innodb_purge_threads auf 4 zu setzen und zu prüfen , ob das Leeren der InnoDB-Seite reduziert ist.

UPDATE 2014-09-02 12:33 EDT

Morgan Tocker wies in dem folgenden Kommentar darauf hin, dass der Page Cleaner das Opfer ist und MySQL 5.7 darauf reagieren kann . Ungeachtet dessen ist Ihre Situation in MySQL 5.6.

Ich habe einen zweiten Blick darauf geworfen und festgestellt, dass Sie innodb_max_dirty_pages_pct bei 50 haben.

Der Standardwert für innodb_max_dirty_pages_pct in MySQL 5.5+ ist 75. Wenn Sie diesen Wert verringern, kommt es häufiger zu Verzögerungen beim Leeren. Ich würde drei (3) Dinge tun

UPDATE 03.09.2014 11:06 EDT

Möglicherweise müssen Sie Ihr Spülverhalten ändern

Stellen Sie Folgendes dynamisch ein

SET GLOBAL flush = 1;
SET GLOBAL flush_time = 10;

Diese Variablen werden gelöscht und flush_time , machen das Löschen aggressiver, indem alle 10 Sekunden geöffnete Datei-Handles für Tabellen geschlossen werden. MyISAM kann definitiv davon profitieren, da es keine Daten zwischenspeichert. Alle Schreibvorgänge in MyISAM-Tabellen erfordern vollständige Tabellensperren, gefolgt von atomaren Schreibvorgängen, und hängen für Festplattenänderungen vom Betriebssystem ab.

Das Löschen von InnoDB auf diese Weise würde einen Neustart von mysql erfordern. Die anzuzeigenden Optionen sind innodb_flush_log_at_trx_commit und innodb_flush_method .

Fügen Sie diese vor dem Neustart hinzu

[mysqld]
flush = 1
flush_time = 10
innodb_flush_log_at_trx_commit = 0
innodb_flush_method = O_DIRECT

Bevor Sie diese Route wählen, sollten Sie prüfen, ob Journaling ein Problem darstellt. Ich habe es gesehen coole mysqlperformance-Blog-Post auf O_DIRECT wegen des Kernels gefälscht wurde. In demselben Beitrag wird auch erwähnt, dass MyISAM betroffen ist.

Ich habe über diesen Beitrag schon einmal geschrieben: ib_logfile wurde mit O_SYNC geöffnet, wenn innodb_flush_method = O_DSYNC

Versuche es !!!

RolandoMySQLDBA
quelle
1
Zur Verdeutlichung: Ich glaube, diese Arbeitslast belastet den / die Page Cleaner-Thread (s) und nicht den / die Purge-Thread (s). Die Mehrseitenbereinigung ist eine 5.7-Funktion, in 5.6 ist jedoch noch eine weitere Konfiguration möglich. Siehe: mysqlserverteam.com/mysql-5-7-improves-dml-oriented-workloads
Morgan Tocker
@MorganTocker @RolandoMySQLDBA Eine Sache, die mir in der sar -dAusgabe aufgefallen ist, awaitist, dass sie sich während eines Stalls fast verzehnfacht, während der Durchsatz sinkt. Halten Sie es für wahrscheinlich, dass es hier Probleme außerhalb von MySQL gibt, zum Beispiel mit dem I / O-Scheduler oder dem Journaling des Dateisystems?
James L
Ich bin durch Ändern der meisten Parameter, die Sie vorgeschlagen haben, mit Ausnahme von innodb_purge_threads (die einen Neustart erfordert). Es hat nicht viel für das Problem getan. Und ich bin zu der Überzeugung gelangt, dass die InnoDB-Engine hier nicht das Problem ist, da MyISAM-Tabelleneinfügungen ebenfalls blockieren.
syneticon-dj
Bitte posten Sie Ihre Einstellungen für innodb_read_io_threads und innodb_write_io_threads. RunSHOW GLOBAL VARIABLES LIKE '%io_threads';
RolandoMySQLDBA
1
@ syneticon-dj Wie wäre es mit Schreibvorgängen von außerhalb von MySQL in dasselbe Dateisystem?
James L