Ich möchte den gesamten Inhalt einer Tabelle ersetzen, ohne dabei eingehende SELECT
Anweisungen zu beeinflussen .
Der Anwendungsfall ist eine Tabelle, in der Postfachinformationen gespeichert werden, die regelmäßig extrahiert werden, und die in einer PostgreSQL-Tabelle gespeichert werden muss. Es gibt viele Clients, die eine Anwendung verwenden, die ständig dieselbe Tabelle abfragt.
Normalerweise würde ich sowas machen (Pseudocode eingehend) ...
BEGIN TRANSACTION
TRUNCATE TABLE
INSERT INTO
COMMIT
Leider kann die Tabelle während dieses Vorgangs nicht gelesen werden. Aufgrund der Zeit, die INSERT INTO
für die Fertigstellung benötigt wird. Der Tisch ist gesperrt.
In MySQL hätte ich ihren atomaren RENAME TABLE
Befehl verwendet, um diese Probleme zu vermeiden ...
CREATE TABLE table_new LIKE table;
INSERT INTO table_new;
RENAME TABLE table TO table_old, table_new TO table; *atomic operation*
DROP TABLE table_old;
Wie könnte ich das in PostgreSQL erreichen?
In dieser Frage können Sie davon ausgehen, dass ich keine Fremdschlüssel verwende.
quelle
TRUNCATE
Befehl erhält eine AccessExclusive-Sperre für die Tabelle, sodass niemand sonst in der Lage ist, aus der Tabelle zu lesen, bis diese Transaktion festgeschrieben oder zurückgesetzt wird.delete
stattdessen verwendentruncate
, wird es langsamer, aber ohne die Leser zu blockieren. Wie viele Zeilen müssen Sie löschen?DELETE
undINSERT
wäre viel zu lang.Antworten:
Richtig, der
TRUNCATE TABLE
Befehl , den Sie ausführen, "... erhält eine ACCESS EXCLUSIVE-Sperre für jede Tabelle, für die er ausgeführt wird ", sodass im ersten von Ihnen veröffentlichten SQL-Block alle anderen Clients, die versuchen, nach dieser Zeit auf die Tabelle zuzugreifen, blockiert werden, bis SieINSERT
fertig sind und duCOMMIT
.Sie können dieselbe Problemumgehung wie in Ihrem MySQL-spezifischen Code verwenden. Postgres unterstützt ungefähr dieselbe Syntax und weist ein ähnliches Sperrverhalten auf. Nämlich:
Zusätzlicher Bonus: Postgres unterstützt im Gegensatz zu MySQL Transaktions-DDL. Falls Sie also die obige Transaktion ROLLBACKEN müssen, können Sie dies sicher tun.
quelle
LOCK TABLE
Ihnen vorgeschlagene Methode verwenden würde, müsste ich sie vor dem erneut entsperrenCOMMIT
, oder wird sie sich selbst entsperren?_old