1. Системная среда
ОС: CentOS Linux, выпуск 7.8.2003 (Core)
Ядро: 3.10.0-1127.19.1.el7.x86_64
MySQL: и 5.0, и 5.7 имеют эту проблему, она не должна иметь ничего общего с версией
2. Инструменты для измерения давления
скамейка [1]
mysql_random_load [2]
3. Проблемное явление
При использовании инструмента mysql_random_load для подключения к MySQL для записи данных производительность очень низкая.
Поскольку инструмент mysql_random_load не поддерживает подключение к сокету, мне пришлось отказаться и вместо этого использовать benchyou . Кстати, benchyou и sysbench очень похожи, но при этом очень просты в использовании.
После переключения на инструмент benchyou проверка давлением проходит нормально. Похоже, это не проблема с версией MySQL.
При использовании инструмента mysql_random_load для выполнения стресс-теста нагрузка на систему очень высока, и можно заметить, что прерывание системы также очень велико и неравномерно.
[[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
Видно, что значение столбца system.in очень высокое.После перехода на инструмент benchyou значение этого столбца упало с 55000 до 16000.
[[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
Давайте посмотрим на производительность прерывания системы при возникновении проблемы
[[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
Видно, что общее количество прерываний в секунду составляет 55 000, но несколько процессоров не сбалансированы.
4. Анализ проблемы
Первоначально было определено, что производительность записи была низкой из-за большого количества системных прерываний, а также было определено, что эта проблема была вызвана дисбалансом прерываний между несколькими процессорами.
Обратите внимание, какие прерывания относительно высоки, и обнаружите, что LOC и RES имеют относительно большое увеличение в секунду.
[[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
...
После попытки изменить процессор, привязанный к соответствующему номеру прерывания (см. SMP-соответствие и правильная обработка прерываний в Linux [3]), проблема все еще не решена.
Позже таинственный босс дал некоторые указания и выяснил, что это оказалась ошибка ядра, связанная с параметром kernel.timer_migration , который необходимо установить в 0.
[[email protected]]# sysctl -w kernel.timer_migration=0
Конечно, лучше всего постоянно записывать его в файл /etc/sysctl.conf .
[[email protected]]# cat /etc/sysctl.conf
kernel.timer_migration=0
#加载配置文件使之生效
[[email protected]]# sysctl -p
Используйте инструмент mysql_random_load , чтобы снова выполнить стресс-тест, и все будет хорошо.
Ниже приводится описание ошибки.
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.
ошибка 详情见 :Ошибка 124661 - kernel.timer_migration = 1 вызывает слишком много прерываний перепланирования [4]
Наконец, стоит упомянуть, что изменение этого параметра на облачном хосте не должно работать, если физический компьютер не изменен. Я столкнулся с аналогичной проблемой при запуске теста давления инструмента mysql_random_load на облачном хосте. Проблема не исчезла после изменения параметров ядра.
Текстовая ссылка
[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
Полный текст окончен.
Наслаждайтесь Linux и MySQL :)
Курс «Оптимизация ядра MySQL» был обновлен до MySQL 8.0, отсканируйте код, чтобы начать путешествие по обучению MySQL