PmaControl logo PmaControl
  • Главная
  • PmaControl
    • ИИ-агенты 13 on-premise агентов
    • Тарифы Community, Cloud, On-Premise, Premium
    • Документация Руководства, API, архитектура
    • Маркетплейс Плагины сообщества
    • Клиенты 28+ компаний
    • FAQ 25 вопросов / 7 категорий
    Базы данных
    • MariaDB 32 статей
    • MySQL 13 статей
    • Galera Cluster 6 статей
    • MaxScale 4 статьи
    • ProxySQL 2 статьи
    • Amazon Aurora MySQL 0 статьи
    • Azure Database 0 статьи
    • ClickHouse 0 статьи
    • GCP CloudSQL 0 статьи
    • Percona Server 0 статьи
    • SingleStore 0 статьи
    • TiDB 0 статьи
    • Vitess 0 статьи
    Решения
    • Поддержка 24×7 Экстренная помощь MariaDB & MySQL
    • Observabilité SQL Мониторинг, алерты, топология
    • Haute disponibilité Репликация, failover, Galera
    • Disaster Recovery Backup, restore, RPO/RTO
    • Sécurité & conformité Аудит, GDPR, SOC2
    • Migration & upgrade Zero downtime, pt-osc, gh-ost
  • Тарифы
  • Ресурсы
    • Документация Технические руководства и API
    • Центр оптимизации MySQL Markdown-индекс, метрики, параметры, инциденты
    • FAQ 25 частых вопросов
    • Отзывы Отзывы клиентов и кейсы
    • Блог Статьи и аналитика
    • Roadmap Планируемые функции
    Области экспертизы
    • Observabilité SQL Мониторинг, алерты, топология Dot3
    • Haute disponibilité Репликация, failover, Galera
    • Sécurité & conformité Аудит, GDPR, SOC2, ISO 27001
    • Disaster Recovery Backup, restore, RPO/RTO
    • Performance & optimisation Digests, EXPLAIN, tuning
    • Migration & upgrade Zero downtime, pt-osc
    Быстрые ссылки
    • Wiki GitHub 26 страниц — установка, движок, плагины
    • Исходный код Официальный репозиторий GitHub
    • Поддержка 24×7 Экстренная помощь MariaDB & MySQL
    • Записаться на демо 30 мин — реальная архитектура
  • Поддержка 24×7
  • Записаться на демо
Записаться на демо
🇫🇷 FR Français 🇬🇧 EN English 🇵🇱 PL Polski 🇷🇺 RU Русский 🇨🇳 ZH 中文 🇸🇦 AR العربية
← Вернуться в блог

Когда фикс атомарности ускоряет ингестию на 12%

Опубликовано July 25, 2026 Автор Aurélien LEQUOY
mariadb mysql innodb time-series performance transactions pmacontrol
Поделиться X LinkedIn Facebook Email PDF
Когда фикс атомарности ускоряет ингестию на 12%

Контекст: самый горячий путь записи в PmaControl

Каждые несколько секунд каждый агент PmaControl собирает сотни метрик с ваших серверов MariaDB / MySQL: статусные переменные, счётчики InnoDB, состояние репликации, дайджесты запросов. Всё это стекается в Integrate::insert_value(), который пишет измерения в таблицы ts_value_general_* — самый нагруженный путь записи в приложении.

Чтобы никогда не превышать max_allowed_packet, кортежи группируются в чанки: SQL-бюджет вычисляется динамически по данным сервера (с запасом), и партия из 200 000 измерений превращается, например, в 32 запроса INSERT INTO ... VALUES (...), (...), ... примерно по 256 КиБ каждый.

До сих пор эти 32 запроса выполнялись в режиме autocommit: 32 INSERT, 32 неявных COMMIT.

Баг: тихие частичные записи

Что происходит, если чанк № 17 падает — переполненная таблица, дедлок, разрыв соединения?

До фикса: чанки с 1 по 16 оставались записанными, чанки с 17 по 32 терялись, а последующий учёт (связка сервер/переменная, чекпоинт ингестии) мог выполниться так, будто всё прошло успешно. Логическая партия превращалась в тихую частичную запись — худший сценарий для данных мониторинга: графики с дырами, о которых никто не сообщает.

Три отдельных задачи сходились к одной и той же первопричине:

  • #1467 / #1471 — частичные записи при сбое посреди партии;
  • #1468 / #1472 — одиночный кортеж крупнее бюджета всё равно отправлялся на сервер, гарантированно падая на max_allowed_packet;
  • #1469 — тихий фолбэк мог отключить динамическое определение бюджета.

Фикс: одна партия = одна транзакция

