TGViewer
Сохранёнки программиста Сохранёнки программиста @prog_stuff · 6.54K subscribers
Post #2904 614
Лимит одновременных транзакций подняли с тысячи до десяти тысяч, чтобы убрать ошибки, и получили шестнадцать минут деградации

Лиз ван Дейк из PlanetScale разобрала 7 августа инцидент, в котором продакшен-база MySQL складывалась на шестнадцать минут. Ошибки шли по нарастающей: на нулевой минуте 5 ошибок в минуту при 15 000 запросов в секунду, на десятой 1400 ошибок и 1500 запросов, потом транзакцию убил таймаут, накопленное разгреблось примерно за тридцать секунд, и пропускная способность подскочила до 8500.

Повод банальный: пакетная задача открыла транзакцию к горячей таблице, взяла блокировки строк и держала их пятнадцать минут без коммита. Интересно то, что происходило вокруг неё. Запросы, копившиеся следом, в основном на блокировках вообще не стояли: это обычные чтения, которым InnoDB отдаёт согласованный снимок. Но построение снимка требует пройти назад по истории версий каждой затронутой строки, а эта история росла все пятнадцать минут.

🔘 чтения, которые обычно занимают миллисекунды, начали упираться в потолок выполнения в 90 секунд, приложение повторяло их в тесном цикле;
🔘 за минуты внутри движка хранения скопилось больше десяти тысяч запросов, каждый восстанавливал всё более длинную цепочку версий;
🔘 чтения страниц обогнали способность буферного пула освобождать память, и падать начали запросы к совершенно другим таблицам, никак не связанным с заблокированными строками;
🔘 предыстория в том, что нагрузку переехали с прежней базы, где перед сервером стоял пул потоков: он ограничивал число одновременных запросов примерно тысячей, а остальных ставил в очередь на миллисекунды;
🔘 на новом месте пул при переполнении не ставит в очередь, а ждёт фиксированное время и возвращает ошибку. Приложение таких ошибок никогда не видело и обрабатывать их не умело, поэтому лимит подняли до десяти тысяч. Число выбрали не по расчёту, а потому что с ним ошибки прекратились;
🔘 лечение оказалось обратным: лимит вернули примерно к тысяче и заменили ошибку ожиданием в очереди с увеличенным таймаутом, то есть повторили поведение прежнего пула потоков.

На следующее утро конфигурация прошла проверку на другом шарде, который держит на порядок больше трафика: на пике около 25 тысяч заявок на слот в секунду при тысяче слотов, ноль ошибок и ровные 60 тысяч запросов в секунду. За весь день отклонена одна транзакция, а внутри MySQL в каждый момент выполнялось меньше двухсот команд: по закону Литтла это примерно три миллисекунды на запрос.

Автор оговаривает, что это не универсальный совет всегда зажимать параллелизм. Совет работает там, где есть пессимистичные блокировки и общее состояние: горячие строки, SELECT ... FOR UPDATE по популярным ключам, счётчики, балансы, очереди задач. И это не свойство MySQL: в PostgreSQL бывает то же самое, а роль ограничителя там играет PgBouncer.

Полная статья: https://planetscale.com/blog/concurrency-vs-throughput-vitess-mysql

@prog_stuff
More from @prog_stuff
  1. Sep 20, 2026Как процессор предсказывает ветвления Псевдотранскрипт доклада объясняет тему с нуля. Конв…
  2. Sep 20, 2026Почему одни движки регулярных выражений зависают, а другие нет Обстоятельная статья Расса…
  3. Sep 19, 2026Как проверять изменения без риска для всего трафика Компактный разбор о снижении риска при…
  4. Sep 19, 2026Как собрать модель пиковой нагрузки из боевой телеметрии Обстоятельный гайд о замене выгру…
  5. Sep 18, 2026Как работает фильтр Блума и когда его неточность экономит память Фильтр Блума сообщает: «э…
  6. Sep 17, 2026Как работает однопошаговый отладчик Linux на ptrace Обстоятельная статья разбирает основу…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →