Spec-Zone.ru › MariaDB

Обзор репликации MariaDB для пользователей SQL Server

MariaDB поддерживает следующие типы репликации:

  • Асинхронная репликация.
  • Полусинхронная репликация.
  • Кластер Galera.
MariaDB начиная с 10.5.1

Примечание: в примерах на этой странице несколько SQL-запросов используют ключевое слово SLAVE. Это слово считается неуместным некоторыми людьми или культурами, поэтому с MariaDB 10.5 можно использовать ключевое слово REPLICA, как синоним.

В будущем будут созданы похожие синонимы для переменных состояния и системных переменных. Следите за статусом этих изменений в MDEV-18777.

Асинхронная репликация

Исходная система репликации MariaDB — это асинхронная репликация первичного-реплики.

У первичного сервера должна быть включена бинарная запись журнала. Первичный сервер регистрирует все изменения данных в бинарном журнале. Каждый событие (запись бинарного журнала) отправляется всем репликам.

Для более высокого уровня описания бинарного журнала для пользователей SQL Server, см. Архитектура MariaDB.

События могут быть записаны в двух форматах: как SQL-запрос (репликация на основе запросов, или SBR), или как двоичное представление изменения (репликация на основе строк, или RBR). Первый обычно медленнее, потому что реплики должны повторно выполнить запрос. Он также менее надёжен, потому что некоторые SQL-запросы являются недетерминированными, поэтому они могут давать разные результаты на репликах. С другой стороны, репликация на основе строк может значительно увеличить размер бинарного журнала и потребовать больше сетевого трафика. По этой причине операторы DML всегда регистрируются в формате запросов.

Для более подробной информации о форматах репликации см. форматы бинарного журнала.

У реплик есть поток I/O, который получает события из бинарного журнала и записывает их в журнале реле. Эти события затем считываются потоком SQL. Этот поток может напрямую применять изменения к локальным базам данных, и это было единственным вариантом до MariaDB 10.0.5. Если параллельная репликация включена, поток SQL передает события потоку-рабочему, который применяет их к базам данных. Последний метод рекомендуется по причинам производительности.

Когда реплика не может применить событие к локальным данным, поток SQL останавливается. Это происходит, например, если событие представляет собой удаление строки, но эта строка не существует на реплике. Причин для этого может быть несколько, например, недетерминированные запросы или пользователь удалил строку на реплике. Чтобы снизить риск, рекомендуется установить read_only в 1 на репликах.

SHOW SLAVE STATUS имеет столбцы, названные Slave_SQL_State и Slave_IO_State, которые показывают, соответственно, работают ли поток SQL и поток I/O. Если они не работают, столбец Last_IO_Errno и Last_IO_Error (для потока I/O) или Last_SQL_Errno и Last_SQL_Error (для потока SQL) показывают, в чём проблема.

В цепочке репликации каждый сервер должен иметь уникальный server_id.

Для получения дополнительной информации о репликации см. стандартную репликацию.

Координаты бинарного журнала, координаты журнала реле и GTID

Координаты бинарного журнала позволяют идентифицировать определённое изменение данных, произведённое сервером. Координаты состоят из имени файла и позиции последнего события, выраженного целым числом. Последние координаты события можно увидеть в столбцах SHOW MASTER STATUS File и Position. mariadb-dump включает их в дамп, если используется опция --master-data.

Реплика использует координаты бинарного журнала первичного сервера для определения последнего события, которое она прочитала. Это можно увидеть в столбцах SHOW SLAVE STATUS Master_Log_File и Read_Master_Log_Pos.

Столбцы Relay_Master_Log_File и Exec_Master_Log_Pos определяют событие первичного сервера, соответствующее последнему событию, применённому потоком SQL.

Журнал реле реплики также имеет координаты. Координаты последнего применённого события можно увидеть в столбцах SHOW SLAVE STATUS Relay_Log_File и Relay_Log_Pos.

Чтобы легко определить отставание реплики от первичного сервера, можно посмотреть на Seconds_Behind_Master.

Координаты в таком представлении имеют проблему: они разные на каждом сервере. Каждый сервер может использовать файлы с разными (или одинаковыми) именами, в зависимости от его конфигурации. Файлы могут вращаться в разное время, включая тот случай, когда пользователь запускает FLUSH LOGS. Включив GTID (глобальный идентификатор транзакции), событие будет иметь один и тот же идентификатор на первичном сервере и на всех репликах.

