PostgreSQL Antipatterns: pugnae multitudinem "mortuum"

Proprietates machinae internae PostgreSQL sinunt eam in quibusdam adiunctis velocissimam esse ac "non valde celerem" in aliis. Hodie in classico exemplo certaminis intendunt quomodo opera DBMS et quid cum ea facit elit. UPDATE nobis MVCC principiis.

Brevis historia e magnus articulus:

Cum ordo per mandatum UPDATE modificatur, duae operationes actu peraguntur: DELETE et INSERT. IN' de emendatione filum xmax aequatur numero rei gerendae UPDATE. Tum creatur novam versionem eadem linea; eius valor xmin coincidit cum valore xmax prioris versionis.

Aliquanto post hac transactione confecta, versio vetus vel nova, secundum COMMIT/ROOLBACKCognoscetur "Mortuus" (tuples mortuus) quando transiens VACUUM iuxta mensam emissam.

PostgreSQL Antipatterns: pugnae multitudinem "mortuum"

Sed hoc non statim fiet, sed problemata "mortuorum" celerrime acquiri possunt - cum iteratis seu molem renovatio monumentorum in magna mensa, et paulo post eundem casum occurres VACUUM adiuvare non poterit.

# I: Ego amo eam movere

Dicamus modum tuum in logica negotiatione laborantem, et subito percipit necessarium esse ad renovandum agrum in aliquo monumento;

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

Deinde, procedente executione, evenit ut campus Y quoque sit ametur;

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

... et tum etiam Z. Quid moror in nugis?

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

Quot versiones huius monumenti nunc habemus in database? Yep, 4 pieces! E quibus unum pertinet, et 3 post te per VACUUM mundari debebit.

Nolite hoc modo facere! Usus adaequationis omnes agros in unam petitionem β€” fere semper logica methodi sic mutari potest:

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

#2: Usus distinctus est ab Luc.

So, adhuc volebam update multis, multis monumentis in mensa (per usum scriptionis vel convertentis, exempli gratia). Et aliquid simile volat in scriptura;

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

Exhibitio in hac fere forma saepe saepius ac fere semper occurrit novum agrum non explere sed aliquos errores in notitia corrigere. Eodem tempore, ipsa rectitudo esse data non ratio omnino - Sed frustra! Hoc est, recordum rescriptum est, etiam si quid prorsus continebat, quod voluit, sed quare? Sit scriptor reficere;

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

Multi homines non sciunt exsistentiam tanti operatoris mirabilis, ergo hic linteum seductorem est IS DISTINCT FROM et alios operatores logicos adiuvantes;
PostgreSQL Antipatterns: pugnae multitudinem "mortuum"
... et pauca de operationibus in complexu ROW()-expressions:
PostgreSQL Antipatterns: pugnae multitudinem "mortuum"

#3: Agnosco corculum meum ab ... obturans

sunt launched Duo identical processibus parallelisquorum unumquodque ingressum notare conatur quod est in progressu;

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

Etiamsi hi processus res ab invicem independentes actu agunt, sed in eodem ID, secundus client "clausus" erit ab hac rogatione donec prima transactio peracta est.

Solutio in decimo: negotium reducitur ad priorem

Lets iustus addere illud IS DISTINCT FROM:

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

In hac forma, altera postulatio simpliciter nihil mutabit in datorum, omnia iam ut oportet - ergo interclusio non occurret. Deinde processimus recordum "non inveniendi" in algorithmo apposito.

Solutio in decimo: advisory cincinnos

Magnus locus pro articulo separato, in quo legere potes modos applicationis et "rase" commendaticiis interclusio.

Solutio in decimo: Stultus vocat

Sed hoc prorsus quid tibi eveniat simul cum eodem record? An tatam fecisti cum algorithmis ad logicam negotiandi in parte clientis, exempli gratia? Et si cogitas?..

Source: www.habr.com