Выберите продукт

MySQL супер‑режим read_only: безопасные окна работ с super_read_only и sql_log_bin

Практическое руководство для админов: как использовать read_only, super_read_only и sql_log_bin, чтобы открыть безопасное окно обслуживания без лишних рисков записи. Разберём роли переключателей, сценарии для мастера и реплик, GTID, бэкапы, наблюдаемость и частые ловушки.
MySQL супер‑режим read_only: безопасные окна работ с super_read_only и sql_log_bin

В любой живой базе неизбежны окна обслуживания: миграции схемы, перестройка индексов, обновления движка, слепки данных. Главный риск — случайные записи со стороны приложений или людей с привилегиями. В MySQL для защиты есть три ключевых рычага: read_only, super_read_only и сессионный флаг sql_log_bin. Вместе они позволяют строить «супер‑режим» безопасного обслуживания, когда записи блокируются корректно, а вспомогательные операции не расползаются по репликации.

Что делают read_only, super_read_only и sql_log_bin

read_only — глобальный флаг, запрещающий записи для всех пользователей, кроме тех, у кого есть привилегия SUPER (в MySQL 8.0 заменена на SYSTEM_VARIABLES_ADMIN и др.) и потоков репликации. С включённым read_only обычные приложения перестают модифицировать данные, но администратор с привилегиями всё ещё может писать, как и репликационный аплаер.

super_read_only — усиливает политику: запрещает записи даже пользователям с SUPER, оставляя «окно» только для внутреннего репликационного потока. Это именно то, что нам нужно для по‑настоящему «замороженного» мастера или стойко защищённой реплики.

sql_log_bin — сессионный переключатель, управляющий записью выполняемых команд в бинарный лог. Его типичный кейс: нужно что-то сделать локально (например, на реплике или на мастере перед переключением ролей), но не хотим, чтобы операция ушла по репликации. Тогда в этой сессии включаем sql_log_bin=0. Важно: это именно сессионный флаг, глобально установить его нельзя.

Репликационный поток в MySQL имеет иммунитет к read_only и super_read_only. Это позволяет держать реплики в постоянном «read‑only» без риска остановки аплая.

Дополнения и тонкости

  • super_read_only существует в MySQL 5.7+; в старых версиях его нет и защиту суперпользователя придётся обеспечивать процессом и доступами.
  • Создание временных таблиц пользователями возможно и при read_only=ON — учитывайте место на диске.
  • С super_read_only=ON блокируются и изменения системной БД mysql (например, GRANT), что хорошо для безопасности в окне работ.
  • Для MySQL 8.0+ можно использовать SET PERSIST, но для временных окон обслуживания чаще не следует сохранять флаги на диск.

Базовые операции: как включить и проверить

# Включить «супер‑режим» (сначала read_only, затем super_read_only)
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;

# Проверить состояние
SHOW GLOBAL VARIABLES LIKE 'read_only';
SHOW GLOBAL VARIABLES LIKE 'super_read_only';

# Снять ограничения (сначала super_read_only, затем read_only)
SET GLOBAL super_read_only = OFF;
SET GLOBAL read_only = OFF;

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

SELECT trx_id, trx_started, trx_state, trx_rows_modified
FROM information_schema.innodb_trx
WHERE trx_operation_state IS NOT NULL;

SHOW PROCESSLIST;

Если видите долгие изменения, корректно завершаем или откатываем их согласно регламенту обслуживания.

Если вы делаете файловый снимок (snapshot), помните: FLUSH TABLES WITH READ LOCK даёт глобальный блок на таблицы MyISAM и стоп/квиктюны метаданных, но для InnoDB на современных версиях лучше использовать LOCK INSTANCE FOR BACKUP — он мягче для нагрузки. Комбинация с super_read_only снижает шанс несогласованности во время окна. Для восстановления до точки времени и общего подхода к журналам см. материал PITR по binlog и GTID.

# Пример краткого окна для снимка
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;
LOCK INSTANCE FOR BACKUP;
-- делаем снимок ФС
UNLOCK INSTANCE;
SET GLOBAL super_read_only = OFF;
SET GLOBAL read_only = OFF;

Схема репликации MySQL: мастер и реплики в режиме read_only/super_read_only

«Супер‑режим» для одиночного сервера

Сценарий: у вас один инстанс MySQL, нужно безопасно провести схему‑миграцию или короткий бэкап с консистентной точкой.

  1. Проверяем активные записи и блокировки, уведомляем приложение о предстоящем окне.
  2. Включаем read_only и super_read_only.
  3. Проверяем, что новые транзакции записи начали падать с ошибками, а чтения работают.
  4. Выполняем операции: DDL, экспорт метаданных, снимок LVM или файловой системы, проверяем целостность.
  5. Выключаем super_read_only, потом read_only, возвращаем трафик.

Мастер и реплики: правильные политики

Реплики

