2016-03-25 8 views
0

Ich arbeite mit PHP 7 (5.6.11) und PostgreSQL 9.4 auf Ubuntu 15.10 und Freebsd.Wie erkennen Sie, warum Sperren Tabelle Zeile?

Mein Code wählen Sie eine Zeile nach ID aus der Tabelle mit "für Update" -Option. Manchmal (ein Fall von Hunderten) führt diese Abfrage sehr lange Zeit aus, ungefähr 20-90 Sekunden. Mein Code arbeitet in etwa 30 Threads.

Wie ich verstehe, "wählen * aus der Tabelle für die Aktualisierung" Sperre nur einzelne Zeile in der Tabelle und ich kann solches Verhalten nur erhalten, wenn ein anderer Prozess diese Zeile bereits auswählen. Habe ich recht? Es kann jedoch nicht passieren, da das Skript erst ausgeführt wird, nachdem eine Nachricht vom Nachrichtenbroker erhalten wurde.

Einzelne Nachricht für eine Zeile. Ich kann mir also nicht vorstellen, wer und warum diese Reihe blockieren kann. (select * from table for update an einer Stelle verwendet, wo ich eine Nachricht aus der Warteschlange bekomme).

Ich versuche, Informationen von pg_locks und psax Ausgang zu verwenden. Ich speichere diese Information, bevor ich für die Aktualisierung auswähle, und dann, wenn ich eine lange Abfrage abfinde, sende ich diese Information in den Protokollen. Ich sehe pid des Prozesses, der Tabelle sperrt, aber ich sehe diese PID in ps ax Ausgabe nicht. Das verwirrt mich.

Hat jemand eine Idee?

+0

Sie müssen dafür Dokumentation bereitstellen. Angenommen, dies ist die einzige Abfrage, die in diesem Moment "pausiert", dann klingt es nach Locking. Ich habe jedoch noch nie gehört, dass ein Schloss nicht in pg_locks aufgeführt ist. –

Antwort

0

ich Grund gefunden. Ich verwende einen eigenen Task-Manager, der mit ActiveMQ arbeitet. Manchmal setzt der Task-Manager aus irgendwelchen Gründen eine Pause für bestimmte Aufgaben ein. Nach einem Ereignis wird die Aufgabe anschließend in der Warteschlange wiederhergestellt. Erneutes Senden in Datenbank- und ActiveMQ-Transaktionen.

Für die Arbeit mit ActiveMQ ich benutze diese Bibliothek: https://github.com/centraldesktop/php-stomp

Für das Senden von Nachrichten i Sync-Modus verwenden, und ich fand, dass ich für Transaktionen verwenden diesen Modus vergessen. Wenn die Aufgabe in der Warteschlange erneut gesendet wird, werden die ersten Nachrichten ohne Transaktionen in die Warteschlange aufgenommen, sie führen Skripts und ... aus. Diese Skripts sollten warten, bis die Resender-Aufgaben erneut gesendet werden und seine Datenbanktransaktionen festschreiben.

-1

Verschiedene Datenbankprodukte verwenden drastisch unterschiedliche Sperrmechanismen. Einige, wenn Sie eine select * from table for update where id=34 tun, kann eine Zeile oder einen Block sperren. Sie müssen die offizielle Dokumentation lesen.

Wenn Sie ein select * from table for update ohne Kriterien tun, werden Sie die gesamte Tabelle sperren, bis Sie commit oder rollback

+0

Ich überprüfe das, meine Anfrage per ID in postgresql Sperre nur einzelne Zeile. – Hayate

Verwandte Themen