Многоузловая запись Percona XtraDB Cluster и неожиданные тупики вне транзакции?

У меня проблемы с поиском ответа на этот вопрос с помощью Google или Stack Overflow, поэтому, возможно, люди, знакомые с Percona XtraDB, помогут ответить на этот вопрос. Я полностью понимаю, как могут возникать неожиданные взаимоблокировки, как описано в этой статье, и решение состоит в том, чтобы убедиться, что вы обернули свои транзакции логикой повторения, чтобы вы могли перезапустить их, если они потерпят неудачу. Мы уже делаем это.

https://www.percona.com/blog/2012/08/17/percona-xtradb-cluster-multi-node-writing-and-unexpected-deadlocks/

Мои вопросы касаются обычных обновлений, которые происходят вне транзакции в режиме автоматической фиксации. Обычно, если вы пишете только в одну БД SQL и выполняете обновление, вы получаете сценарий с последним выигрышем, поэтому тот, кто выполняет оператор последним, получает золотую награду. Любые другие данные будут потеряны, поэтому, если два обновления происходят одновременно, одно из них вступит в силу, а остальные данные по существу будут потеряны.

Теперь, что происходит в мультимастерной среде с тем же самым? Разница в кластерном режиме с несколькими хозяевами заключается в том, что тупик может возникать в точке, где происходит фиксация, а не когда блокировка впервые берется на стол. Таким образом, в режиме автоматической фиксации данные будут записаны в БД, но затем они могут потерпеть неудачу при попытке передать это другим узлам в кластере, если что-то еще изменило точно такую ​​же запись в то же время. Очевидно, что простым решением является повторное выполнение обновления, и мне кажется, что сама база данных должна справиться с этим, так как это один оператор в режиме автоматической фиксации?

Так это то, что происходит в этом сценарии, или мне нужно начинать переносить весь мой код обновления и при повторной обработке, и повторять его сам, когда это не удается?

1 ответ

Autocommit по-прежнему является транзакцией; транзакция с одним оператором. Ваше единственное заявление только что заключено в BEGIN/COMMIT для вас. Я верю, что ваша логика перевернута. В PXC действует правило "зафиксировать первые выигрыши". Если вы запускаете ручную транзакцию на узле 1 (то есть: autocommit=0; BEGIN;) и UPDATE id=1 и не фиксируете затем на узле 2, вы автоматически фиксируете обновление в той же строке, что будет успешно на узле 2 и успешно на узле 1. Когда вы фиксируете ручное ОБНОВЛЕНИЕ, вы получите ошибку взаимоблокировки. Это правильное поведение.

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

Да, если вы хотите писать в несколько узлов, вам нужно настроить код так, чтобы "try-catch-retry" обрабатывал этот случай ошибки.

Другие вопросы по тегам