При включении GTID SHOW SLAVE STATUS показывает два GTID: Gtid_IO_Pos — последнее событие, записанное в журнал реле, и Gtid_Slave_Pos — последнее событие, применённое потоком SQL. Нет необходимости в столбце, идентифицирующем то же самое событие на первичном сервере, потому что идентификатор одинаков.

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

В MariaDB нет эквивалента репликации моментального снимка SQL Server.

Для настройки реплики необходимо выполнить её ручную настройку. Реплику можно настроить с первичного сервера следующим образом:

  • Сначала необходимо восстановить резервную копию первичного сервера на новой реплике;
  • Координаты бинарного журнала на момент создания резервной копии должны быть установлены как координаты репликации на реплике, с помощью CHANGE MASTER TO.

Однако, если есть хотя бы одна существующая реплика, лучше использовать её для настройки новой реплики:

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

Для получения дополнительной информации см. Настройка репликации и Настройка реплики с помощью Mariabackup.

Репликация и разрешения

Реплика подключается к первичному серверу, используя свои учетные данные. См. CHANGE MASTER TO.

В первичном сервере должна быть создана соответствующая учетная запись, и она должна иметь разрешение REPLICATION SLAVE.

Для получения дополнительной информации см. Настройка репликации.

Параллельная репликация и групповое подтверждение

MariaDB использует групповое подтверждение, что означает, что группа событий физически записывается в бинарный журнал вместе. Это уменьшает количество IOPS (операций ввода-вывода в секунду). Групповое подтверждение нельзя отключить, но его можно настроить с помощью переменных, таких как binlog_commit_wait_count и binlog_commit_wait_usec.

Реплики могут применять изменения с помощью нескольких потоков. Это известно как параллельная репликация. До MariaDB 10.0.5 использовался только один поток для применения изменений. Поскольку первичный сервер может использовать множество потоков для записи данных, репликация с одним потоком является известной узкой точкой. Параллельная репликация по умолчанию не включена. Для её использования необходимо установить переменную slave_parallel_threads на значение больше 1. Если репликация запущена, необходимо остановить потоки реплики, чтобы изменить это значение:

STOP SLAVE SQL_THREAD;
SET GLOBAL slave_parallel_threads = 4;
START SLAVE SQL_THREAD;

Существуют различные стили параллельной репликации: в порядке и вне порядка. Точный используемый режим определяется системной переменной slave_parallel_mode. При параллельной репликации события не реплицируются в точном порядке, в котором они произошли на первичном сервере. Но в режиме репликации в порядке фаза подтверждения всегда применяется одновременно. Таким образом, данные на реплике всегда отражают данные, как они были на первичном сервере в определённый момент времени. Репликация вне порядка быстрее, потому что меньше очередей, но она не полностью согласована с первичным сервером. Если две транзакции изменили разные наборы строк на первичном сервере, они могут стать видимыми на реплике в разном порядке.

conservative опирается на групповое подтверждение первичного сервера: события в разных группах выполняются параллельно.

optimistic не пытается определить, какие транзакции могут быть выполнены параллельно — за исключением транзакций, которые вступили в конфликт на первичном сервере. Вместо этого, она всегда пытается применить сразу много событий и откатывает транзакции при возникновении конфликта.

aggressive похожа на оптимистическую, но не учитывает, какие транзакции вступили в конфликт на первичном сервере.

minimal применяет подтверждения вместе, но все остальные события применяются в порядке.

Репликацию вне порядка нельзя включить автоматически, изменив переменную на реплике. Вместо этого её необходимо включить приложениями, которые выполняют транзакции на первичном сервере. Они могут сделать это, если включён GTID. Они могут устанавливать разные значения для переменной gtid_domain_id в разных транзакциях. Это сдвигает большую ответственность на уровень приложения; однако, если приложение знает, какие транзакции не будут вступать в конфликт, и эта информация позволяет разумно увеличить параллелизм, использование репликации вне порядка может быть хорошей идеей.

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

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

Различия между первичным сервером и репликациями

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

Для уменьшения возможных причин конфликтов рекомендуется следующая лучшая практика:

  • Пользователи не должны изменять данные в реплике напрямую. Установите read_only в 1. Обратите внимание, что это не предотвратит изменения от пользователя root.
  • Используйте одинаковые определения таблиц на первичном и реплицированном серверах.
  • Используйте формат двоичного журнала ROW на первичном сервере.

