1. Systemumgebung
Betriebssystem: CentOS Linux Release 7.8.2003 (Core)
Kernel: 3.10.0-1127.19.1.el7.x86_64
MySQL: Sowohl 5.0 als auch 5.7 haben dieses Problem, es sollte nichts mit der Version zu tun haben
2. Druckmesswerkzeuge
Benchyou [1]
mysql_random_load [2]
3. Problemphänomen
Wenn Sie das Tool mysql_random_load verwenden, um eine Verbindung zu MySQL herzustellen und Daten zu schreiben, ist die Leistung sehr, sehr gering.
Da das Tool mysql_random_load keine Socket-Verbindungen unterstützt, musste ich aufgeben und stattdessen Benchyou verwenden . Übrigens sind Benchyou und Sysbench sehr ähnlich, aber auch sehr einfach zu bedienen.
Nach dem Umschalten auf das Benchyou- Werkzeug ist der Drucktest normal. Es scheint kein Problem mit der MySQL-Version zu sein.
Wenn Sie das Tool mysql_random_load verwenden, um einen Stresstest durchzuführen, ist die Systemlast sehr hoch, und es kann beobachtet werden, dass die Systemunterbrechung ebenfalls sehr hoch und ungleichmäßig ist.
[[email protected]]# vmstat -S m 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 73585 2 41051 0 0 117 91 4 2 0 0 99 0 0
2 0 0 73585 2 41051 0 0 0 28320 55444 100207 18 2 80 0 0
4 0 0 73584 2 41052 0 0 0 1936 52949 98607 18 2 81 0 0
2 0 0 73583 2 41052 0 0 0 4864 56375 101262 14 2 84 0 0
4 0 0 73583 2 41052 0 0 0 29064 55806 103715 19 2 80 0 0
5 0 0 73583 2 41052 0 0 0 5704 55854 98386 15 2 83 0 0
Sie können sehen, dass der Wert der Spalte system.in sehr hoch ist. Nach dem Wechsel zum Benchyou- Tool ist der Wert dieser Spalte von 55.000 auf 16.000 gesunken.
[[email protected]]# vmstat -S m 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
4 0 0 77238 2 38371 0 0 118 88 2 3 0 0 99 0 0
2 0 0 77234 2 38374 0 0 0 31620 16039 77988 3 2 95 0 0
2 0 0 77231 2 38377 0 0 0 31996 16091 78926 3 2 95 0 0
3 0 0 77229 2 38378 0 0 0 33028 16347 81006 3 2 95 0 0
0 0 0 77226 2 38383 0 0 0 52412 15496 75715 3 2 95 0 0
2 0 0 77224 2 38384 0 0 0 32252 16167 79352 3 2 95 0 0
Schauen wir uns die Leistung der Systemunterbrechung an, wenn ein Problem auftritt
[[email protected]]# mpstat -I SUM -P ALL 1
Linux 3.10.0-1127.19.1.el7.x86_64 (yejr.run) 09/28/2020 _x86_64_ (32 CPU)
05:37:40 PM CPU intr/s
05:37:41 PM all 51833.00
05:37:41 PM 0 2069.00
05:37:41 PM 1 1159.00
05:37:41 PM 2 2979.00
05:37:41 PM 3 1580.00
05:37:41 PM 4 1627.00
05:37:41 PM 5 1461.00
05:37:41 PM 6 1243.00
05:37:41 PM 7 1825.00
05:37:41 PM 8 2154.00
05:37:41 PM 9 1367.00
05:37:41 PM 10 1277.00
05:37:41 PM 11 1376.00
05:37:41 PM 12 4085.00
05:37:41 PM 13 1601.00
05:37:41 PM 14 4045.00
05:37:41 PM 15 1857.00
05:37:41 PM 16 1692.00
05:37:41 PM 17 722.00
05:37:41 PM 18 118.00
05:37:41 PM 19 1862.00
05:37:41 PM 20 1637.00
05:37:41 PM 21 1130.00
05:37:41 PM 22 1750.00
05:37:41 PM 23 1653.00
05:37:41 PM 24 1417.00
05:37:41 PM 25 1547.00
05:37:41 PM 26 1500.00
05:37:41 PM 27 1033.00
05:37:41 PM 28 20.00
05:37:41 PM 29 1683.00
05:37:41 PM 30 888.00
05:37:41 PM 31 1549.00
Es ist ersichtlich, dass die Gesamtzahl der Interrupts pro Sekunde 55.000 beträgt, die mehreren CPUs jedoch nicht ausgeglichen sind.
4. Problemanalyse
Zunächst wurde festgestellt, dass die Schreibleistung aufgrund hoher Systeminterrupts schlecht war, und es wurde auch festgestellt, dass dieses Problem durch das Ungleichgewicht der Interrupts zwischen mehreren CPUs verursacht wurde.
Beobachten Sie, welche Interrupts relativ hoch sind, und stellen Sie fest, dass LOC und RES einen relativ großen Anstieg pro Sekunde aufweisen.
[[email protected]]# watch -d cat /proc/interrupts
...
LOC: 2468939840 2374791518 2373834803 2373613050 Local timer interrupts
SPU: 0 0 0 0 Spurious interrupts
PMI: 0 0 0 0 Performance monitoring interrupts
IWI: 50073298 45861632 45568755 45833911 IRQ work interrupts
RTR: 0 0 0 0 APIC ICR read retries
RES: 3472920231 3022439316 2990464825 3012790828 Rescheduling interrupts
CAL: 5131479 6539715 17285454 11211131 Function call interrupts
TLB: 23094853 24045725 24230472 24271286 TLB shootdowns
TRM: 0 0 0 0 Thermal event interrupts
...
Nach dem Versuch, die durch die entsprechende Interrupt-Nummer gebundene CPU zu ändern (siehe: SMP-Affinität und ordnungsgemäße Interrupt-Behandlung unter Linux [3]), wird das Problem immer noch nicht behoben.
Später gab ein mysteriöser Chef eine Anleitung und stellte fest, dass es sich um einen Kernel-Fehler handelte, der den Parameter kernel.timer_migration betraf , der auf 0 gesetzt werden muss.
[[email protected]]# sysctl -w kernel.timer_migration=0
Natürlich ist es am besten, es dauerhaft in die Datei /etc/sysctl.conf zu schreiben .
[[email protected]]# cat /etc/sysctl.conf
kernel.timer_migration=0
#加载配置文件使之生效
[[email protected]]# sysctl -p
Verwenden Sie das Tool mysql_random_load , um den Stresstest erneut durchzuführen , und es wird in Ordnung sein.
Das Folgende ist eine Beschreibung des Fehlers
The bug is when linux os receive too many tcp packages,
and the tcp may add too many timer, but in
get_target_base->get_nohz_timer_target it check current
cpu is idle, sometimes thouth the current core is very busy,
but the idle_cpu result is 1, in this time
if set kernel.timer_migration=1 ,the timer will be move to next cpu.
Fehler 详情见 : Fehler 124661 - kernel.timer_migration = 1 verursacht zu viele Interrupts für die Neuplanung [4]
Schließlich ist zu erwähnen, dass das Ändern dieses Parameters auf dem Cloud-Host nur funktionieren sollte, wenn die physische Maschine geändert wird. Beim Ausführen des Drucktests des Tools mysql_random_load auf einem Cloud-Host ist ein ähnliches Problem aufgetreten. Das Problem blieb nach dem Ändern der Kernelparameter bestehen.
In-Text-Link
[1]: https: //github.com/xelabs/benchyou
[2]: https: //github.com/Percona-Lab/mysql_random_data_load
[3]: http: //www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux
[4]: https: //bugzilla.kernel.org/show_bug.cgi? Id = 124661
Der vollständige Text ist vorbei.
Viel Spaß mit Linux & MySQL :)
Der Kurs "MySQL Core Optimization" wurde auf MySQL 8.0 aktualisiert. Scannen Sie den Code, um die Reise des MySQL-Trainings zu beginnen