MVCC
Za prvé, pokud se "normální operace" skládají z SELECT
dotazy, model MVCC se o to postará automaticky. UPDATE
neblokuje SELECT
a naopak. SELECT
vidí pouze potvrzená data (nebo to, co bylo provedeno ve stejné transakci), takže výsledek velkého UPDATE
zůstane neviditelný pro ostatní transakce, dokud nebude dokončen (odsouhlasen).
Výkon / nadýmání
Pokud nemáte další objekty odkazující na tuto tabulku,
a nemáte souběžné operace zápisu (které by byly ztraceny!),
a můžete si dovolit velmi krátký exkluzivní zámek na stole,
a máte samozřejmě další místo na disku:
Zamykání můžete omezit na minimum vytvořením aktualizované verze tabulky na pozadí. Ujistěte se, že má vše být náhradní náhradou, pak originál zahoďte a přejmenujte dupe.
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;
Používám CREATE TABLE (LIKE .. INCLUDING CONSTRAINTS)
, protože (zde cituji manuál):
Nenulová omezení se vždy zkopírují do nové tabulky.
CHECK
omezení budou zkopírována pouze v případě, žeINCLUDING CONSTRAINTS
je zadáno;jiné typy omezení nebudou nikdy zkopírovány.
Ujistěte se, že nový stůl je připraven. Potom:
DROP tbl_org;
ALTER TABLE tbl_new RENAME TO tbl_org;
Výsledkem je velmi krátké časové okno, kde je tabulka výhradně uzamčena.
Tady jde opravdu jen o výkon. Poměrně rychle vytvoří nový stůl bez nadýmání. Máte-li cizí klíče nebo pohledy, stále můžete jít touto cestou, ale musíte si připravit skript k odstranění a opětovnému vytvoření těchto objektů, což může potenciálně vytvářet další exkluzivní zámky.
Souběžné zápisy
Se souběžnými operacemi zápisu opravdu vše, co můžete udělat, je rozdělit aktualizaci na kousky. Nemůžete to udělat v jedné transakci, protože zámky se uvolní až na konci transakce.
Mohli byste používat dblink , který může spouštět nezávislé transakce na jiné databázi, včetně sebe sama. Tímto způsobem byste to mohli udělat vše v jediném DO
příkaz nebo funkce plpgsql se smyčkou. Zde je volně související odpověď s dalšími informacemi o dblink:
- Zrušte nebo vytvořte databázi z uložené procedury v PostgreSQL
Váš přístup pomocí kurzorů
Kurzor uvnitř funkce vám nic nekoupí . Jakákoli funkce je automaticky uzavřena v transakci a všechny zámky se uvolní až na konci transakce. I když jste použili CLOSE cursor
(což vy ne) uvolnilo by to pouze některé zdroje, ale ne uvolnit získané zámky na stole. Cituji manuál:
CLOSE
zavře portál pod otevřeným kurzorem. Toho lze použít k uvolnění zdrojů před koncem transakce nebo k uvolnění proměnné kurzoru, aby ji bylo možné znovu otevřít.
Budete muset spustit samostatně transakce nebo (ab)použijte dblink, který to udělá za vás.