Spec-Zone.ru › MySQL 9.2

25.7.11 Репликация NDB Cluster с помощью многопоточного приложения

  • Требования

  • Настройка MTA: Источник

  • Настройка MTA: Реплика

  • Зависимость транзакций и обработка наборов изменений

  • Использование памяти для отслеживания наборов изменений

  • Известные ограничения

Репликация NDB в NDB 9.2 поддерживает использование механизма многопоточного приложения (MTA) MySQL Server, что позволяет параллельно применять независимые двоичные протокольные транзакции на реплике, увеличивая пиковую пропускную способность репликации.

Требования

Реализация MTA MySQL Server делегирует обработку отдельных двоичных протокольных транзакций пулу потоков-работников (размер которого настраивается), и координирует потоки-работники для обеспечения соблюдения зависимостей транзакций, закодированных в двоичном протоколе, и поддержания порядка подтверждения, если это требуется (см. Раздел 19.2.3, “Потоки репликации”). Для использования этой функциональности с NDB Cluster необходимо, чтобы реплика была настроена на использование нескольких потоков-работников. Для этого необходимо установить replica_parallel_workers для управления количеством потоков-работников на реплике. Значение по умолчанию равно 4.

Настройка MTA: Источник

Если установлено на источнике mysqld, replica_parallel_type должно быть LOGICAL_CLOCK (значение по умолчанию).

Примечание

NDB не поддерживает replica_parallel_type=DATABASE.

Кроме того, рекомендуется установить объем памяти, используемый для отслеживания наборов изменений двоичного протокола транзакций на источнике (binlog_transaction_dependency_history_size) до E * P, где E — средний размер эпохи (как количество операций на эпоху), а P — максимальная ожидаемая параллельность. Подробнее см. Использование памяти для отслеживания наборов изменений.

Настройка MTA: Реплика

Настройка реплики mysqld для MTA требует, чтобы replica_parallel_workers было больше 1. Рекомендуемое начальное значение при первом включении MTA — 4, что является значением по умолчанию.

Кроме того, replica_preserve_commit_order должно быть ON. Это также значение по умолчанию.

Зависимость транзакций и обработка наборов изменений

Зависимости транзакций обнаруживаются с помощью анализа набора изменений каждой транзакции, то есть набора строк (таблица, значения ключей), записанных транзакцией. Если две транзакции изменяют одну и ту же строку, они считаются зависимыми и должны применяться в определенном порядке (другими словами, последовательно), чтобы избежать тупиков или некорректных результатов. Если в таблице есть вторичные уникальные ключи, эти значения также добавляются в набор изменений транзакции, чтобы обнаружить случай, когда существуют зависимости транзакций, подразумеваемые разными транзакциями, затрагивающими одно и то же уникальное значение ключа, и поэтому требующие упорядочивания. Если зависимости не могут быть эффективно определены, mysqld переходит к рассмотрению транзакций как зависимых по соображениям безопасности.

Зависимости транзакций кодируются в двоичном протоколе источником mysqld. Зависимости закодированы в событии ANONYMOUS_GTID с использованием схемы «Логические часы». (См. Раздел 19.1.4.1, “Понятия репликации”.)

Реализация наборов изменений, используемая MySQL (и NDB Cluster), использует обнаружение конфликтов на основе хешей, основанных на хешировании 64-битных строк строк релевантных таблиц и индексов. Это надежно обнаруживает, когда один и тот же ключ встречается дважды, но также может давать ложные срабатывания, если разные значения таблиц и индексов хешируются в одно и то же 64-битное значение; это может привести к искусственным зависимостям, которые могут уменьшить доступную параллельность.

Зависимости транзакций принудительно накладываются в следующих случаях:

  • DDL-операции

  • Поворот двоичного протокола или столкновение с границами файлов двоичного протокола

  • Ограничения размера истории наборов изменений

  • Изменения, которые ссылаются на родительские внешние ключи в целевой таблице

    Более конкретно, транзакции, выполняющие вставки, обновления и удаления в таблицах родительских внешних ключей, сериализуются относительно всех предыдущих и последующих транзакций, а не только тех транзакций, которые затрагивают таблицы, участвующие в отношении ограничений. И наоборот, транзакции, выполняющие вставки, обновления и удаления в таблицах дочерних внешних ключей (ссылок), не особенно сериализуются друг с другом.

