14 октября 2026 года Джонатан Миллер опубликовал на mariadb.org разбор MDEV-37992. Тикет завёл Марк Кэллахан: SELECT с длинным списком IN по первичному ключу. На каждом таком чтении InnoDB продвигает страницу в молодую часть LRU и берёт общий mutex буферного пула. Фонд прогнал ту же нагрузку через TAF на ветках 11.8, 12.3 и 13.1. Сравнивали родительский коммит и коммит с патчем из MDEV-33966. Патч поднял скорость примерно в 3,5 раза на всех трёх ветках.
Длинный IN и buf_pool.mutex
В JIRA тикет закрыт, резолюция Fixed. Компоненты Performance и Storage Engine InnoDB, метка regression. В шапке затронутая версия одна, 10.9.8. В описании просадка шире.
Кэллахан гонял points-covered на сервере с 48 ядрами: 8 таблиц по 10 миллионов строк, 40 потоков, в списке IN сто значений. Запрос по форме такой: выбрать id из sbtest1, где id входит в длинный список. До 10.4.34 это около 73 тысяч запросов в секунду. На 10.5.29 цифра падает примерно к 30 тысячам. На 10.8.8 она внезапно возвращается к 76 тысячам, а с 10.9.8 снова около 27 тысяч. Дальше по его таблице: 10.11.14 даёт 25 904, 11.4.8 даёт 25 598, 11.8.3 даёт 26 044, 12.1.1 даёт 25 916. План по explain не менялся.
Менялось число переключений контекста на один запрос. На 10.8.8 их 2,45, на 10.9.8 уже 36. Стеки из тикета упираются в buf_page_make_young: страница переезжает из старой части LRU в молодую, и на одном буферном пуле это захват buf_pool.mutex. С 10.5 пул в MariaDB один. Сорок потоков читают ключ из памяти и стоят на этом mutex, а не ждут диск.
Марко Мякеля в комментарии прямо отнёс MDEV-37992 к более раннему MDEV-33966. В release note того тикета алгоритм вытеснения LRU заменили на обход, который buf_pool.mutex не держит. Оба тикета закрыты с одним и тем же списком версий: 11.8.10, 12.3.4 и 13.1.2.
Шесть коммитов на 11.8, 12.3 и 13.1
Миллер мерил сборки по хешам. Это коммиты, не пакет из apt.
- Ветка 11.8. Родитель 14362356d14 дал 17 925 TPS. Патч db94f391be4e дал 66 653 TPS.
- Ветка 12.3. Родитель 5981efcecd8 дал 18 739 TPS. Патч 4083fbef83c6 дал 68 646 TPS.
- Ветка 13.1. Родитель d0661d9bb8c дал 18 737 TPS. Патч 5ab51d6248bb6 дал 66 145 TPS.
Родители держатся между 18 и 19 тысячами TPS, патчи между 66 и 68 тысячами. Фонд пишет, что после MDEV-33966 скорость выросла примерно в 3,5 раза. Нагрузка одна и та же: тест POINTS-COVERED-PK, 8 таблиц по 10 миллионов строк, 40 потоков, прогрев включён, буферный пул 90 ГБ. TAF сначала греет базу, потом ждёт, пока её процесс успокоится по загрузке CPU, и снимает цифры уже на ровном участке. Поэтому три ветки сравнимы между собой.
С таблицей Кэллахана это другой прогон. Другая машина, другой каркас, другая длина. 73 тысячи из его описания и 66 тысяч TPS фонда после патча в один ряд не складываются.
Буфер 90 ГБ и файл MDEV37992
Хост в посте назван Hetzner Sponsor Host. Процессор AMD EPYC 9454, 48 ядер и 96 логических CPU, один сокет, 124,98 ГБ памяти. Система AlmaLinux 9.8 (Olive Jaguar), ядро 5.14.0-687.29.1.el9_8. Пул на 90 ГБ на такой памяти оставляет запас и держит все 80 миллионов строк в RAM. На VPS с двумя или четырьмя ядрами и пулом в один-два гигабайта очередь на mutex короче. Множитель 3,5 с этого стенда на маленькую машину не переносится.
Файл прогона и скрипт лежат в коммите 64d46f0 репозитория MariaDB/TAF. В properties стоят innodb_buffer_pool_size=90G и innodb_old_blocks_time=1000. Строка со значением 2147483647 закомментирована. Именно этим значением Алессандро Ветере в тикете выключал продвижение страниц по LRU. На сборке main медиана у него выросла примерно с 18 945 до 57 286 запросов в секунду, физических чтений при этом ноль: данные уже были в памяти. Это проверка гипотезы. Рабочий патч фонда в другом месте. Меняется алгоритм вытеснения, а не ставится вечный запрет омолаживать страницы.
В том же файле выключены doublewrite и бинарный журнал. Скрипт шесть раз вызывает perl taf.pl. На каждую ветку сначала родитель, потом патч. Каталог установки смотрит на сборку с хешем коммита, теги вида MDEV33966_11.8_PARENT_CACHED. Перед прогоном cpupower переводит процессор в режим performance, ставит частоту 2100 МГц и выключает boost. Пути внутри скрипта ведут в /home/jeb/taf-perl. Это машина Миллера, не сервер с сайтом.
Сам файл properties в коммите лежит в каталоге properties/mariadb/mdevs/. Переменная PROP в скрипте указывает на properties/mariadb/MDEV37992.properties. Пока путь не поправить, taf.pl конфиг не откроет. После правки установка всё равно остаётся в дереве TAF. Юнит MariaDB, из которого сайт читает таблицы, скрипт не перезапускает и не подменяет.
11.8.10, 12.3.4 и 13.1.2
В обоих тикетах в поле Fix Version одни и те же три номера: 11.8.10, 12.3.4 и 13.1.2. В JIRA ни один не отмечен как выпущенный. У 12.3.4 стоит дата 30 октября 2026, у 13.1.2 дата 5 ноября 2026. У 11.8.10 даты нет. Пока этих номеров нет в выводе версии, обновление пакета из текущего репозитория этот патч не привезёт.
mariadb --version
sudo mariadb -e "SHOW VARIABLES WHERE Variable_name IN ('version','innodb_buffer_pool_size','innodb_old_blocks_time');"
На Ubuntu и Debian локальный сокет обычно пускает sudo mariadb без пароля. Если клиент спрашивает пароль, это уже ваша учётка.
Строка 10.11 или 11.4 к шести коммитам из поста не относится. Просадку точечных чтений по первичному ключу Кэллахан на этих ветках видел, но в Fix Version их не поставили. Сама ветка 11.8 тоже ещё не означает, что патч внутри: 11.8.3 в его таблице в просадке, а 11.8.10 только назначена под фикс.
Длинный IN на сайте с WordPress это не открытие одной записи. Одна запись читается одним поиском по первичному ключу. Список IN появляется у post__in и у плагинов, которые забирают пачку записей по готовым ID. Сорок потоков в прогоне фонда по порядку величины близки к пулу php-fpm с pm.max_children=40. На небольшом VPS воркеров обычно меньше, и база не занимает десятки гигабайт. Туда, где пул уже большой, данных хватает в память и одновременных чтений много, эта просадка как раз и попадает.
Пока пакета нет, блок из MDEV37992.properties в конфиг боевой базы лучше не переносить. innodb_buffer_pool_size=90G на машине с парой гигабайт памяти либо не выделится при старте, либо уйдёт в swap и положит вместе с базой ещё и php-fpm. innodb_doublewrite=0 и log_bin=OFF убирают двойную запись и бинарный журнал. На стенде, который TAF поднимает у себя и который можно снести, так короче прогон. На базе, с которой nginx и php-fpm отдают сайт, после сбоя восстанавливаться хуже.
cpupower из скрипта фиксирует частоту всего процессора, не одного процесса MariaDB. На машине, где рядом сайт, это уже не замер InnoDB.
Не ставьте innodb_old_blocks_time=2147483647, чтобы повторить эксперимент из тикета. Так глушат продвижение по LRU. Когда 11.8.10, 12.3.4 или 13.1.2 появятся в том репозитории, из которого стоит текущий пакет, порядок обычный. Сначала копия данных, потом обновление пакета, потом ещё раз mariadb –version. mysql_upgrade без повода и restart базы на всякий случай к этому фиксу не привязаны. До появления пакета конфиг сайта можно не трогать.