Deadlock erkannt in PL/pgSQL-Funktion
Ich bin vor ein deadlock-problem aus einer PL/pgSQL-Funktion in meiner PostgreSQL-Datenbank. Finden Sie die SQL-Anweisung im code-block (nur Beispiel):
BEGIN
UPDATE accounts SET balance = 0 WHERE acct_name like 'A%';
UPDATE accounts SET balance = balance + 100 WHERE acct_name like '%A';
EXCEPTION WHEN OTHERS THEN RAISE NOTICE SQLERRM;
END;
Habe ich herausgefunden, dass der deadlock aufgetreten ist, während diese Anweisung ausgeführt wurde. Aber ich bin mir nicht sicher, dass es noch andere Aussagen zu aktualisieren versuchen diese Tabelle in der gleichen Zeit (weil ich nicht finden in meinen logging-system).
So, ist es möglich, dass der deadlock innerhalb dieser Aussage? Soweit ich weiß, wenn wir blockiert ganze Erklärung mit BEGIN
/END
. Es werden die gleichen Transaktion und sollte nicht gesperrt werden, von selbst.
- Sie haben alle Trigger, die auf Konten? Auch die explizite sperren?
- Standardmäßig wird eine Transaktion kann das beobachten der änderungen commit von anderen Transaktionen ausgeführt. Weitere Informationen finden Sie unter Transaction Isolation aus der PostgreSQL-Dokumentation.
- Ja habe ich, aber-Anweisung in diesem trigger ist nicht mit dieser Tabelle. Für die expliziten sperren ja auch.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist definitiv einige andere Prozess im Wettbewerb um die gleichen Ressourcen. Das liegt in der Natur von einem deadlock. Eine Funktion wie Sie-Anzeige kann nie deadlock selbst. Sehen Kommentar von @kgrittn unten, wer ist ein Experte auf Parallelität in PostgreSQL.
Ihre version von PostgreSQL fehlt. Moderne Versionen heben detaillierte Fehlermeldung. Beide Prozesse konkurrieren um Ressourcen aufgeführt sind, im detail mit standard-Protokollierung-Einstellungen. Überprüfen Sie Ihre db-logs.
Die Tatsache, dass Sie fangen die Fehler verhindern können, Postgres geben Sie den vollständigen details. Entfernen Sie die AUSNAHME block von Ihrem plpgsql-Funktion, wenn Sie nicht die Informationen erhalten, die in der db anmelden und versuchen Sie es erneut.
Zu lindern, deadlocks, können Sie eine Anzahl von Sachen tun. Wenn alle clients Zugriff auf Ressourcen synchronisiert, um deadlocks nicht auftreten können. Das Handbuch bietet eine grundlegende Strategie zu lösen die meisten Fälle in dem Kapitel über deadlocks.
Als für version 8.3: betrachten Sie ein Upgrade auf eine neuere version. Insbesondere diese Verbesserung in der version 8.4 sollte für Sie interessant sein (unter Angabe der release-notes):
Auch, version 8.3 entsprechen seine Ende des Lebens, im Februar 2013. Sie sollten beginnen, sollten Sie die Aktualisierung.
Einer deadlock-situation mit
VACUUM
hätte Feste in 8.3.1.Die Sie nicht bekommen würde deadlock-problem, wenn Sie hinzufügen Begehen zur Freigabe von Schreibsperren.
In PostgreSQL, beginnen bedeutet, dass Sie starten Sie die batch-Transaktion.
Ihre erste update lock Zeilen für Konten
WHERE acct_name like 'A%';
Diese Zeilen sind exklusiv gesperrt werden, nach dem ersten update.
Zweite update versucht zu öffnen, genau die gleichen Zeilen wie die erste Aktualisierung , aktualisieren
Versagen, weil die erste update ist noch NICHT begangen, noch.
Deshalb wird die zweite Aktualisierung Treffer deadlock war rollback.
BEGIN
ist nur der Anfang eines code-Blocks. Nicht das gleiche wieBEGIN
/COMMIT
in plain SQL.