Вопрос или проблема
У меня есть 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 для более глубокого анализа вашей конфигурации и кода.