Реплики разумно держать в защищённом состоянии постоянно: read_only=ON, super_read_only=ON. Это предотвращает случайные записи через консоль и скрипты. При этом поток репликации применяет события как обычно.

# my.cnf для реплики
[mysqld]
read_only = ON
super_read_only = ON

Если на реплике включён бинарный лог (например, это промежуточный узел в цепочке), для локальных технических действий пользуемся сессионным sql_log_bin=0, чтобы операции не ушли дальше:

-- Только в текущей сессии!
SET SESSION sql_log_bin = 0;
-- Если включён GTID, безопаснее явно анонсировать анонимные транзакции
SET SESSION gtid_next = 'ANONYMOUS';
-- локальные операции, не для репликации
ANALYZE TABLE mydb.t1;
OPTIMIZE TABLE mydb.t2;
SET SESSION gtid_next = 'AUTOMATIC';
SET SESSION sql_log_bin = 1;

Такой подход особенно полезен для операций обслуживания вроде ANALYZE, перезаписи статистики, перестроения вторичных индексов с ALGORITHM=INPLACE/INSTANT, которые вы не хотите транслировать вниз по топологии.

Сессия DBA с отключённым sql_log_bin для локальных операций на реплике

Мастер

На мастере read_only и super_read_only обычно выключены. Но для короткого и предсказуемого окна работ можно включить их вместе, предварительно убедившись, что реплики догнали мастера.

  1. Проверяем задержку реплик и длинные транзакции на мастере.
  2. Включаем read_only и super_read_only. Приложение начинает получать ошибки на запись — окно должно быть минимальным.
  3. Делаем нужные действия: фиксация контрольной точки для бэкапа, подготовка к failover, критичный DDL с недопустимой рассинхронизацией.
  4. Отключаем флаги в обратном порядке и возвращаем трафик.

Если ваш пайплайн подразумевает переключение ролей (promote реплики), то перед promote убедитесь, что старый мастер находится в «супер‑режиме» и не принимает запись, иначе будет split‑brain. Полезно автоматизировать проверку флагов в оркестрации. Про сценарии переключений с GTID и политику semi-sync см. статью GTID и semi-sync failover.

Производственные кластеры удобнее держать на изолированных серверах или виртуалках; если нужна гибкая топология и быстрый апгрейд CPU/IO, рассмотрите VDS с выделенными ресурсами.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

sql_log_bin: безопасные локальные операции

sql_log_bin — сессионный. Он не изменяет глобальную политику и не снимает read_only/super_read_only. Это именно про контроль записи в бинарный лог для текущей сессии. Типичные кейсы:

  • Локальное обслуживание на реплике, которая транзитом ретранслирует события дальше.
  • Однократные фиксы метаданных, которые не должны попасть в другие узлы.
  • Проверочные операции и инспекции, которые затрагивают служебные таблицы, но не должны попадать в репликацию.

При включённом GTID используйте связку SET SESSION sql_log_bin = 0 и SET SESSION gtid_next = 'ANONYMOUS', затем верните gtid_next в 'AUTOMATIC'. Это предотвращает ошибки согласованности и «дыры» в последовательности.

Важно помнить: такие операции не попадут в бинарный лог и не будут реплицированы, поэтому их последствия останутся только на текущем узле. Это ожидаемое поведение — учитывайте это в регламентах и документации.

Шаблоны процедур: от простого к продвинутому

Короткое окно для DDL с риском блокировок

-- Проверяем активные записи
SELECT COUNT(*) FROM information_schema.innodb_trx WHERE trx_rows_modified > 0;
-- Включаем режим
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;
-- Делаем DDL
ALTER TABLE app.users ADD COLUMN flags INT NOT NULL DEFAULT 0, ALGORITHM=INPLACE, LOCK=NONE;
-- Выключаем режим
SET GLOBAL super_read_only = OFF;
SET GLOBAL read_only = OFF;

Если DDL всё же потребовал блокировок (например, перестройка первичного ключа), окно лучше выносить на период минимальной нагрузки и иметь план отката.

Подготовка к failover

  1. Убедиться, что все реплики догнали мастера (задержка нулевая).
  2. На мастере включить read_only и super_read_only.
  3. Снять контрольный слепок состояния (позиция в binlog/GTID), зафиксировать метрики.
  4. Promote реплику и перевести трафик.
  5. Старый мастер оставить в super_read_only до полной ресинхронизации и переинициализации как реплики.

Обслуживание на промежуточной реплике

-- Реплика постоянно в read-only/super-read-only
-- Для локальной операции не для репликации
SET SESSION sql_log_bin = 0;
SET SESSION gtid_next = 'ANONYMOUS';
ANALYZE TABLE analytics.events;
SET SESSION gtid_next = 'AUTOMATIC';
SET SESSION sql_log_bin = 1;

