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 Cluster Replication использует таблицу 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.21, «Оператор CREATE TABLESPACE» и Раздел 15.1.20, «Оператор 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 Cluster регулярно записывает в двоичный журнал и, предположительно, чаще вращает файлы двоичного журнала, чем пассивный. Это означает, что у «пассивного» NDB Cluster с опцией --ndb-log-empty-epochs=ON фактически может быть гораздо большее количество строк ndb_binlog_index в файле, чем у активного.
Когда mysqld запускается с опцией --ndb-log-orig, столбцы orig_server_id и orig_epoch хранят соответственно идентификатор сервера, на котором произошло событие, и эпоху, в которой событие произошло на исходном сервере, что полезно в установках репликации NDB Cluster с несколькими источниками. Оператор SELECT, используемый для поиска ближайшей позиции в двоичном журнале к самой высокой применённой эпохе на реплике в конфигурации с несколькими источниками (см. Раздел 25.7.10, «NDB Cluster Replication: Двунаправленная и циклическая репликация»), использует эти два столбца, которые не индексируются. Это может привести к проблемам производительности при попытке переключения, так как запросу необходимо выполнить сканирование таблицы, особенно когда источник работал с --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.
См. Раздел 25.7.8, «Реализация переключения при помощи NDB Cluster Replication» для получения дополнительной информации об использовании столбцов next_position и next_file.
На следующем рисунке показаны отношения между сервером источника репликации NDB Cluster, его потоком вставки двоичного журнала и таблицей mysql.ndb_binlog_index.
Рисунок 25.13 Кластер источника репликации
Таблица 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.