Многоузловая запись Percona XtraDB Cluster и неожиданные тупики вне транзакции?
У меня проблемы с поиском ответа на этот вопрос с помощью Google или Stack Overflow, поэтому, возможно, люди, знакомые с Percona XtraDB, помогут ответить на этот вопрос. Я полностью понимаю, как могут возникать неожиданные взаимоблокировки, как описано в этой статье, и решение состоит в том, чтобы убедиться, что вы обернули свои транзакции логикой повторения, чтобы вы могли перезапустить их, если они потерпят неудачу. Мы уже делаем это.
Мои вопросы касаются обычных обновлений, которые происходят вне транзакции в режиме автоматической фиксации. Обычно, если вы пишете только в одну БД SQL и выполняете обновление, вы получаете сценарий с последним выигрышем, поэтому тот, кто выполняет оператор последним, получает золотую награду. Любые другие данные будут потеряны, поэтому, если два обновления происходят одновременно, одно из них вступит в силу, а остальные данные по существу будут потеряны.
Теперь, что происходит в мультимастерной среде с тем же самым? Разница в кластерном режиме с несколькими хозяевами заключается в том, что тупик может возникать в точке, где происходит фиксация, а не когда блокировка впервые берется на стол. Таким образом, в режиме автоматической фиксации данные будут записаны в БД, но затем они могут потерпеть неудачу при попытке передать это другим узлам в кластере, если что-то еще изменило точно такую же запись в то же время. Очевидно, что простым решением является повторное выполнение обновления, и мне кажется, что сама база данных должна справиться с этим, так как это один оператор в режиме автоматической фиксации?
Так это то, что происходит в этом сценарии, или мне нужно начинать переносить весь мой код обновления и при повторной обработке, и повторять его сам, когда это не удается?
1 ответ
Autocommit по-прежнему является транзакцией; транзакция с одним оператором. Ваше единственное заявление только что заключено в BEGIN/COMMIT для вас. Я верю, что ваша логика перевернута. В PXC действует правило "зафиксировать первые выигрыши". Если вы запускаете ручную транзакцию на узле 1 (то есть: autocommit=0; BEGIN;) и UPDATE id=1 и не фиксируете затем на узле 2, вы автоматически фиксируете обновление в той же строке, что будет успешно на узле 2 и успешно на узле 1. Когда вы фиксируете ручное ОБНОВЛЕНИЕ, вы получите ошибку взаимоблокировки. Это правильное поведение.
Неважно, если автокоммит или нет; какой бы коммит ни выпал первым, другая транзакция должна быть повторена. По этой причине мы не рекомендуем выполнять запись в несколько узлов в PXC.
Да, если вы хотите писать в несколько узлов, вам нужно настроить код так, чтобы "try-catch-retry" обрабатывал этот случай ошибки.