sql >> Database teknologi >  >> RDS >> PostgreSQL

Opdatering af databaserækker uden at låse tabellen i PostgreSQL 9.2

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.




  1. CASESTUDIE:ARKWARE MS ACCESS CRM

  2. Android Realm-håndtering af primær nøgle i relationelt objekt

  3. Kan ikke finde PostgreSQL-klientbiblioteket (libpq)

  4. Postgres dynamiske forespørgselsfunktion