Многоузловая запись 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 и выполняете обновление, вы получаете сценарий «последний в выигрыше», поэтому тот, кто выполняет оператор последним, будет золотым. Любые другие данные теряются, поэтому, если два обновления происходят одновременно, одно из них будет сохранено, а данные других по существу потеряны.

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

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


person Kendall Bennett    schedule 08.06.2016    source источник


Ответы (1)


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

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

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

person utdrmac    schedule 28.06.2016
comment
У нас уже есть полная обработка повторных попыток для ручных транзакций (что довольно необходимо для правильной работы), поэтому мой вопрос действительно был о том, будут ли транзакции автоматической фиксации когда-либо терпеть неудачу. Я имею в виду ситуацию, когда два узла пытаются одновременно выполнять транзакции с одной и той же записью. Узел 1 будет завершен, а узел 2 - отдельно, но когда он идет на его репликацию, один из них должен выйти из строя? Итак, PXC автоматически пытается выполнить автоматическую фиксацию, которая не удалась? - person Kendall Bennett; 29.06.2016
comment
Да, автоматическая фиксация транзакций тоже может завершиться ошибкой. В конце концов, это транзакции. Нет никакой разницы, если autocommit = 0 или = 1, они обрабатываются одинаково. Ваш оператор узел 2 будет заполняться отдельно неверно. В вашем примере node2 НЕ завершится при фиксации. Сертификация происходит ДО того, как произойдет фиксация, поэтому узел 2 получит ошибку при фиксации. Узел 1 запускает процесс фиксации. Это включает в себя репликацию набора записи на все узлы (включая его самого) и сертификацию. Затем происходит фактическая фиксация на диске. Узел 2 при фиксации также будет реплицироваться и пытаться сертифицировать локально, что не удастся. - person utdrmac; 15.07.2016
comment
Я никогда не говорил, что это не подведет. Я знаю, что это не удастся; вопрос в том, будет ли база данных автоматически повторять транзакцию, если она терпит неудачу в режиме автоматической фиксации, потому что она уже знает, что она атомарна, и имеет все необходимое для ее перезапуска? - person Kendall Bennett; 15.07.2016
comment
Кластер может автоматически повторять автоматически выполненные операторы (wsrep_retry_autocommit), но не обычные (ручные) транзакции с несколькими операторами. Из руководства Percona: Эта переменная устанавливает количество попыток автоматически выполненных транзакций в кластере при обнаружении ошибок сертификации. В случае конфликта узел кластера должен быть безопасным, чтобы просто повторить попытку выполнения инструкции без ведома клиента в надежде, что в следующий раз она пройдет. - person utdrmac; 16.07.2016
comment
Спасибо это то, что я искал - person Kendall Bennett; 17.07.2016