Galera + MariaDB: Взаимная блокировка: транзакция wsrep прервана

Вопрос или проблема

У меня есть 1 сервер, настроенный на Galera, 4 сервера с MariaDB и 1 с HAProxy.

Но когда я пытаюсь сделать обновление на любом сервере, я получаю ошибку “Deadlock: wsrep aborted transaction” или “wsrep_max_ws_rows exceeded” (иногда).

Серверы мощные, с 32 ГБ памяти и 24 CPU (VmWare).

gard.conf (ip 1.1.1.110):

GALERA_NODES="1.1.1.111:4567 1.1.1.112:4567  1.1.1.113:4567  1.1.1.114:4567"
GALERA_GROUP="mariadb_cluster" 
GALERA_OPTIONS="pc.wait_prim=no"  
LOG_FILE="/var/log/garbd.log"

cluster.cnf (4 сервера MariaDB с ip 1.1.1.111 до 1.1.1.114):

[mysqld]
query_cache_size=0
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
query_cache_type=0
bind-address=0.0.0.0
innodb_file_per_table
collation-server = utf8_general_ci
init-connect="SET NAMES utf8"
character-set-server = utf8
join_buffer_size = 1M

wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
    
wsrep_cluster_name="mariadb_cluster"
wsrep_cluster_address="gcomm://1.1.1.111,1.1.1.112,1.1.1.113,1.1.1.114"

wsrep_sst_method=rsync
    
wsrep_node_address="1.1.1.111"
wsrep_node_name="mysqlcl0X"
wsrep_max_ws_rows=2048
wsrep_max_ws_size=8G
wsrep_provider_options = "gcs.fc_limit = 2048; gcs.fc_factor = 0.99; gcs.fc_master_slave = yes"

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

haproxy.cfg:

listen galera
     bind *:3306
     mode tcp
     timeout client 60000ms
     timeout server 60000ms
     balance leastconn
     server 1.1.1.111 1.1.1.111:3306 check
     server 1.1.1.112 1.1.1.112:3306 check
     server 1.1.1.113 1.1.1.113:3306 check
     server 1.1.1.114 1.1.1.114:3306 check

Что мне не хватает в конфигурации?

Уже сейчас большое спасибо!

https://mariadb.com/kb/en/galera-cluster-system-variables/#wsrep_max_ws_rows

Возможно, =0 решит хотя бы часть проблемы.

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

Я решил это с помощью следующего параметра:

wsrep-retry-autocommit = 100

Я не думаю, что это правильное решение, выполнение занимает много времени, но это работает.

Продолжает выдавать ошибку..

1213 Deadlock: wsrep aborted transaction 

Ответ или решение

Проблема, с которой вы столкнулись в вашем Galera кластере, связана с двумя ошибками: "Deadlock: wsrep aborted transaction" и "wsrep_max_ws_rows exceeded". Эти ошибки могут возникать по нескольким причинам, и их разрешение требует комплексного подхода.

1. Понимание ошибок

  • "Deadlock: wsrep aborted transaction": Это сообщение указывает на то, что две или более транзакций блокируют друг друга, ожидая освобождения ресурсов, что приводит к тому, что одна из них должна быть прервана для разрешения ситуации. Это может происходить при неправильной обработке транзакций, когда они пытаются обновить одни и те же строки данных в разное время.

  • "wsrep_max_ws_rows exceeded": Эта ошибка возникает, когда количество строк, изменяемых в одной транзакции, превышает значение, установленное в параметре wsrep_max_ws_rows. Поскольку ваш текущий лимит установлен на 2048, вы можете столкнуться с этой ошибкой, если ваши транзакции обрабатывают больше строк, чем этот лимит.

2. Рекомендации по конфигурации

Увеличение wsrep_max_ws_rows

Если ваш рабочий процесс позволяет обрабатывать больше строк в транзакциях, вы можете попробовать увеличить wsrep_max_ws_rows. Например:

wsrep_max_ws_rows=4096

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

Оптимизация транзакций

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

3. Настройки блокировок и таймаутов

Рассмотрите возможность настройки параметров, связанных с блокировками и таймаутами. Например, вы уже попробовали использовать wsrep-retry-autocommit, что может помочь, но в то же время стоит установить таймауты для блокировок:

innodb_lock_wait_timeout=50

4. Настройки Galera

Убедитесь, что ваш параметр gcs.fc_limit настроен в соответствии с вашими потребностями. Это значение контролирует, сколько фронтов (или потока) может быть в одном блоке. Попробуйте настроить его на более высокое значение.

wsrep_provider_options = "gcs.fc_limit = 4096; gcs.fc_factor = 0.99; gcs.fc_master_slave = yes"

5. Мониторинг и ведение журнала

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

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...