Улучшения бинарного журнала и репликации¶
Благодаря постоянному развитию в MyDB Сервер для MySQL вошли ряд улучшений, связанные с репликацией и обработкой бинарных журналов. Это привело к особенностям репликации, отличающим ее от MySQL.
Безопасность операторов с указанием LIMIT
¶
Краткое описание исправления¶
MySQL рассматривает все команды UPDATE/DELETE/INSERT ... SELECT
с указанием LIMIT
как небезопасные, независимо от того, действительно ли они производят недетерминированный результат, и переключает режим бинарного журнала с режима statement-based
на row-based
. MyDB Сервер для MySQL более точен, он рассматривает такие команды как безопасные, если они содержат ORDER BY PK
или условие WHERE
. Это исправление было перенесено из отчета об ошибке MySQL #42415 (#44).
Улучшение производительности при обновлении положения журнала ретрансляции¶
Исправление положения журнала ретрансляции¶
MySQL всегда обновляет позицию журнала ретрансляции в настройках репликации с несколькими источниками независимо от того, была ли уже выполнены зафиксированная транзакция или нет. MyDB Сервер пропускает обновления положения журнала ретрансляции для уже зарегистрированных GTID.
Детали положения журнала ретрансляции¶
В частности, такие безусловные обновления положения журнала ретрансляции вызывали дополнительные операции fsync в случае relay-log-info-repository=TABLE
и с большим количеством каналов, передающих такие дублирующие (уже выполненные) транзакции, ситуация становилась хуже пропорционально. Исправлена ошибка #1786 (MySQL #85141).
Улучшение производительности при обновлении источника и статуса соединения¶
Исправление обновления источника и статуса соединения.¶
Реплики, настроенные для обновления состояния источника и информации о соединении только при ротации файла журнала, не наблюдали ожидаемого снижения нагрузки. MySQL дополнительно обновлял эту информацию в случае наличия нескольких источников репликация, когда реплике приходилось пропустить уже выполненное событие GTID.
Подробности об источнике и состоянии соединения¶
Конфигурация с master_info_repository=TABLE
и sync_master_info=0
заставляет реплику обновлять информацию о состоянии источника и соединения в специальной таблице только при ротации файлов журнала, а не после каждых sync_master_info
событий. Но эта функциональность не работала в конфигурациях репликации с несколькими источниками. Сигналы Heartbeat, отправляемые на реплику, чтобы пропустить события GTID, которые она уже выполнила, ранее оценивались как события ротации журнала ретрансляции и приводили к синхронизации таблицы mysql.slave_master_info
. Эта неточность могла привести к огромному (вплоть до 5 раз при некоторых настройках) увеличению нагрузки на запись на реплике до того, как проблема была исправлена в Percona Server for MySQL. Исправлена ошибка #1812 (MySQL #85158).
Запись команд FLUSH
в бинарный журнал¶
Команды FLUSH
, такие как FLUSH SLOW LOGS
, не записываются в бинарный журнал, если системная переменная binlog_skip_flush_commands
установлена в ON.
Кроме того, были реализованы следующие изменения в поведении режимов read_only
и super_read_only
:
-
Когда для
read_only
установлено значение ON, любая командаFLUSH ...
, выполняемая обычным пользователем (без привилегииSUPER
), не записывается в бинарный журнал независимо от значения переменнойbinlog_skip_flush_commands
. -
Когда для параметра
super_read_only
установлено значение ON, любая командаFLUSH ...
, выполняемая любым пользователем (даже обладающим привилегиейSUPER
), не записывается в бинарный журнал независимо от значения переменнойbinlog_skip_flush_commands
.
Попытка запустить команду FLUSH
без привилегий SUPER
или RELOAD
приводит к ошибке ER_SPECIFIC_ACCESS_DENIED_ERROR
независимо от значения переменной binlog_skip_flush_commands
.
binlog_skip_flush_commands
¶
Свойство | Значение |
---|---|
Командная строка | Да |
Конфигурационный файл | Да |
Область видимости | Глобальная |
Динамическая | Да |
По умолчанию | OFF |
Когда для binlog_skip_flush_commands
установлено значение ON, команды FLUSH ...
не записываются в бинарный журнал. Дополнительную информацию о том, что ещё влияет на запись команд FLUSH
в бинарный журнал, см. в разделе «Запись команд FLUSH в бинарный журнал».
Примечание
FLUSH LOGS
, FLUSH BINARY LOGS
, FLUSH TABLES WITH READ LOCK
и FLUSH TABLES ... FOR EXPORT
не записываются в бинарный журнал независимо от того, какое значение содержит переменная binlog_skip_flush_commands
. Команда FLUSH не записывается в бинарный журнал, а значение binlog_skip_flush_commands
игнорируется, если команда FLUSH
запускается с ключевым словом NO_WRITE_TO_BINLOG
(или его псевдонимом LOCAL
).
Сохранение комментариев в DROP TABLE
¶
Когда вы выполняете команду DROP TABLE
, бинарный журнал сохраняет команду, но удаляет комментарии и заключает имя таблицы в кавычки. Если вам требуется, чтобы бинарный журнал сохранял комментарии и не добавлял кавычки, включите опцию binlog_ddl_skip_rewrite
.
binlog_ddl_skip_rewrite¶
Свойство | Значение |
---|---|
Командная строка | Да |
Конфигурационный файл | Да |
Область видимости | Глобальная |
Динамическая | Да |
По умолчанию | OFF |
Если переменная включена, DDL-команды DROP TABLE
для одной таблицы регистрируются в бинарном журнале с комментариями. DDL-команды DROP TABLE
для нескольких таблиц не поддерживаются и возвращают ошибку.
SET binlog_ddl_skip_rewrite = ON;
/*comment at start*/DROP TABLE t /*comment at end*/;
Пользовательские функции бинарного журнала¶
Чтобы реализовать восстановление на определенный момент времени (point in time recovery), мы добавили binlog_utils_udf
. Включены следующие определяемые пользователем функции:
Имя | Возвращает | Описание |
---|---|---|
get_binlog_by_gtid() | Имя файла бинлога в виде строки | Возвращает имя файла бинлога, содержащего указанный GTID |
get_last_gtid_from_binlog() | GTID в виде строки | Возвращает последний GTID в указанном бинлоге |
get_gtid_set_by_binlog() | Набор GTID в виде строки | Возвращает все GTID в указанном бинлоге |
get_binlog_by_gtid_set() | Имя файла бинлога в виде строки | Возвращает имя файла бинлога, который содержит хотя бы один GTID из указанного набора |
get_first_record_timestamp_by_binlog() | Временную метку в виде целого числа | Возвращает временную метку первого события в указанном бинлоге |
get_last_record_timestamp_by_binlog() | Временную метку в виде целого числа | Возвращает временную метку последнего события в указанном бинлоге |
Примечание
Все функции, возвращающие временные метки, возвращают свои значения в формате UNIX-времени с точностью до микросекунды. Другими словами, они представляют собой количество микросекунд, прошедших с 1 января 1970 года.
Все функции, принимающие имя бинарного журнала в качестве параметра, принимают только короткие имена без компонента пути. Если во входных данных обнаружен разделитель пути (/
), возвращается ошибка. Это требуется для ограничения путей, из которых можно читать бинарные журналы. Они всегда считываются из текущего каталога для бинарных журналов (системная переменная @@log_bin_basename).
Все функции, возвращающие имена файлов бинарного журнала, возвращают имя в краткой форме, без компонента пути.
Основной синтаксис get_binlog_by_gtid()
следующий:
* get_binlog_by_gtid(string) [AS] alias
Использование: SELECT get_binlog_by_gtid(string) [AS] alias
Пример:
CREATE FUNCTION get_binlog_by_gtid RETURNS STRING SONAME 'binlog_utils_udf.so';
SELECT get_binlog_by_gtid("F6F54186-8495-47B3-8D9F-011DDB1B65B3:1") AS result;
Ожидаемый результат
+--------------+
| result |
+==============+
| binlog.00001 |
+--------------+
DROP FUNCTION get_binlog_by_gtid;
Основной синтаксис get_last_gtid_from_binlog()
следующий:
* get_last_gtid_from_binlog(string) [AS] alias
Использование: SELECT get_last_gtid_from_binlog(string) [AS] alias
Например:
CREATE FUNCTION get_last_gtid_from_binlog RETURNS STRING SONAME 'binlog_utils_udf.so';
SELECT get_last_gtid_from_binlog("binlog.00001") AS result;
Ожидаемый результат
+-----------------------------------------+
| result |
+=========================================+
| F6F54186-8495-47B3-8D9F-011DDB1B65B3:10 |
+-----------------------------------------+
DROP FUNCTION get_last_gtid_from_binlog;
Основной синтаксис get_gtid_set_by_binlog()
следующий:
* get_gtid_set_by_binlog(string) [AS] alias
Использование: SELECT get_gtid_set_by_binlog(string) [AS] alias
Например:
CREATE FUNCTION get_gtid_set_by_binlog RETURNS STRING SONAME 'binlog_utils_udf.so';
SELECT get_gtid_set_by_binlog("binlog.00001") AS result;
Ожидаемый результат
+-------------------------+
| result |
+=========================+
| 11ea-b9a7:7,11ea-b9a7:8 |
+-------------------------+
DROP FUNCTION get_gtid_set_by_binlog;
Основной синтаксис get_binlog_by_gtid_set()
следующий:
* get_binlog_by_gtid_set(string) [AS] alias
Использование: SELECT get_binlog_by_gtid_set(string) [AS] alias
Пример:
CREATE FUNCTION get_binlog_by_gtid_set RETURNS STRING SONAME 'binlog_utils_udf.so';
SELECT get_binlog_by_gtid_set("11ea-b9a7:7,11ea-b9a7:8") AS result;
Ожидаемый результат
+---------------------------------------------------------------+
| result |
+===============================================================+
| bin.000003 |
+---------------------------------------------------------------+
DROP FUNCTION get_binlog_by_gtid_set;
Основной синтаксис get_first_record_timestamp_by_binlog()
следующий:
* get_first_record_timestamp_by_binlog(TIMESTAMP) [AS] alias
Использование: SELECT get_first_record_timestamp_by_binlog(TIMESTAMP) [AS] alias
Например:
CREATE FUNCTION get_first_record_timestamp_by_binlog RETURNS INTEGER SONAME 'binlog_utils_udf.so';
SELECT FROM_UNIXTIME(get_first_record_timestamp_by_binlog("bin.00003") DIV 1000000) AS result;
Ожидаемый результат
+---------------------+
| result |
+=====================+
| 2020-12-03 09:10:40 |
+---------------------+
DROP FUNCTION get_first_record_timestamp_by_binlog;
Основной синтаксис get_last_record_timestamp_by_binlog()
следующий:
* get_last_record_timestamp_by_binlog(TIMESTAMP) [AS] alias
Использование: SELECT get_last_record_timestamp_by_binlog(TIMESTAMP) [AS] alias
Например:
CREATE FUNCTION get_last_record_timestamp_by_binlog RETURNS INTEGER SONAME 'binlog_utils_udf.so';
SELECT FROM_UNIXTIME(get_last_record_timestamp_by_binlog("bin.00003") DIV 1000000) AS result;
Ожидаемый результат
+---------------------+
| result |
+=====================+
| 2020-12-04 04:18:56 |
+---------------------+
DROP FUNCTION get_last_record_timestamp_by_binlog;
Ограничения¶
Для следующих переменных не присваивайте значения с одним или несколькими символами точки (.
):
Значение, определенное с помощью этих символов, обрабатывается по-разному в MySQL и Percona XtraBackup и может привести к непредсказуемому поведению.