2016-11-22 3 views
1

Eine gespeicherte Prozedur hängt von Zeit zu Zeit. Irgendwelche Ratschläge?Gespeicherte Prozedur hängt

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 

Wenn es hängt es tut es auf: | 23970842 | Benutzername | sqlhost: 54264 | Datenbank | Abfrage | 65 | Daten senden | SELECT IFNULL (id, 0) INTO BookID VON Produkte WHERE isbn = NAME_CONST ('p_isbn', _ utf8'973-679-50 | 0.000 |

| 1133136 | Benutzername | sqlhost: 52466 | Datenbank _emindb | Abfrage | 18694 | Daten senden | SELECT IFNULL (id, 0) INTO BookID VON Produkte WHERE isbn = NAME_CONST ('p_isbn', _ utf8'606-92266- | 0.000 |

Antwort

1

Erstens würde Ich mag die Percona toolkit erwähnen Es ist großartig für das Debuggen von Deadlocks und angehängten Transaktionen. Zweitens würde ich vermuten, dass zum Zeitpunkt des Hängens mehrere Threads dasselbe Verfahren ausführen. Was wir wissen müssen, ist, welche Sperren zum Zeitpunkt des Hängens akquiriert werden MySQL Befehl SHOW INNODB STATUS gibt Ihnen diese Informationen im Detail. Führen Sie diesen Befehl beim nächsten "Hängen" aus.

ich fast vergessen das Werkzeug innotop zu erwähnen, die ähnlich ist, aber besser: https://github.com/innotop/innotop

Als nächstes gehe ich davon aus Sie die InnoDB-Engine sind. Die Standardtransaktionsisolationsstufe von REPEATABLE READ kann in dieser Situation aufgrund der Bereichssperrung zu hoch sein. Sie könnten READ COMMITTED für den Hauptteil der Prozedur verwenden (SET zu READ COMMITTED am Anfang und zurück zu REPEATABLE READ am Ende).

Schließlich, vielleicht am wichtigsten, beachten Sie, dass Ihre Prozedur SELECTs und UPDATEs (in gemischter Reihenfolge) auf der gleichen Tabelle mit vielleicht der gleichen p_isbn Wert führt. Stellen Sie sich vor, dass diese Prozedur gleichzeitig ausgeführt wird - es ist eine perfekte Deadlock-Einrichtung.