Есть ли ограничение на одновременные транзакции в MariaDB?

Существует сервер Centos 7 с Asterisk PBX 11.25.3 и mysql Ver 15.1 Distrib 10.3.18-MariaDB для Linux (x86_64).

extension.conf:

[from-main-asterisk]
exten => _9XXXXXXXXXXXX,1,MYSQL(Connect connid localhost root rootpasswd mydatabase)
exten => _9XXXXXXXXXXXX,n,GotoIf($["${connid}" = ""]?error,1)
exten => _9XXXXXXXXXXXX,n(select_sim),MYSQL(Query RESULTID ${connid} set autocommit=0)
exten => _9XXXXXXXXXXXX,n,MYSQL(Query RESULTID ${connid} START TRANSACTION)
exten => _9XXXXXXXXXXXX,n,MYSQL(Query RESULTID ${connid} SELECT sim_name FROM  sim_stat  where status = 'FREE'  order by rand() limit 1 ) 
exten => _9XXXXXXXXXXXX,n(sqlresult),MYSQL(Fetch fetchid ${RESULTID} SIM_NAME)
exten => _9XXXXXXXXXXXX,n,MYSQL(Clear ${RESULTID})
exten => _9XXXXXXXXXXXX,n,MYSQL(Query RESULTID ${connid} UPDATE sim_stat set status = "BUSY" where sim_name = "${SIM_NAME}") 
exten => _9XXXXXXXXXXXX,n,MYSQL(Query RESULTID ${connid} COMMIT)
exten => _9XXXXXXXXXXXX,n,Dial(SIP/gsm-${SIM_NAME}#${EXTEN:1},,g)
exten => _9XXXXXXXXXXXX,n,Hangup

exten => h,1,MYSQL(Query RESULTID ${connid} UPDATE sim_stat set status = "FREE"  where sim_name = "${SIM_NAME}")
exten => h,n,MYSQL(Query RESULTID ${connid} COMMIT)
exten => h,n,MYSQL(Disconnect ${connid})

exten => error,1,NoOp(Database connection error!)
exten => error,n,Hangup

sip.conf:

[from-main-asterisk]
type=friend
host=x.x.x.x
qualify=yes
qualifyfreq=60
canreinvite=no
disallow=all
allow=alaw
context=from-main-asterisk

Когда из магистрали поступает более 15-20 одновременных вызовов, я получаю сообщение:

WARNING[2239][C-00000389] app_mysql.c: aMYSQL_query: mysql_query failed. Error: Lock wait timeout exceeded; try restarting transaction

Есть ли ограничение на одновременные транзакции в MariaDB?

2 ответа

Решение
  1. Используйте func_odbc, он правильно обрабатывает соединения
  2. Заказ с помощью rand() ВСЕГДА сканировать всю таблицу
  3. Если ваша таблица типа myisam, любое сканирование таблицы блокирует всю таблицу.

Количество транзакций ограничено примерно 96 КБ. См. https://mariadb.com/kb/en/library/innodb-limitations/

INDEX(status, sim_name) (в этом порядке) может ускорить выполнение длинного запроса в вашей транзакции.

Или вы можете избежать сканирования таблицы, требуемого ORDER BY rand()используя один из способов здесь: http://mysql.rjweb.org/doc.php/random

Другой подход включает переработку вашего приложения, чтобы захватить, скажем, 10 случайных sim_names, пометить их как используемые вашим процессом, выйти из транзакции. Затем обработайте их и, наконец, выпустите в другой транзакции (ах).

Такой подход, при котором отметка и деблокирование не являются частью транзакции, содержащей действие - это особенно полезно, когда действие занимает много времени.

Взять 10 так же быстро, как и 1; следовательно, это дает вам скорость.

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