Механизм бинлога
В этой статье подробно объясняется механизм записи важного журнала binlog
в MySQL и основные конфигурации, влияющие на производительность ввода-вывода, а также рассказывается, как использовать binlog
для восстановления данных.
Как писать в бинлог?
Логика написания binlog
не сложна. Во время выполнения транзакции журнал сначала записывается в binlog
cache, а когда транзакция фиксируется, binlog
cache записывается в binlog
file.
Кэш Binlog
binlog cache
временно хранит binlog
данные во время выполнения транзакции, а binlog cache
пространственно независим в каждом потоке.
Если ведение журнала binlog
включено, MySQL выделяет кэш двоичного журнала для каждого клиента.
Если вы часто используете большие транзакции, вы можете увеличить размер кэша для повышения производительности. Его размер можно настроить через binlog_cache_size
, по умолчанию 32768 bytes
.
Основная функция этого параметра — контролировать размер памяти, занимаемой binlog
cache в одном потоке.
Если места binlog cache
достаточно, при фиксации транзакции содержимое кэша будет очищено, а данные будут записаны в файлы binlog
.
Поскольку binlog
content необходимо записать в один момент, когда транзакция зафиксирована, независимо от того, насколько она велика, когда кеш журнала бинов не может его поместить, его необходимо временно сохранить на диске, а затем фиксация записывается в binlog
файлов.
Вышеупомянутое написание binlog
фактически разделено на две части:
- Запись: во-первых, это будет записано в
binlog
files в кэше страниц, который представляет собой часть памяти, не занимающую IOPS на диске. - Fsync: тогда журнал bin фактически сохраняется из кэша страниц на диск, когда операционная система выполняет
fsync
; он занимает дисковые IOPS.
Когда write
и fsync
?
Синхронизация write
и fsync
управляется параметром sync_binlog
:
sync_binlog=0
: указывает, что каждая транзакция фиксации только записывается и fsync
не выполняется, то есть binlog
не сохраняется (не рекомендуется).
sync_binlog=1
: указывает, что fsync
происходит каждый раз, когда транзакция фиксируется.
sync_binlog=N
: указывает, что каждая транзакция будет записываться, но отправка N
транзакций будет выполняться fsync
для сохранения.
Вообще говоря, для увеличения IOPS этот параметр устанавливается в пределах 100–1000. Недостатком является то, что если машина выйдет из строя до выполнения fsync
, binlog
log самых последних N
транзакций будет потерян не более чем. Установите 1
для защиты данных.
Официальная документация описывает это следующим образом:
По умолчанию двоичный журнал синхронизируется с диском при каждой записи (
sync_binlog=1
). Если «sync_binlog
не был включен, а операционная система или машина (не только сервер MySQL) вышли из строя, есть шанс, что последние операторы двоичного журнала могут быть потеряны.
Чтобы предотвратить это, включите системную переменную
sync_binlog
, чтобы синхронизировать двоичный журнал с диском после каждыхN
групп фиксации. См. Раздел 5.1.8, «Системные переменные сервера». Самое безопасное значение дляsync_binlog
— 1 (по умолчанию), но оно также и самое медленное».
Что делать, если binlog
контента нет?
Мы уже знаем, что данные можно восстановить через redo log
, но что, если содержимое binlog
отсутствует?
Согласно описанию параметра sync_binlog
, если он установлен больше единицы, это означает, что N
транзакций будут сохраняться в журнале на диск.
В то же время параметр innodb_flush_log_at_trx_commit
redo log
устанавливается равным 1
, что означает, что fsync
будет выполняться для каждой зафиксированной транзакции.
Это создает вероятность того, что в случае сбоя сервера MySQL redo log
сохраняется в это время, но binlog
и транзакции все еще хранятся в кэше страниц, и нет времени для выполнения fsync
.
После перезапуска службы после простоя и использования redo log
для восстановления данных binlog
length будет короче, чем должны быть фактические данные.
Что произойдет в этом случае, учитывая полные данные, но отсутствующие binlog
? Сначала я был озадачен. Наконец, я нашел ответ в официальной документации MySQL 5.7.
Официальная документация описывает это следующим образом:
«Если сервер MySQL обнаруживает при восстановлении после сбоя, что двоичный журнал короче, чем должен был быть, значит, отсутствует как минимум одна успешно совершенная
InnoDB
транзакция. Этого не должно происходить, еслиsync_binlog=1
и дисковая/файловая система выполняют реальную синхронизацию по запросу (некоторые этого не делают), поэтому сервер выводит сообщение об ошибкеThe binary log *
имя_файла* is shorter than its expected size
.
В этом случае этот двоичный журнал неверен, и репликацию следует перезапустить из нового моментального снимка исходных данных».
Согласно официальному описанию, если sync_binlog
установить на 1
, этого не произойдет. Если binlog
меньше ожидаемого, на сервере будет напечатан ненормальный лог binlog
:
The binary log xxx is shorter than its expected size.
Таким образом, эта ситуация требует вмешательства человека и повторного копирования из самого последнего источника данных моментального снимка.
Как использовать Bin Log для восстановления исторических данных?
binlog
будет записывать все логические операции, и в форме «добавления записи» он не будет перезаписывать файлы журнала, такие как redo log
.
Данные в binlog
надежны и должны быть данными после фиксации транзакции, что гарантируется двухфазной фиксацией журнала повторов.
Как мы все знаем, мы можем восстановить данные в любой момент времени через bin log
, как это сделать?
На самом деле это обязательное условие. У нас должен быть механизм регулярного резервного копирования всего объема данных, например, раз в полмесяца, каждую неделю или каждый день.
Гипотетический сценарий. Например, данные таблицы были удалены по ошибке сегодня в полдень, и их необходимо восстановить. Что я должен делать?
- Сначала найдите самую последнюю полную резервную копию, например, сделанную вчера в 1:00, а затем восстановите эту резервную копию во временной базе данных.
- Затем, начиная со времени резервного копирования в
1:00
утра вчера, резервные копииbinlog
извлекаются и последовательно воспроизводятся до данных в12:00
полудня сегодняшнего дня.
Таким образом, временная база данных достигает состояния до того, как данные были случайно удалены, а затем данные таблицы могут быть извлечены из временной базы данных и восстановлены в интерактивной официальной базе данных по мере необходимости.
Спасибо, что прочитали эту статью.