25.7.4 Схема репликации NDB Cluster и таблицы
Репликация в NDB Cluster использует ряд специальных таблиц в базе данных mysql на каждом экземпляре MySQL Server, действующем как узел SQL как в реплицируемом кластере, так и в реплике. Это справедливо независимо от того, является ли реплика одним сервером или кластером.
Таблицы ndb_binlog_index и ndb_apply_status создаются в базе данных mysql. Их не следует явно реплицировать пользователем. Вмешательство пользователя обычно не требуется для создания или обслуживания этих таблиц, поскольку обе таблицы поддерживаются потоком инжектора двоичного журнала (NDB) . Это позволяет процессу mysqld оставаться обновленным в изменениях, производимых хранилищем NDB. Поток инжектора двоичного журнала (NDB поток инжектора двоичного журнала) получает события непосредственно от хранилища NDB. Поток инжектора NDB отвечает за захват всех событий данных в кластере и гарантирует, что все события, изменяющие, вставляющие или удаляющие данные, записываются в таблицу ndb_binlog_index. Поток ввода-вывода (приёмник) реплики передает события из двоичного журнала источника в репликационный журнал реплики.
Таблица ndb_replication должна быть создана вручную. Пользователь может обновить эту таблицу для выполнения фильтрации по базе данных или таблице. Дополнительную информацию см. в таблице ndb_replication. ndb_replication также используется в NDB Replication для обнаружения и разрешения конфликтов при управлении разрешением конфликтов; см. Управление разрешением конфликтов.
Хотя ndb_binlog_index и ndb_apply_status создаются и обслуживаются автоматически, рекомендуется проверить существование и целостность этих таблиц как начальный этап подготовки NDB Cluster к репликации. Возможно просмотреть данные событий, записанные в двоичный журнал, запросив таблицу mysql.ndb_binlog_index напрямую на источнике. Это также можно сделать с помощью инструкции SHOW BINLOG EVENTS на узле SQL источника или реплики. (См. Раздел 15.7.7.3, «Запрос SHOW BINLOG EVENTS».)
Также можно получить полезную информацию из вывода SHOW ENGINE NDB
STATUS.
При выполнении изменений схемы в таблицах NDB приложениям следует подождать, пока инструкция ALTER TABLE не вернётся в подключение MySQL-клиента, который выдал инструкцию, прежде чем пытаться использовать обновлённое определение таблицы.
Таблица ndb_apply_status
ndb_apply_status используется для записи операций, которые были реплицированы от источника к реплике. Если таблица ndb_apply_status не существует на реплике, ndb_restore пересоздает её.
В отличие от ndb_binlog_index, данные в этой таблице не специфичны для какого-либо одного узла SQL в (репликационном) кластере, поэтому ndb_apply_status может использовать хранилище NDBCLUSTER, как показано здесь:
CREATE TABLE `ndb_apply_status` (
`server_id` INT(10) UNSIGNED NOT NULL,
`epoch` BIGINT(20) UNSIGNED NOT NULL,
`log_name` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`start_pos` BIGINT(20) UNSIGNED NOT NULL,
`end_pos` BIGINT(20) UNSIGNED NOT NULL,
PRIMARY KEY (`server_id`) USING HASH
) ENGINE=NDBCLUSTER DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Таблица ndb_apply_status заполняется только на репликах, что означает, что на источнике эта таблица никогда не содержит строк; поэтому нет необходимости выделять какой-либо DataMemory для ndb_apply_status там.
Поскольку эта таблица заполняется данными, происходящими на источнике, её следует разрешить для репликации; любые правила фильтрации репликации или двоичного журнала, которые непреднамеренно препятствуют обновлению репликой ndb_apply_status или записи в двоичный журнал источником, могут помешать корректной работе репликации между кластерами. Дополнительную информацию о потенциальных проблемах, возникающих из-за таких правил фильтрации, см. в Правилах фильтрации репликации и двоичного журнала при репликации между кластерами NDB.
Возможна удаление этой таблицы, но это не рекомендуется. Удаление её переводит все узлы SQL в режим только для чтения; NDB обнаруживает, что эта таблица была удалена, и пересоздаёт её, после чего снова возможны обновления. Удаление и пересоздание ndb_apply_status создаёт пробел в двоичном журнале; это событие приводит к остановке узлов SQL реплики от применения изменений с источника до перезапуска канала репликации.
0 в столбце epoch этой таблицы указывает транзакцию, исходящую от хранилища, отличного от NDB.
ndb_apply_status используется для записи того, какие эпохальные транзакции были реплицированы и применены к кластеру реплики от источника выше по иерархии. Эта информация захватывается в резервной копии NDB в режиме онлайн, но (по дизайну) не восстанавливается с помощью ndb_restore. В некоторых случаях может быть полезно восстановить эту информацию для использования в новых установках; это можно сделать, вызвав ndb_restore с опцией --with-apply-status. Дополнительную информацию см. в описании опции.
Таблица ndb_binlog_index
Репликация кластера NDB использует таблицу ndb_binlog_index для хранения данных индексации двоичного журнала. Поскольку эта таблица локальна для каждого сервера MySQL и не участвует в кластеризации, она использует движок хранения InnoDB. Это означает, что она должна быть создана отдельно на каждом mysqld, участвующем в исходном кластере. (Сам двоичный журнал содержит обновления со всех серверов MySQL в кластере.) Эта таблица определяется следующим образом:
CREATE TABLE `ndb_binlog_index` (
`Position` BIGINT(20) UNSIGNED NOT NULL,
`File` VARCHAR(255) NOT NULL,
`epoch` BIGINT(20) UNSIGNED NOT NULL,
`inserts` INT(10) UNSIGNED NOT NULL,
`updates` INT(10) UNSIGNED NOT NULL,
`deletes` INT(10) UNSIGNED NOT NULL,
`schemaops` INT(10) UNSIGNED NOT NULL,
`orig_server_id` INT(10) UNSIGNED NOT NULL,
`orig_epoch` BIGINT(20) UNSIGNED NOT NULL,
`gci` INT(10) UNSIGNED NOT NULL,
`next_position` bigint(20) unsigned NOT NULL,
`next_file` varchar(255) NOT NULL,
PRIMARY KEY (`epoch`,`orig_server_id`,`orig_epoch`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Если вы обновляетесь с более старой версии, выполните процедуру обновления MySQL и убедитесь, что системные таблицы обновлены, запустив сервер MySQL с опцией --upgrade=FORCE. Обновление системной таблицы приводит к выполнению оператора ALTER TABLE ...
ENGINE=INNODB для этой таблицы. Использование движка хранения MyISAM для этой таблицы по-прежнему поддерживается для обратной совместимости.
ndb_binlog_index может потребовать дополнительного дискового пространства после преобразования в InnoDB. Если это станет проблемой, вы сможете сэкономить место, используя табличное пространство InnoDB для этой таблицы, изменив её ROW_FORMAT на COMPRESSED или оба варианта. Более подробную информацию см. в Разделе 15.1.22, «Оператор CREATE TABLESPACE», и Разделе 15.1.21, «Оператор CREATE TABLE», а также в Разделе 17.6.3, «Табличные пространства».
Размер таблицы ndb_binlog_index зависит от количества эпох на файл двоичного журнала и от количества файлов двоичного журнала. Количество эпох на файл двоичного журнала обычно зависит от объема двоичного журнала, генерируемого за эпоху, и от размера файла двоичного журнала, при этом меньшие эпохи приводят к большему количеству эпох на файл. Следует знать, что пустые эпохи создают записи в таблице ndb_binlog_index даже при использовании опции --ndb-log-empty-epochs, которая находится в состоянии OFF, что означает, что количество записей на файл зависит от продолжительности использования файла; эту зависимость можно представить в виде показанной здесь формулы:
[number of epochs per file] = [time spent per file] / TimeBetweenEpochs
Занятый кластер NDB регулярно записывает в двоичный журнал и, предположительно, быстрее сменяет файлы двоичного журнала, чем спокойный. Это означает, что у «спокойного» кластера NDB с опцией --ndb-log-empty-epochs=ON может быть фактически намного больше строк ndb_binlog_index в файле, чем у кластера с высокой активностью.
При запуске mysqld с опцией --ndb-log-orig, столбцы orig_server_id и orig_epoch хранят соответственно идентификатор сервера, на котором произошло событие, и эпоху, в которой событие произошло на исходном сервере, что полезно в схемах репликации кластера NDB с несколькими источниками. Оператор SELECT, используемый для поиска ближайшей позиции двоичного журнала к самой высокой применённой эпохе на реплике в схеме с несколькими источниками (см. Раздел 25.7.10, «Репликация кластера NDB: двунаправленная и циклическая репликация»), использует эти два столбца, которые не индексируются. Это может привести к проблемам производительности при попытке выполнить отказ от действия, так как запрос должен выполнить сканирование таблицы, особенно если источник работал с опцией --ndb-log-empty-epochs=ON. Вы можете улучшить время отказа от действия при работе с несколькими источниками, добавив индекс к этим столбцам, как показано здесь:
ALTER TABLE mysql.ndb_binlog_index
ADD INDEX orig_lookup USING BTREE (orig_server_id, orig_epoch);
Добавление этого индекса не приносит никакой пользы при репликации из одного источника на одну реплику, так как запрос, используемый для получения позиции двоичного журнала в таких случаях, не использует столбцы orig_server_id или orig_epoch.
Дополнительную информацию об использовании столбцов next_position и next_file см. в Разделе 25.7.8, «Реализация отказа от действия с помощью репликации кластера NDB».
На следующем рисунке показаны отношения между источником репликации кластера NDB, потоком инжектора двоичного журнала и таблицей mysql.ndb_binlog_index.
Рисунок 25.13 Источник кластера репликации NDB
Таблица ndb_replication
Таблица ndb_replication используется для управления двоичным протоколированием и разрешения конфликтов, и действует на основе каждой отдельной таблицы. Каждая строка в этой таблице соответствует таблице, которая реплицируется, определяет, как регистрировать изменения в таблице, и, если задана функция разрешения конфликтов, определяет, как разрешать конфликты для этой таблицы.
В отличие от таблиц ndb_apply_status и ndb_replication, таблицу ndb_replication необходимо создавать вручную, используя приведенное здесь SQL-предложение:
CREATE TABLE mysql.ndb_replication (
db VARBINARY(63),
table_name VARBINARY(63),
server_id INT UNSIGNED,
binlog_type INT UNSIGNED,
conflict_fn VARBINARY(128),
PRIMARY KEY USING HASH (db, table_name, server_id)
) ENGINE=NDB
PARTITION BY KEY(db,table_name);
Столбцы этой таблицы перечислены здесь с описаниями:
-
Столбец
dbИмя базы данных, содержащей таблицу, подлежащую репликации.
Вы можете использовать один или оба подстановочных знака
_и%в качестве части имени базы данных. (См. Сопоставление с подстановочными знаками, далее в этом разделе.) -
Столбец
table_nameИмя таблицы, подлежащей репликации.
Имя таблицы может включать один или оба подстановочных знака
_и%. См. Сопоставление с подстановочными знаками в данном разделе. -
Столбец
server_idУникальный идентификатор сервера экземпляра MySQL (узла SQL), где находится таблица.
0в этом столбце действует как подстановочный знак, эквивалентный%, и соответствует любому идентификатору сервера. (См. Сопоставление с подстановочными знаками, далее в этом разделе.) -
Столбец
binlog_typeТип двоичного протоколирования, который необходимо использовать. См. текст для значений и описаний.
-
Столбец
conflict_fnФункция разрешения конфликтов, которая должна применяться; одна из NDB$OLD(), NDB$MAX(), NDB$MAX_DELETE_WIN(), NDB$EPOCH(), NDB$EPOCH_TRANS(), NDB$EPOCH2(), NDB$EPOCH2_TRANS(), NDB$MAX_INS() или NDB$MAX_DEL_WIN_INS();
NULLуказывает, что разрешение конфликтов для этой таблицы не используется.См. Функции разрешения конфликтов для получения дополнительной информации об этих функциях и их использовании при разрешении конфликтов в NDB Replication.
Некоторые функции разрешения конфликтов (
NDB$OLD(),NDB$EPOCH(),NDB$EPOCH_TRANS()) требуют использования одной или нескольких созданных пользователем таблиц исключений. См. Таблицу исключений разрешения конфликтов.
Для включения разрешения конфликтов с NDB Replication необходимо создать и заполнить эту таблицу информацией об управлении на узле(ах) SQL, на котором(ых) должен быть решён конфликт. В зависимости от типа разрешения конфликтов и используемого метода это может быть источник, реплика или оба сервера. В простой схеме источник-реплика, где данные также могут быть изменены локально на реплике, это обычно реплика. В более сложной схеме репликации, такой как двусторонняя репликация, это, как правило, все участвующие источники. См. Раздел 25.7.12, «Разрешение конфликтов в репликации кластеров NDB» для получения дополнительной информации.
Таблица ndb_replication позволяет контролировать двоичное протоколирование на уровне таблицы вне области разрешения конфликтов, в этом случае conflict_fn задаётся как NULL, а оставшиеся значения столбцов используются для управления двоичным протоколированием для данной таблицы или набора таблиц, соответствующих выражению с подстановочными знаками. Задавая правильное значение для столбца binlog_type, вы можете настроить протоколирование для данной таблицы или таблиц с использованием требуемого формата двоичного протокола или отключить двоичное протоколирование полностью. Возможные значения для этого столбца с значениями и описаниями показаны в следующей таблице:
Таблица 25.42 Значения binlog_type, со значениями и описаниями
| Значение | Описание |
|---|---|
| 0 | Использовать настройки сервера по умолчанию |
| 1 | Не протоколировать эту таблицу в двоичном журнале (аналогично sql_log_bin = 0, но применяется только к одной или нескольким указанным таблицам) |
| 2 | Протоколировать только обновлённые атрибуты; протоколировать их как события WRITE_ROW |
| 3 | Протоколировать полную строку, даже если она не обновлена (поведение MySQL сервера по умолчанию) |
| 6 | Использовать обновлённые атрибуты, даже если значения не изменены |
| 7 | Протоколировать полную строку, даже если значения не изменены; протоколировать обновления как события UPDATE_ROW |
| 8 | Протоколировать обновление как UPDATE_ROW; протоколировать только столбцы первичного ключа в предыдущем изображении и только обновлённые столбцы в последующем изображении (аналогично --ndb-log-update-minimal, но применяется только к одной или нескольким указанным таблицам) |
| 9 | Протоколировать обновление как UPDATE_ROW; протоколировать только столбцы первичного ключа в предыдущем изображении и все столбцы, кроме столбцов первичного ключа, в последующем изображении |
Значения binlog_type 4 и 5 не используются, поэтому они опущены из показанной таблицы, а также из следующей таблицы.
Несколько значений binlog_type эквивалентны различным комбинациям параметров протоколирования mysqld --ndb-log-updated-only, --ndb-log-update-as-write и --ndb-log-update-minimal, как показано в следующей таблице:
Таблица 25.43 Значения binlog_type с эквивалентными комбинациями параметров протоколирования NDB
| Значение |
--ndb-log-updated-only Значение |
--ndb-log-update-as-write Значение |
--ndb-log-update-minimal Значение |
|---|---|---|---|
| 0 | -- | -- | -- |
| 1 | -- | -- | -- |
| 2 | ВКЛ | ВКЛ | ВЫКЛ |
| 3 | ВЫКЛ | ВКЛ | ВЫКЛ |
| 6 | ВКЛ | ВЫКЛ | ВЫКЛ |
| 7 | ВЫКЛ | ВЫКЛ | ВЫКЛ |
| 8 | ВКЛ | ВЫКЛ | ВКЛ |
| 9 | ВЫКЛ | ВЫКЛ | ВКЛ |
Двоичное протоколирование может быть настроено на различные форматы для разных таблиц путём вставки строк в таблицу ndb_replication с использованием соответствующих значений столбцов db, table_name и binlog_type. Внутреннее целое значение, показанное в предыдущей таблице, должно использоваться при настройке формата двоичного протоколирования. Следующие два предложения задают двоичное протоколирование на полные строки (значение 3) для таблицы test.a и на обновления только (значение 2) для таблицы test.b:
# Table test.a: Log full rows
INSERT INTO mysql.ndb_replication VALUES("test", "a", 0, 3, NULL);
# Table test.b: log updates only
INSERT INTO mysql.ndb_replication VALUES("test", "b", 0, 2, NULL);
Для отключения протоколирования для одной или нескольких таблиц используйте 1 для binlog_type, как показано здесь:
# Disable binary logging for table test.t1
INSERT INTO mysql.ndb_replication VALUES("test", "t1", 0, 1, NULL);
# Disable binary logging for any table in 'test' whose name begins with 't'
INSERT INTO mysql.ndb_replication VALUES("test", "t%", 0, 1, NULL);
Отключение протоколирования для данной таблицы эквивалентно установке sql_log_bin = 0, за исключением того, что это применяется к одной или нескольким таблицам индивидуально. Если узел SQL не выполняет двоичное протоколирование для данной таблицы, он не получает события изменения строки для этих таблиц. Это означает, что он не получает все изменения и отбрасывает некоторые, а скорее не подписывается на эти изменения.
Отключение протоколирования может быть полезно по ряду причин, в том числе перечисленных здесь:
Отправка изменений по сети обычно экономит пропускную способность, буферизацию и ресурсы процессора.
Не регистрировать изменения в таблицах с очень частыми обновлениями, но значение которых не велико, подходит для транзиентных данных (таких как данные сеанса), которые могут быть относительно неважны в случае полного отказа кластера.
Используя переменную сеанса (или
sql_log_bin) и код приложения, также можно регистрировать (или не регистрировать) определенные SQL-запросы или типы SQL-запросов; например, в некоторых случаях может быть желательно не записывать DDL-запросы в одной или нескольких таблицах.Разделение потоков репликации на два (или более) двоичных журнала может быть выполнено по причинам производительности, необходимости репликации разных баз данных в разные места, использования разных типов двоичного логирования для разных баз данных и так далее.
Сопоставление с подстановками. Чтобы не было необходимости вставлять строку в таблицу ndb_replication для каждой комбинации базы данных, таблицы и узла SQL в вашей настройке репликации, NDB поддерживает подстановку символов-заменителей в столбцах этой таблицы: db, table_name и server_id. Имена баз данных и таблиц, используемые соответственно в db и table_name, могут содержать один или оба следующих символа-заменители:
_(символ подчеркивания): соответствует нулю или более символам%(знак процента): соответствует одному символу
(Это те же символы-заменители, что и в операторе MySQL LIKE.)
Столбец server_id поддерживает 0 в качестве символа-заменителя, эквивалентного _ (соответствует чему угодно). Это используется в приведенных ранее примерах.
Определенная строка в таблице ndb_replication может использовать символы-заменители для сопоставления любого из имени базы данных, имени таблицы и идентификатора сервера в любой комбинации. При наличии нескольких потенциальных совпадений в таблице выбирается лучшее совпадение в соответствии с приведенной здесь таблицей, где W представляет совпадение с символом-заменителем, E — точное совпадение, и чем больше значение в столбце Quality, тем лучше совпадение:
Таблица 25.44 Веса различных комбинаций совпадений с символами-заменителями и точных совпадений в столбцах таблицы mysql.ndb_replication
db | table_name | server_id | Качество |
|---|---|---|---|
| W | W | W | 1 |
| W | W | E | 2 |
| W | E | W | 3 |
| W | E | E | 4 |
| E | W | W | 5 |
| E | W | E | 6 |
| E | E | W | 7 |
| E | E | E | 8 |
Таким образом, точное совпадение с именем базы данных, именем таблицы и идентификатором сервера считается лучшим (самым сильным), а самое слабое (худшее) совпадение — это совпадение с символами-заменителями во всех трех столбцах. При выборе правила для применения учитывается только сила совпадения; порядок строк в таблице на это определение не влияет.
Регистрация полных или частичных строк. Существует два основных метода регистрации строк, определяемых настройкой параметра --ndb-log-updated-only для mysqld:
Записывать полные строки (параметр установлен на
ON)Записывать только данные столбцов, которые были обновлены, то есть данные столбцов, значение которых было установлено, независимо от того, было ли это значение фактически изменено. Это поведение по умолчанию (параметр установлен на
OFF).
Обычно достаточно и эффективнее регистрировать только обновленные столбцы; однако, если вам нужно записать полные строки, вы можете сделать это, установив --ndb-log-updated-only на 0 или OFF.
Регистрация измененных данных как обновлений. Настройка параметра --ndb-log-update-as-write сервера MySQL определяет, выполняется ли ведение журнала с изображением “перед” или без него.
Поскольку разрешение конфликтов для обновлений и операций удаления выполняется в обработчике обновлений сервера MySQL, необходимо контролировать ведение журнала, выполняемое источником репликации, таким образом, чтобы обновления были обновлениями, а не записями; другими словами, чтобы обновления обрабатывались как изменения в существующих строках, а не как запись новых строк, даже если они заменяют существующие строки.
Этот параметр включен по умолчанию; другими словами, обновления обрабатываются как записи. То есть обновления по умолчанию записываются как события write_row в двоичном журнале, а не как события update_row.
Чтобы отключить параметр, запустите исходный mysqld с --ndb-log-update-as-write=0 или --ndb-log-update-as-write=OFF. Это необходимо при репликации из таблиц NDB в таблицы, использующие другой движок хранения; см. Репликация из NDB в другие движки хранения и Репликация из NDB в не транзакционный движок хранения для получения дополнительной информации.
При разрешении конфликтов при вставках с помощью NDB$MAX_INS() или NDB$MAX_DEL_WIN_INS() узел SQL (то есть процесс mysqld) может записывать обновления строк в исходном кластере как события WRITE_ROW при включенном параметре --ndb-log-update-as-write для идемпотентности и оптимального размера. Это работает для этих алгоритмов, поскольку они оба отображают событие WRITE_ROW на вставку или обновление в зависимости от того, существует ли строка, и требуемая метаданные (изображение “после” для столбца времени) присутствуют в событии “WRITE_ROW”.
© 2025 Oracle
Licensed under the GPLv2 License.