Исправление (PR #2323) вводит executeTimeSeriesInsertBatch(): все чанки одного типа метрики теперь обёрнуты в одну транзакцию:

START TRANSACTION;
INSERT INTO ts_value_general_int (...) VALUES (...), (...), ...;  -- чанк 1
INSERT INTO ts_value_general_int (...) VALUES (...), (...), ...;  -- чанк 2
-- ... ещё 30 чанков ...
COMMIT;

Любой сбой — falsy-результат, небезобидный warning, исключение — вызывает ROLLBACK и поднимает типизированное исключение с безопасными диагностическими метаданными (таблица, чанк, оценка байтов, бюджет). Файл измерений сохраняется для повтора: либо вся партия записана, либо ничего.

Бонус: одиночный кортеж, чей оценочный размер уже превышает бюджет, обнаруживается до открытия транзакции — заведомо обречённый INSERT вообще не отправляется на сервер.

Вопрос на 12%: сколько это стоит?

Транзакция на 32 запроса — это дополнительная бухгалтерия на стороне InnoDB: более длинный undo log, дольше удерживаемые блокировки. Мы ожидали небольших накладных расходов и считали их справедливой ценой за гарантию атомарности.

Перед мержем мы сделали бенчмарк. Протокол:

  • точное воспроизведение горячего цикла insert_value() (чанкование → сборка SQL → выполнение), а не синтетический микробенчмарк;
  • 200 000 детерминированных кортежей в ts_value_general_int (уникальные первичные ключи), бюджет 256 КиБ → 32 чанка;
  • MariaDB 11.8, PHP 8.5.8, таблица InnoDB, TRUNCATE между прогонами, 1 прогрев + 5 измеряемых прогонов;
  • один и тот же LXC-контейнер, одни и те же данные, между замерами меняется только код приложения.

Результаты:

Прогон До (autocommit ×32) После (1 транзакция)
1 1,127 с 0,927 с
2 1,199 с 0,947 с
3 1,155 с 1,012 с
4 1,168 с 1,019 с
5 1,157 с 1,026 с
Медиана 1,157 с 1,012 с

Медиана быстрее на 12,5%. Фикс атомарности ничего не стоит — он экономит время. Пропускная способность ингестии выросла примерно со 173 000 до 198 000 измерений в секунду.

Почему быстрее: скрытая цена COMMIT

Ответ кроется в том, что COMMIT на самом деле делает в InnoDB.

При каждой фиксации InnoDB обязан сделать транзакцию долговечной: записать страницы redo-лога и — при innodb_flush_log_at_trx_commit = 1, значении по умолчанию и единственном по-настоящему безопасном — принудительно выполнить fsync() файла лога. Этот flush — самая дорогая операция в жизненном цикле транзакции: она физически ждёт хранилище.

В режиме autocommit каждый INSERT — отдельная транзакция:

  • до: 32 чанка = 32 COMMIT = 32 сброса redo-лога;
  • после: 32 чанка = 1 COMMIT = 1 сброс redo-лога.

Сэкономленная 31 синхронизация весит куда больше, чем чуть более длинный undo log. Это тот же механизм, из-за которого SQL-импорт в транзакции работает радикально быстрее, а group commit в MariaDB амортизирует сбросы между конкурентными транзакциями — здесь он применён внутри одной логической партии.

Выигрыш зависит от железа: на хранилище с очень медленным fsync() (механические диски, виртуализация без безопасного кэша записи) разрыв ещё больше. На быстром NVMe он сокращается. Но знак не меняется: одна транзакция всегда как минимум не медленнее.

Выводы

  • Атомарность — не роскошь, за которую платят; часто это оптимизация. Группировка связанных записей в одну транзакцию устраняет сбросы redo-лога — надёжность и производительность работают в одну сторону.
  • Бенчмаркайте реальный путь кода. Именно воспроизведение настоящего горячего цикла на настоящей базе превратило «мы принимаем накладные расходы» в «накладных расходов нет».
  • Сбой должен быть громким и полным. Наполовину записанная партия метрик хуже, чем партия, записанная повторно: с этим фиксом PmaControl гарантирует «всё или ничего» для ингестии time-series.

Фикс доступен в ветке master PmaControl с 25 июля 2026 года.

Поделиться X LinkedIn Facebook Email PDF
← Вернуться в блог

Комментарии (0)

Комментариев пока нет.

Оставить комментарий

PmaControl
+33 6 63 28 27 47 contact@pmacontrol.com
Юридическая информация GitHub Контакты
Не ждите инцидента, чтобы понять свою архитектуру. © 2014-2026 PmaControl — 68Koncept