Другой причиной несоответствий могут быть ошибки MariaDB и переключение в случае сбоя первичного сервера.

Существует инструмент с открытым исходным кодом стороннего производителя, который проверяет, являются ли первичный сервер и реплика согласованными. Он называется pt-table-checksum. Другой инструмент, pt-table-sync, может быть использован для устранения различий. Оба являются частью Percona Toolkit. Советуем периодически запускать pt-table-checksum, и использовать pt-table-sync, если несоответствия обнаружены.

Если сбой репликации происходит из-за обнаруженного несоответствия, иногда нужно быстро вернуть реплику в рабочее состояние как можно скорее и решить основную проблему позже. Если GTID не используется, один из способов сделать это — запустить SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1, что пропускает проблемное событие репликации.

Если используется GTID, можно использовать переменную gtid_slave_pos вместо этого. См. ссылку для объяснения того, как это работает.

Существуют способы иметь разные данные на репликациях. Например:

  • Возможна репликация из нескольких источников. Таким образом, реплика будет реплицировать данные из нескольких первичных серверов. Эта функция описана ниже.
  • Фильтры репликации поддерживаются. Это позволяет исключить или включить в репликацию определённые таблицы, базы данных или таблицы, имена которых соответствуют определённому шаблону. Это позволяет избежать репликации данных, которые присутствуют на первичном сервере, но всегда могут быть восстановлены.
  • Различия в определениях таблиц также возможны. Например, реплика может иметь больше или меньше столбцов по сравнению с первичным сервером. Таким образом, мы можем избежать репликации столбцов, значения которых можно восстановить. Или мы можем добавить столбцы для аналитических целей, не имея их на первичном сервере. Убедитесь, что вы понимаете ограничения и риски этой техники.

Задержка репликации

MariaDB поддерживает задержку репликации. Это эквивалентно установке pollinginterval в SQL Server.

Чтобы задерживать репликацию в реплике MariaDB, используйте CHANGE MASTER TO для указания задержки в секундах.

Для получения дополнительной информации см. Задержка репликации.

Репликация из нескольких источников

Репликация из нескольких источников эквивалентна репликации «точка-точка», доступной в SQL Server Enterprise Edition.

Реплика MariaDB может реплицировать данные с любого количества первичных серверов. Очень важно, чтобы разные первичные серверы не имели одинаковых таблиц. В противном случае могут возникнуть конфликты между изменениями данных, внесёнными на разных первичных серверах, что приведёт к сбою репликации.

При репликации из нескольких источников существуют отдельные каналы для каждого первичного сервера.

Это изменило работу команд SQL репликации. SHOW PROCESSLIST возвращает разные строки для каждого канала. Несколько команд, таких как CHANGE MASTER TO, START SLAVE или STOP SLAVE. принимают параметр, который указывает, на какой канал репликации они должны повлиять. Например, чтобы остановить канал с именем wp1:

STOP SLAVE "wp1";

Кроме того, переменные, влияющие на параллельную репликацию, могут быть снабжены префиксом имени канала. Это позволяет использовать параллельную репликацию только для определённых каналов или настраивать её по-разному для каждого канала. Например, чтобы включить параллельную репликацию в канале с именем wp1:

SET GLOBAL wp1.slave_parallel_threads = 4;

Два первичных сервера

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

Таким образом, данные теоретически могут быть вставлены в любой из этих серверов, а затем будут реплицированы на другой сервер. Однако в такой конфигурации конфликты очень вероятны. Поэтому использовать эту технику для масштабирования записи непрактично.

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

В этом сценарии следует рассмотреть несколько проблем:

  • Если активный первичный сервер выйдет из строя, очень вероятно, что пассивный первичный сервер ещё не получил все события, так как репликация асинхронна. Если первичные данные потеряны (например, из-за повреждения диска), некоторые данные также теряются.
  • Если данные не потеряны, при повторном включении первичного сервера последние события будут реплицированы другим сервером. Могут возникнуть конфликты, которые нарушат репликацию.
  • Когда активный первичный сервер считается выключенным? Даже если к нему невозможно подключиться, активный первичный сервер может работать и может взаимодействовать с пассивным первичным сервером. Переключение клиентов на пассивный первичный сервер может привести к ненужным проблемам. Хорошей идеей является всегда проверять SHOW SLAVE STATUS , чтобы убедиться, что оба первичных сервера не общаются.
  • Если мы хотим иметь больше реплик, мы должны подключить некоторые из них к активному первичному серверу, а некоторые — к пассивному первичному серверу. Причина в том, что при выходе из строя сервера его реплики перестают получать данные. Переключение всё ещё возможно, но лучше иметь некоторые серверы, которым не потребуется переключение.

