репликация, поле uuid в качестве первичного ключа, репликация на основе строк

#mysql #primary-key #replication #uuid

#mysql #первичный ключ #репликация #uuid

Вопрос:

Я ищу наилучший способ реализовать репликацию на нескольких сайтах с помощью MySDQL. Поскольку я в основном пользователь MS-SQL, я чувствую себя довольно некомфортно с терминологией репликации MySQL и несколькими версиями MySQL, которые не выполняют в точности одно и то же одинаково.

Моя цель, согласно терминологии SQL, иметь издателя и много подписчиков. Учетные записи открыты для пользовательских обновлений. Изменения реплицируются издателем, который затем распространит эти изменения среди других подписчиков.

Итак, моя цель здесь — определить правильное правило первичного ключа, которое будет использоваться для наших таблиц. Поскольку нам нужны исключительно суррогатные ключи, у нас есть возможность использовать либо целочисленные автоинкрементные поля, либо uuid / uuid_short. Чтобы избежать конфликтов репликации, integer autoincrement не соответствует нашим потребностям, поскольку это может создать конфликты репликации, когда между двумя синхронизациями оба сервера вставляют запись в одну и ту же таблицу. Итак, по моему мнению, правильным решением для предотвращения конфликтов репликации первичного ключа было бы:

  • используйте поля uuid или uuid-short в качестве первичных ключей
  • иметь соответствующие значения uuid, установленные сервером во время ВСТАВКИ
  • установите репликацию в режим RBR (репликация на основе строк — звучит эквивалентно репликации слиянием MS-SQl), а не SBR (репликация на основе инструкций — звучит как репликация транзакций). Насколько я понимаю, RBR вставит вычисленное значение uuid «как есть» на другие серверы во время репликации, в то время как SBR вызовет функцию uuid () и сгенерирует новое значение на каждом сервере… таким образом, возникает серьезная проблема!

Будет ли это работать?

Комментарии:

1. Если вы определяете первичный ключ как PRIMARY KEY(id, server_id) , а затем устанавливаете значения по умолчанию для server_id столбца на каждом из ваших недавно добавленных серверов — вы устраняете необходимость в UUID и избегаете конфликтов pk.

2. Это решение, но я бы хотел не иметь составных первичных ключей. Они делают ОБЪЕДИНЕНИЯ настолько трудными для понимания. Я уверен, что есть способ заставить это работать, не прибегая к такому решению. В любом случае спасибо.

3. UUID добавляет так много накладных расходов, и добавление еще одного AND к вашему соединению действительно не должно быть критерием, из-за которого не удается использовать auto_increment как PK. Я пробовал оба способа, UUID был моим первым выбором, но они медленные, длинные, создают проблемы для InnoDB, и когда вы хотите вручную что-то посмотреть в своей базе данных — это полная тарабарщина, на которую трудно быстро что-то найти.

Ответ №1:

Я думаю, что здесь есть две не связанные проблемы:

1.

Выбор первичного ключа способом, который, вероятно, уникален — UUID является приемлемым подходом. Вы можете использовать его с SBR или RBR, при условии, что клиентское приложение генерирует UUID. Если вы случайно вызываете функцию mysql для ее генерации, то вам нужно использовать репликацию на основе строк. Репликация на основе строк, как правило, намного лучше, поэтому единственная причина, по которой вы хотели бы использовать репликацию на основе инструкций, — это обратная совместимость с подчиненным устройством MySQL <5.1 или устаревшим приложением, которое полагается на некоторые его действия.

2.

Во-вторых, вы, похоже, хотите выполнить репликацию с несколькими мастерами. ЭТО НЕ СРАБОТАЕТ.

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

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

Репликация MySQL не имеет алгоритма «разрешения конфликтов», она просто остановится и прервется, если будет обнаружен конфликт.

Даже если предположить, что ваша база данных не содержит УНИКАЛЬНЫХ ИНДЕКСОВ, кроме первичных ключей, которые выделяются UUID, в вашем приложении все равно могут быть правила, которые приводят к сбою работы с несколькими мастерами.

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

Комментарии:

1. Спасибо за ваш ответ. Итак, я понимаю из ваших комментариев, что репликация с MySQL ограничена репликацией только для чтения, где обновления могут выполняться только на одном сервере, а затем распространяться на серверы только для чтения. Для меня это звучит как серьезное ограничение на использование этого сервера. Как пользователи MySQL справляются с этим ограничением?

2. Обычно путем записи только в мастер; они либо асинхронно ставят записи в очередь (для достижения высокой доступности), либо допускают, что мастер является единственным местом для выполнения записей. На практике это не является серьезным ограничением. Репликация с несколькими мастерами может работать с MySQL только в очень ограниченных обстоятельствах, не подходит для использования общего назначения (например, приложение было специально разработано для работы с несколькими мастерами). Как я уже сказал, разрешения конфликтов репликации не существует, поэтому единственным решением является отсутствие конфликтов репликации, что на практике означает только запись в одном месте.

3. Есть ли у вас какие-либо ссылки или документация о базах данных, предназначенных для репликации с несколькими мастерами? На рынке нет доступных дополнений для разрешения конфликтов?