2016-11-22 3 views
1

Время от времени зависает хранимая процедура. Какие-нибудь советы?Сохраненная процедура висит

BEGIN 
DECLARE bookId int; 

SELECT IFNULL(id,0) INTO bookId FROM products 
    WHERE 
     isbn=p_isbn 
    and stoc>0 
    and status='vizibil' 
    and pret_ron=(SELECT MAX(pret_ron) FROM products 
    WHERE isbn=p_isbn 
        and stoc>0 
        and status='vizibil') 
    ORDER BY stoc DESC 

LIMIT 0,1; 

IF bookId>0 THEN 
UPDATE products SET afisat='nu' WHERE isbn=p_isbn; 
UPDATE products SET afisat='da' WHERE id=bookId; 
SELECT bookId INTO obookId; 
ELSE 

SELECT id INTO bookId FROM products 
    WHERE 
     isbn=p_isbn 
    and stoc=0 
    and status='vizibil' 
    and pret_ron=(SELECT MAX(pret_ron) FROM products 
        WHERE isbn=p_isbn 
         and stoc=0 
         and status='vizibil') 
LIMIT 0,1; 
UPDATE products SET afisat='nu' WHERE isbn=p_isbn; 
UPDATE products SET afisat='da' WHERE id=bookId; 
SELECT bookId INTO obookId; 
END IF; 

END 

Когда он висит он делает это на: | 23970842 | имя пользователя | sqlhost: 54264 | база данных | Запрос | 65 | Отправка данных | ВЫБРАТЬ IFNULL (идентификатор, 0) INTO BookID ИЗ продуктов ГДЕ = NAME_CONST ISBN ('p_isbn', _ utf8'973-679-50 | 0,000 |

| 1133136 | Имя пользователя | sqlhost: 52466 | _emindb базы данных | Запрос | 18694 | Передача данных | ВЫБРАТЬ IFNULL (идентификатор, 0) INTO BookID ИЗ продуктов ГДЕ = NAME_CONST ISBN ('p_isbn', _ utf8'606-92266- | 0,000 |

ответ

1

Во-первых, я хотел бы упомянуть Percona toolkit , это отлично подходит для отладки взаимоблокировок и зависания транзакций. Во-вторых, я бы предположил, что во время зависания существует несколько потоков, выполняющих эту же процедуру. Нам нужно знать, какие блокировки приобретаются во время зависания MySQL команда SHOW INNODB STATUS дает вам эту информацию в деталях. На следующей «зависании» запустите эту команду.

я почти забыл упомянуть innotop инструмент, который похож, но лучше: https://github.com/innotop/innotop

Далее, я предполагаю, что вы двигатель InnoDB. Уровень изоляции транзакции по умолчанию REPEATABLE READ может быть слишком высоким в этой ситуации из-за блокировки диапазона, вы можете попробовать попробовать READ COMMITTED для тела процедуры (SET для READ COMMITTED в начале и обратно к REPEATABLE READ в конце).

Наконец, возможно, самое главное, обратите внимание, что ваша процедура выполняет SELECT и UPDATE (в смешанном порядке) в одной таблице, используя, возможно, одно и то же значение p_isbn. Представьте, если эта процедура выполняется одновременно - это идеальный тупик.

Смежные вопросы