Однако безопасная конфигурация с двумя первичными серверами, где оба сервера принимают записи, возможна. Это происходит в том случае, если данные никогда не конфликтуют. Например, два сервера могут принимать записи в разные базы данных. Нам придётся решить, что должно произойти в случае сбоя сервера:

  • Записи могут быть остановлены до тех пор, пока сервер не заработает снова. Чтения могут быть отправлены на другой сервер, но имейте в виду, что самые последние записанные данные могут отсутствовать.
  • Как записи, так и чтения могут переключиться на другой сервер. Все упомянутые выше проблемы могут применяться к этой ситуации.

См. слайды Светланы Смирновой на MariaDB Day 2020: "Насколько безопасна асинхронная конфигурация мастер-мастер?".

Полусинхронная репликация

Полусинхронная репликация была первоначально реализована как плагин в MySQL. Для использования требовалось два разных плагина, один на первичном сервере, а другой на репликах. Начиная с MariaDB 10.3.3 она встроена, что улучшило её производительность.

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

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

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

Включение полусинхронной репликации

Полусинхронную репликацию можно включить во время выполнения на первичном сервере таким образом:

SET GLOBAL rpl_semi_sync_master_enabled = ON;

Полусинхронная репликация не используется до тех пор, пока она не будет включена и на репликах. Если реплики уже реплицируют, нужно остановить и перезапустить поток io_thread. Это можно сделать следующим образом:

SET GLOBAL rpl_semi_sync_slave_enabled = ON;
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

Настройка точки ожидания и таймаута первичного сервера

Наиболее важные аспекты для настройки — это точка ожидания и таймаут первичного сервера.

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

Точка ожидания определяет, в какой момент первичный сервер должен остановиться и дождаться подтверждения от реплики. Это важное решение с точки зрения аварийного восстановления, в случае если первичный сервер выйдет из строя, когда транзакция не полностью подтверждена. Для установки точки ожидания используется rpl_semi_sync_master_wait_point. Разрешенные значения:

  • AFTER_SYNC: После подтверждения транзакции в двоичном журнале, но до подтверждения в движке хранения. После сбоя транзакция может присутствовать в двоичном журнале, даже если она не была подтверждена.
  • AFTER_COMMIT. После подтверждения транзакции как в двоичном журнале, так и в движке хранения. В случае сбоя транзакция, возможно, была подтверждена на первичном сервере, но не реплицирована на серверах-репликах. Это значение по умолчанию.

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

Таймаут устанавливается с помощью переменной rpl_semi_sync_master_timeout.

Кластер Galera

Galera — это технология, которая реализует практически синхронную репликацию primary-primary для кластера серверов MariaDB.

Raft и основной кластер

Узлы кластера взаимодействуют с помощью протокола Raft. В случае разделения кластера или сбоя некоторых узлов, кластер понимает, что он по-прежнему является основным кластером, если он имеет кворум: половину узлов + 1. Только основной кластер принимает чтение и запись.

По этой причине кластер должен состоять из нечётного числа узлов. Представьте, например, что кластер состоит из двух узлов: если один из них выйдет из строя или связь между ними прервётся, не будет основного кластера.

Сертификация транзакций

Транзакция может быть выполнена на любом узле. Узел воспользуется двухфазным подтверждением. После локального выполнения транзакции узел запросит у других узлов её сертификацию. Это означает, что другие узлы получат её, попытаются применить и сообщат об успехе или ошибке. Узел, получивший транзакцию, не будет ждать ответа от всех узлов. Как только она будет успешно выполнена более чем на половине узлов (кворум), узел выполнит окончательное подтверждение, и данные станут видимыми.

Желательно записывать данные только на один узел (если он не выйдет из строя) или записывать разные базы данных на разных узлах. Это минимизирует риск конфликтов.

