Antipatterns PostgreSQL: cumbattimentu di l'orde di "morti"

I peculiarità di i miccanismi interni di PostgreSQL permettenu di esse assai veloce in certi situazioni è "micca assai veloce" in altri. Oghje ci concentreremu nantu à un esempiu classicu di un cunflittu trà cumu funziona un DBMS è ciò chì u sviluppatore face cun ellu - UPDATE vs principii MVCC.

Breve storia da grande articulu:

Quandu una fila hè mudificata da un cumandamentu UPDATE, duie operazioni sò veramente realizate: DELETE è INSERT. IN versione attuale di a stringa xmax hè stabilitu uguale à u numeru di a transazzione chì hà realizatu l'UPDATE. Allora hè creatu una nova versione a stessa linea; u so valore xmin coincide cù u valore xmax di a versione precedente.

Qualchì tempu dopu à sta transazzione hè cumpleta, a versione vechja o nova, secondu COMMIT/ROOLBACK, sarà ricunnisciutu "morti" (tuple morti) quandu passa VACUUM secondu a tavula è sbulicatu.

Antipatterns PostgreSQL: cumbattimentu di l'orde di "morti"

Ma questu ùn succede micca subitu, ma i prublemi cù i "morti" ponu esse acquistati assai rapidamente - cù ripetuti o aghjurnamentu di massa di i registri in una grande tavola, è un pocu dopu vi scontru a listessa situazione VACUUM ùn puderà aiutà.

# 1: Mi piace à spustà

Diciamu chì u vostru metudu travaglia nantu à a logica di l'affari, è di colpu si capisce chì ci vole à aghjurnà u campu X in qualchì record:

UPDATE tbl SET X = <newX> WHERE pk = $1;

Allora, cum'è l'esekzione avanza, risulta chì u campu Y deve ancu esse aghjurnatu:

UPDATE tbl SET Y = <newY> WHERE pk = $1;

... è dopu ancu Z - perchè perde u tempu in trifles?

UPDATE tbl SET Z = <newZ> WHERE pk = $1;

Quante versioni di stu record avemu avà in a basa di dati ? Iè, 4 pezzi! Di questi, unu hè pertinenti, è 3 duverà esse puliti dopu à voi da [auto]VACUUM.

Ùn fate micca cusì! Aduprà aghjurnà tutti i campi in una dumanda - quasi sempre a logica di u metudu pò esse cambiatu cusì:

UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;

# 2: L'usu hè distintu da, Luke!

Allora, avete sempre vulutu aghjurnà assai, assai dischi in una tavula (durante l'usu di un script o cunvertitore, per esempiu). È qualcosa cum'è questu vola in u script:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;

Una dumanda apprussimatamente in questa forma si trova abbastanza spessu è quasi sempre micca per riempie un novu campu vacante, ma per correggerà alcuni errori in i dati. À u listessu tempu, ella stessu a correttezza di e dati esistenti ùn hè micca cunsideratu à tutti - ma in vanu ! Questu hè, u discu hè riscritto, ancu s'ellu cuntene esattamente ciò chì si vulia - ma perchè? Fixemu lu:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;

Parechje persone ùn sò micca cuscenti di l'esistenza di un operatore cusì maravigliu, cusì quì hè un fogliu di truccu IS DISTINCT FROM è altri operatori lògichi per aiutà:
Antipatterns PostgreSQL: cumbattimentu di l'orde di "morti"
... è un pocu nantu à l'operazioni cumplessi ROW()- espressioni :
Antipatterns PostgreSQL: cumbattimentu di l'orde di "morti"

# 3: Ricunnoscu u mo caru da ... bluccatu

sò lanciati dui prucessi paralleli identichi, ognunu di quali prova di marcà l'entrata chì hè "in corso":

UPDATE tbl SET processing = TRUE WHERE pk = $1;

Ancu s'è sti prucessi facenu veramente cose indipindenti di l'altri, ma in u stessu ID, u secondu cliente serà "bloccatu" nantu à sta dumanda finu à chì a prima transazzione hè cumpleta.

Soluzione # 1: u compitu hè ridutta à u precedente

Aghjunghjemu solu di novu IS DISTINCT FROM:

UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;

In questa forma, a seconda dumanda simpliciamente ùn cambierà nunda in a basa di dati, tuttu hè digià cum'è deve esse - per quessa, u bloccu ùn succede micca. Dopu, processemu u fattu di "micca truvà" u record in l'algoritmu applicatu.

Soluzione # 2: serrature di cunsigliu

Un grande tema per un articulu separatu, in quale pudete leghje metudi d'applicazione è "rake" di ubligatoriu di ricumandazione.

Soluzione # 3: chiama stupidu

Ma questu hè esattamente ciò chì deve accade à voi travagliu simultanea cù u listessu record? O avete messu cù l'algoritmi per chjamà a logica di l'affari da u cliente, per esempiu? E se ci pensate?...

Source: www.habr.com

Add a comment