Wie mittels PL/SQL eine Datenbankverbindung blockieren?

Zrebna

Bekanntes Mitglied
Hi!

Folgender SQL-Code liefert mir ausgewählte Attribute aller Connections incl. dem Attribut 'blocking PIDs':

SQL:
select datname, pid, usename, application_name, client_addr, backend_start, state, wait_event, pg_blocking_pids(pid)
from pg_stat_activity;

Da kein Prozess bei mir eine Verbindung bzw. einen anderen Prozess blockiert, liefert mir die Abfrage für das Attribut ' pg_blocking_pids(pid)' keine Werte.
Ich möchte aber, dass hier zu Testzwecken Werte auftauchen.

Scheinbar soll man mittels einer PL/SQL-Methode einen blockierenden Prozess erzeugen können.

Weiß Jemand wie genau das geht?

Gruß
Zrebna
 
Erstmal eine Tabelle vorbereiten:
SQL:
CREATE TABLE blocker (
  id serial primary key,
  bvalue integer not null
);

INSERT INTO blocker(bvalue) VALUES (100);
INSERT INTO blocker(bvalue) VALUES (110);

SELECT * FROM blocker;

 id | bvalue 
----+--------
  1 |    100
  2 |    110
(2 rows)

In einer psql-Session (Session 1):
SQL:
\set AUTOCOMMIT=OFF;
UPDATE blocker SET bvalue = bvalue + 10 WHERE id = 1;

In einer zweiten psql-Session (Session 2):
SQL:
UPDATE blocker SET bvalue = bvalue + 10 WHERE id = 1;

Die zweite Session blockiert nun, bis die erste Session die Transaktion beendet hat. Das solltest Du nun mit Deinem SQL-Statement abfragen können.
 
Schon mal vielen Danks fürs Antworten - leider funktioniert es bei mir nicht.

Also nach dem Erstellen der beiden Tabellen und dem Deaktivieren von auto-committ in pgadmin4,
markiere ich einfach diese beiden Befehle und exekutiere sie:

SQL:
UPDATE blocker SET bvalue = bvalue + 10 WHERE id = 1;
UPDATE blocker SET bvalue = bvalue + 10 WHERE id = 1;

Danach hab ich einfach folgenden Befehl ausgeführt und gehofft, dass durch das Ausführen der beiden Update-Befehle ein neuer Prozess entstanden ist, der nun auch einen blockierenden Prozess hat, also von einem anderen Prozess blockiert wird:

SQL:
select datname, pid, usename, application_name, client_addr, backend_start, state, wait_event, pg_blocking_pids(pid)
from pg_stat_activity;

Leider ist das nicht der Fall gewesen 🙁

Der neue Wert von bvalue mit der id = 1 ist nun auch 120.

Liegt es daran, dass ich die beiden Update-Befehle einfach konsekutiv in einem Ruck ausgeführt habe?
Wie führt man die beiden Befehle in unterschiedlichen Sessions aus, so wie du es angeführt hast?
 
Du musst mehrere Verbindungen öffnen ...
1. Verbindung: Du machst das UPDATE ohne COMMIT, damit hat diese Verbindung einen Lock auf der Table Row
2. Verbindung: Du greifst ebenfalls auf diese Row zu, die durch die andere Verbung gelockt ist. Dieser Zugriff muss somit warten, bis ide erste Verbindung den Lock freigibt.
3. Verbindung: Du fragst nach den Blocks- und nun solltest Du sehen, dass die 2. Verbindung geblockt wurde.
 
Du musst mehrere Verbindungen öffnen ...
1. Verbindung: Du machst das UPDATE ohne COMMIT, damit hat diese Verbindung einen Lock auf der Table Row
2. Verbindung: Du greifst ebenfalls auf diese Row zu, die durch die andere Verbung gelockt ist. Dieser Zugriff muss somit warten, bis ide erste Verbindung den Lock freigibt.
3. Verbindung: Du fragst nach den Blocks- und nun solltest Du sehen, dass die 2. Verbindung geblockt wurde.

Ich kenne es bei pgadmin4 bis dato nur so bzgl. neue Verbindungen erstellen:

Ich wechsel zu einer anderen Datenbank:
Wenn ich nun den Schritt 2 ausführe, dann ist die Tabelle 'blocker' natürlich in dieser db nicht bekannt.

Soll sie dort auch erstellt werden? Wobei, dann ist es ja nicht die selbe Relation.

Oder wie erstellt man in pgadmin4 neue Verbindungen und kann dann (im selben?) Query-Fenster die obigen 3 Schritte bzgl. 3 unterschiedlichen Verbindungen ausführen?

edit:
Und in welcher der drei Verbindungen wir dieser Code ausgeführt?

SQL:
CREATE TABLE blocker (
  id serial primary key,
  bvalue integer not null
);

INSERT INTO blocker(bvalue) VALUES (100);
INSERT INTO blocker(bvalue) VALUES (110);

SELECT * FROM blocker;
 
Zuletzt bearbeitet:
Sowas könntest Du per Kommandozeile machen - einfach in 3 Terminal Fenstern jeweils auf die Datenbank zugreifen.

Und pgadmin kenne ich nicht so im Detail. Aber das Tool lässt sich ggf. auch einfach mehrfach starten? Oder ein Server mehrfach eintragen, so dass man mehrere Connections bekommen kann? Aber über die Kommandozeile ist sowas immer am einfachsten finde ich.
 

Neue Themen


Zurück
Oben