Кэш Galera и SST

Применённые изменения данных записываются некоторое время в кэш Galera. Это кэш на диске, записанный в циклическом файле.

Размер кэша Galera можно настроить с помощью системной переменной wsrep_provider_options, которая содержит множество флагов. Нам нужно настроить gcache.size. Для настройки добавьте строку, подобную следующей, в конфигурационный файл:

wsrep_provider_options = 'gcache.size=2G';

Если одна транзакция больше, чем половина кэша Galera, она должна быть записана в отдельный файл в качестве страниц по требованию. Страницы по требованию регулярно заменяются. Замена старой страницы новой страницей зависит от другого флага wsrep_provider_options: wsrep_provider_options#gcachekeep_pages_size|gcache.keep_pages_size, который ограничивает общий размер страниц по требованию.

При перезапуске узла (после сбоя или по причинам обслуживания) ему потребуется получить все изменения, которые были внесены другими узлами с момента его недоступности. Поэтому выбирается узел-донор, возможно, используя флаг gcssync_donor wsrep_provider_options.

Если это возможно, донор отправит все последние изменения, прочитав их из кэша Galera и страниц по требованию. Однако иногда кэш Galera недостаточно велик для хранения всех необходимых изменений или страницы по требованию были перезаписаны, потому что gcache.keep_pages_size недостаточно велик. В этих случаях требуется передача моментального снимка состояния (SST). Это означает, что донор отправит весь набор данных на перезапущенный узел. Чаще всего это происходит с помощью метода mariabackup.

Управление потоком

Хотя сертификация транзакций синхронна, сертифицированные транзакции применяются локально асинхронно. Однако узел не должен сильно отставать от других. Чтобы избежать этого, узел может периодически запускать механизм, называемый управлением потоком, чтобы попросить другие узлы приостановить репликацию до тех пор, пока ситуация не улучшится. Несколько флагов wsrep_provider_options влияют на управление потоком.

gcs.fc_master_slave обычно должен быть установлен в 1, если все записи отправляются на один узел.

gcs.fc_limit настраивается автоматически, если gcs.fc_master_slave не установлен в 0. Очередь приема (транзакции, полученные и ещё не применённые) не должна превышать этот предел. Когда это происходит, узел запускает управление потоком, чтобы приостановить репликацию других узлов.

После активации управления потоком gcs.fc_factor определяет, когда оно будет снято. Это число от 0 до 1, и оно представляет собой дробь. Когда очередь приёма находится ниже этой дроби, управление потоком снимается.

Управление потоком и очередь приёма можно и нужно контролировать. Наиболее полезными метриками являются:

  • wsrep_flow_control_paused указывает, сколько раз репликация была приостановлена по запросу других узлов с момента последнего FLUSH STATUS.
  • wsrep_flow_control_sent указывает, сколько раз этот узел запросил другие узлы приостановить репликацию.
  • wsrep_local_recv_queue — размер очереди приёма.

Конфигурация

Galera реализуется как плагин. Начиная с версии 10.1, MariaDB поставляется с предварительно установленным Galera, но по умолчанию не используется. Для его включения необходимо установить системную переменную wsrep_on.

Как и при асинхронной репликации, Galera использует двоичный журнал. Она также требует, чтобы изменения данных регистрировались в формате ROW.

Для других необходимых настроек см. Обязательные параметры.

Ограничения Galera

Galera не подходит для всех баз данных и рабочих нагрузок.

  • Galera реплицирует только таблицы InnoDB. Не следует использовать другие движки хранения.
  • По соображениям производительности крайне желательно, чтобы все таблицы имели первичный ключ.
  • Длинные транзакции повредят производительность.
  • Некоторые приложения используют целочисленный первичный ключ AUTO_INCREMENT. В случае переключения с аварийного узла на другой узел Galera не гарантирует, что AUTO_INCREMENT будет следовать хронологическому порядку. Поэтому приложения должны использовать столбцы TIMESTAMP для хронологического порядка вместо этого.
Содержимое, воспроизведённое на этом сайте, является собственностью его соответствующих владельцев, и это содержимое не проверяется предварительно MariaDB. Мнения, информация и мнения, выраженные в этом содержании, не обязательно отражают точку зрения MariaDB или любой другой стороны.

© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/mariadb-replication-overview-for-sql-server-users/

Spec-Zone.ru

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