Частые ошибки и ловушки

  • Включили только read_only. Пользователь с SUPER всё ещё может писать. Итог — «дырка» в защите. Используйте оба флага.
  • Сняли флаги в неверном порядке. Сначала выключайте super_read_only, затем read_only, чтобы не получить короткий момент, когда SUPER может писать.
  • Забыли вернуть sql_log_bin. Дальнейшие действия останутся вне бинарного лога, нарушится предсказуемость. Работайте в отдельной сессии и закрывайте её сразу после операции.
  • Игнорирование длинных транзакций. Включение read‑only посреди долгих записей ведёт к таймаутам и ретраям на приложении. Лучше дождаться завершения или принудительно остановить согласно регламенту.
  • Несогласованность GTID. При GTID и sql_log_bin=0 не забудьте gtid_next='ANONYMOUS' и возврат в 'AUTOMATIC'.
  • События планировщика и триггеры. В «супер‑режиме» они тоже не должны писать, но проверяйте бизнес‑триггеры и отложенные задания — возможно, их стоит временно отключить на уровне приложения.

Наблюдаемость во время окна

Поддерживайте видимость состояния:

  • SHOW GLOBAL STATUS: метрики соединений, ошибок, откатов.
  • SHOW ENGINE INNODB STATUS: блокировки и ожидания.
  • SHOW SLAVE STATUS или SHOW REPLICA STATUS: задержка репликации, номера журналов.
  • Проверка версий переменных: SELECT @@global.read_only, @@global.super_read_only;

Имеет смысл вывести состояние в мониторинг заранее, чтобы дашборд «краснел» предсказуемо и не тревожил смену понапрасну.

Политики по умолчанию

  • Реплики: read_only=ON, super_read_only=ON в конфиге. Временные исключения — только сессионные и только под регламент.
  • Мастер: оба флага OFF. На время обслуживания включаем оба, минимизируем окно, держим план отката.
  • Сессионные операции: только через отдельные подключения с явным sql_log_bin=0 и возвратом в дефолт, желательно с ролевой сегрегацией доступа.

Чек‑лист безопасного окна

  1. Уведомили приложение и стейкхолдеров, подготовили таймбокс и обратный план.
  2. Проверили длинные транзакции, задержку реплик, состояние блокировок.
  3. Включили read_only и super_read_only в нужной последовательности.
  4. Выполнили операции, требующие заморозки записи, при необходимости использовали LOCK INSTANCE FOR BACKUP.
  5. Выключили флаги, проверили метрики, провели функциональные прогоны.
  6. Задокументировали изменения и артефакты (позиции binlog/GTID, версии схемы).

Короткий FAQ

Можно ли навсегда держать мастер в read_only и просто выдавать SUPER приложению? Нет. Это нарушает модель безопасности и усложняет анализ инцидентов. Используйте принцип наименьших привилегий.

Чем FLUSH TABLES WITH READ LOCK отличается от super_read_only? FTWRL — глобальная блокировка на уровне сервера, влияющая на метаданные и MyISAM; super_read_only — политика запрета записи транзакций пользователями. Для InnoDB‑нагрузки «супер‑режим» обычно мягче и достаточен, FTWRL нужен для специфических задач.

Будет ли реплика писать при super_read_only=ON? Да, поток репликации применяет события независимо, и это ожидаемо.

Нужно ли включать sql_log_bin=0 при всех сервисных операциях? Нет. Только там, где вы осознанно не хотите реплицировать эффект. По умолчанию лучше оставлять бинарный лог включенным.

Итоги

Правильная комбинация read_only, super_read_only и аккуратного использования sql_log_bin превращает окна обслуживания MySQL в предсказуемую и безопасную процедуру. «Супер‑режим» жестко отсекает любые записи, кроме репликации, а сессионное отключение бинарного лога помогает выполнять локальные задачи без сторонних эффектов. Добавьте мониторинг, чек‑листы и дисциплину — и даже непростые миграции пройдут без сюрпризов.

Поделиться статьей

Вам будет интересно

MySQL HA на keepalived + ProxySQL: VIP failover без split-brain и с проверками здоровья OpenAI Статья написана AI (GPT 5)

MySQL HA на keepalived + ProxySQL: VIP failover без split-brain и с проверками здоровья

Разбираем рабочую схему MySQL HA: два узла ProxySQL под VIP на keepalived (VRRP unicast). Настраиваем health checks, maintenance m ...
Docker/Compose: IPAM, DNS и MTU — как диагностировать и исправлять сетевые проблемы OpenAI Статья написана AI (GPT 5)

Docker/Compose: IPAM, DNS и MTU — как диагностировать и исправлять сетевые проблемы

Сети в Docker обычно «просто работают», пока не появляется: container cannot resolve, резолвинг через раз, таймауты без ошибок или ...
IDN и Punycode: как работают международные домены и как защититься от homograph attack OpenAI Статья написана AI (GPT 5)

IDN и Punycode: как работают международные домены и как защититься от homograph attack

IDN-домены удобны для брендов и проектов, но из-за похожих символов появляются homograph-атаки и фишинг. Разбираем punycode (xn--) ...