MVCC
For det første, hvis "normale operationer" består af SELECT
forespørgsler, vil MVCC-modellen tage sig af det automatisk. UPDATE
blokerer ikke SELECT
og omvendt. SELECT
ser kun forpligtede data (eller hvad der er blevet gjort i samme transaktion), så resultatet af den store UPDATE
forbliver usynlig for andre transaktioner, indtil den er færdig (forpligtet).
Ydeevne / oppustethed
Hvis du har ikke andre objekter, der refererer til den tabel,
og du har ikke samtidige skriveoperationer (som ville gå tabt!),
og du har råd til en meget kort eksklusiv lås på bordet,
og du har selvfølgelig den ekstra diskplads:
Du kan holde låsningen på et minimum ved at oprette en opdateret version af tabellen i baggrunden. Sørg for, at den har alt for at være en drop-in-erstatning, så slip originalen og omdøb dupeen.
CREATE TABLE tbl_new (LIKE tbl_org INCLUDING CONSTRAINTS);
INSERT INTO tbl_new
SELECT col_a, col_b, array[col] aS col_c
FROM tbl_org;
Jeg bruger CREATE TABLE (LIKE .. INCLUDING CONSTRAINTS)
, fordi (der citerer manualen her):
Ikke-nul-begrænsninger kopieres altid til den nye tabel. CHECK
begrænsninger vil kun blive kopieret hvis INCLUDING CONSTRAINTS
er specificeret; andre typer begrænsninger vil aldrig blive kopieret.
Sørg for, at det nye bord er klar. Så:
DROP tbl_org;
ALTER TABLE tbl_new RENAME TO tbl_org;
Resulterer i et meget kort tidsvindue, hvor bordet udelukkende er låst.
Dette handler egentlig kun om ydeevne. Det skaber ret hurtigt et nyt bord uden opsvulmning. Hvis du har fremmednøgler eller visninger, kan du stadig gå den vej, men du skal forberede et script for at slippe og genskabe disse objekter, hvilket potentielt skaber yderligere eksklusive låse.
Samtidig skrivning
Med samtidige skriveoperationer er alt, hvad du kan gøre, at dele din opdatering i bidder. Du kan ikke gøre det i en enkelt transaktion, da låse kun frigives i slutningen af en transaktion.
Du kunne ansætte dblink , som kan starte uafhængige transaktioner på en anden database, inklusive sig selv. På denne måde kan du gøre det hele i en enkelt DO
sætning eller en plpgsql-funktion med en loop. Her er et løst relateret svar med flere oplysninger om dblink:
- Slip eller opret database fra lagret procedure i PostgreSQL
Din tilgang med markører
En markør inde i funktionen vil ikke købe dig noget . Enhver funktion indesluttes automatisk i en transaktion, og alle låse frigives først ved slutningen af transaktionen. Også selvom du brugte CLOSE cursor
(hvilket du ikke gør) det ville kun frigøre nogle ressourcer, men ikke frigør erhvervede låse på bordet. Jeg citerer manualen:
CLOSE
lukker portalen under en åben markør. Dette kan bruges til at frigive ressourcer tidligere end slutningen af transaktionen eller til at frigive cursorvariablen til at blive åbnet igen.
Du skal køre separat transaktioner eller (ab)brug dblink, som gør det for dig.