Реализация MTA MySQL пытается параллельно применять независимые двоичные протокольные транзакции. NDB записывает все изменения, происходящие во всех пользовательских транзакциях, подтверждаемых в эпоху (TimeBetweenEpochs, по умолчанию 100 миллисекунд), в одной двоичной протокольной транзакции, называемой транзакцией эпохи. Поэтому, чтобы две последовательные транзакции эпохи были независимыми и могли быть применены параллельно, необходимо, чтобы ни одна строка не была изменена в обеих эпохах. Если какая-либо строка изменяется в обеих эпохах, то они зависимы и применяются последовательно, что может ограничить доступную параллельность.

Транзакции эпохи считаются независимыми на основе набора строк, измененных на кластере источника в эпоху, но без учета сгенерированных mysql.ndb_apply_status WRITE_ROW событий, которые передают метаданные эпохи. Это предотвращает то, чтобы каждая транзакция эпохи была тривиально зависима от предыдущей эпохи, но требует, чтобы двоичный протокол применялся на реплике с сохранением порядка подтверждения. Это также подразумевает, что двоичный протокол NDB с зависимостями наборов изменений не подходит для использования репликой базы данных, использующей другой движок хранения MySQL.

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

Использование памяти для отслеживания наборов изменений

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

Если средняя двоичная протокольная транзакция изменяет N строк, то для возможности определения независимых (параллелизуемых) транзакций до уровня параллельности P, значение binlog_transaction_dependency_history_size должно быть по крайней мере N * P. (Максимальное значение — 1000000.)

Конечный размер истории приводит к конечному максимальному значению длины зависимости, которое можно надежно определить, что задает конечную параллельность, которая может быть выражена. Любая строка, не найденная в истории, может зависеть от последней транзакции, удаленной из истории.

История наборов изменений не работает как скользящее окно над последними N транзакциями; скорее, это конечный буфер, который разрешается заполнить полностью, а затем все его содержимое полностью удаляется, когда он становится полным. Это означает, что размер истории со временем имеет пилообразный характер, а значит, максимальная обнаруживаемая длина зависимости также имеет пилообразный характер, в результате чего независимые транзакции все еще могут быть помечены как зависимые, если буфер истории набора изменений был сброшен между их обработкой.

В этой схеме каждая транзакция в файле двоичного протокола аннотируется с sequence_number (1, 2, 3, ...) и порядковым номером последней двоичной протокольной транзакции, от которой она зависит, которую мы называем last_committed.

В данном файле двоичного протокола первая транзакция имеет sequence_number 1 и last_committed 0.

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

Содержимое событий ANONYMOUS_GTID, включая sequence_number и last_committed (а значит, и зависимости транзакций), можно увидеть с помощью mysqlbinlog.

END_OF_DOCUMENT_MARKER

События ANONYMOUS_GTID, генерируемые на источнике, обрабатываются отдельно от сжатой транзакционной полезной нагрузки с объёмными событиями BEGIN, TABLE_MAP*, WRITE_ROW*, UPDATE_ROW*, DELETE_ROW* и COMMIT, что позволяет определить зависимости до разархивирования. Это означает, что поток координатора реплики может делегировать разархивирование полезной нагрузки транзакции потоку-рабочему, обеспечивая автоматическое параллельное разархивирование независимых транзакций на реплике.

Известные ограничения

Вторичные уникальные столбцы. Таблицы со вторичными уникальными столбцами (то есть уникальными ключами, отличными от первичного ключа) отправляют все столбцы на источник, чтобы можно было обнаружить конфликты, связанные с уникальными ключами.

В случае, когда текущий режим двоичного протоколирования не включает все столбцы, а только изменённые столбцы (--ndb-log-updated-only=OFF, --ndb-log-update-minimal=ON, --ndb-log-update-as-write=OFF), это может увеличить объём данных, отправляемых от узлов данных к узлам SQL.

Влияние зависит как от скорости изменения (обновления или удаления) строк в таких таблицах, так и от объёма данных в столбцах, которые фактически не изменяются.

Репликация NDB в InnoDB. Модуль отслеживания зависимостей транзакций NDB двоичного журнализатора намеренно игнорирует межтранзакционные зависимости, созданные событиями метаданных mysql.ndb_apply_status, которые обрабатываются отдельно в рамках завершения транзакции эпохи на прикладном уровне репликации. Для репликации в InnoDB специальной обработки нет; это может привести к снижению производительности или другим проблемам при использовании многопоточного приложения InnoDB для обработки двоичного журнала NDB MTA.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/mysql-cluster-replication-mta.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API