Mae hynodrwydd mecanweithiau mewnol PostgreSQL yn caniatáu iddo fod yn gyflym iawn mewn rhai sefyllfaoedd a “ddim yn gyflym iawn” mewn eraill. Heddiw, byddwn yn canolbwyntio ar enghraifft glasurol o wrthdaro rhwng sut mae DBMS yn gweithio a'r hyn y mae'r datblygwr yn ei wneud ag ef - DIWEDDARIAD yn erbyn egwyddorion MVCC.
Stori fer gan
Pan fydd rhes yn cael ei haddasu gan orchymyn DIWEDDARIAD, mae dau weithrediad yn cael eu perfformio mewn gwirionedd: DILEU a INSERT. YN fersiwn gyfredol y llinyn xmax wedi'i osod yn hafal i nifer y trafodiad a gyflawnodd y DIWEDDARIAD. Yna mae'n cael ei greu fersiwn newydd yr un llinell; mae ei werth xmin yn cyd-fynd â gwerth xmax y fersiwn flaenorol.
Beth amser ar ôl i'r trafodiad hwn gael ei gwblhau, bydd yr hen fersiwn neu'r fersiwn newydd, yn dibynnu ar COMMIT/ROOLBACK
, bydd yn cael ei gydnabod "marw" (tuples marw) wrth basio VACUUM
yn ol y bwrdd a gliriwyd.
Ond ni fydd hyn yn digwydd ar unwaith, ond gellir cael problemau gyda'r “marw” yn gyflym iawn - gydag ailadrodd neu
#1: Rwy'n Hoffi Ei Symud
Gadewch i ni ddweud bod eich dull yn gweithio ar resymeg busnes, ac yn sydyn mae'n sylweddoli y byddai angen diweddaru maes X mewn rhyw gofnod:
UPDATE tbl SET X = <newX> WHERE pk = $1;
Yna, wrth i'r gweithredu fynd rhagddo, mae'n ymddangos y dylid diweddaru maes Y hefyd:
UPDATE tbl SET Y = <newY> WHERE pk = $1;
... ac yna hefyd Z - pam gwastraffu amser ar dreifflau?
UPDATE tbl SET Z = <newZ> WHERE pk = $1;
Sawl fersiwn o'r cofnod hwn sydd gennym bellach yn y gronfa ddata? Ie, 4 darn! O'r rhain, mae un yn berthnasol, a bydd yn rhaid glanhau 3 ar eich ôl gan [awto] VACUUM.
Peidiwch â'i wneud fel hyn! Defnydd diweddaru pob maes mewn un cais — bron bob amser gellir newid rhesymeg y dull fel hyn:
UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;
#2: MAE DEFNYDD YN WAHANOL, Luc!
Felly, roeddech chi eisiau o hyd
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;
Mae cais o gwmpas y ffurflen hon yn digwydd yn eithaf aml a bron bob amser i beidio â llenwi maes newydd gwag, ond i gywiro rhai gwallau yn y data. Ar yr un pryd, hi ei hun nid yw cywirdeb y data presennol yn cael ei ystyried o gwbl - ond yn ofer! Hynny yw, mae'r cofnod yn cael ei ailysgrifennu, hyd yn oed os oedd yn cynnwys yn union beth oedd ei eisiau - ond pam? Gadewch i ni ei drwsio:
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;
Nid yw llawer o bobl yn ymwybodol o fodolaeth gweithredwr mor wych, felly dyma daflen twyllo ymlaen IS DISTINCT FROM
a gweithredwyr rhesymegol eraill i helpu:
... ac ychydig am lawdriniaethau ar gymhleth ROW()
- ymadroddion:
#3: Rwy'n adnabod fy nghariad trwy... rwystro
yn cael eu lansio dwy broses gyfochrog union yr un fath, pob un yn ceisio nodi’r cofnod ei fod “ar y gweill”:
UPDATE tbl SET processing = TRUE WHERE pk = $1;
Hyd yn oed os yw'r prosesau hyn mewn gwirionedd yn gwneud pethau'n annibynnol ar ei gilydd, ond o fewn yr un ID, bydd yr ail gleient yn cael ei “gloi” ar y cais hwn nes bod y trafodiad cyntaf wedi'i gwblhau.
Datrysiad # 1: gostyngir y dasg i'r un blaenorol
Gadewch i ni ei ychwanegu eto IS DISTINCT FROM
:
UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;
Yn y ffurflen hon, ni fydd yr ail gais yn newid unrhyw beth yn y gronfa ddata, mae popeth eisoes fel y dylai fod - felly, ni fydd blocio yn digwydd. Nesaf, rydym yn prosesu'r ffaith "peidio â dod o hyd i" y cofnod yn yr algorithm cymhwysol.
Datrysiad # 2: cloeon cynghorol
Pwnc mawr ar gyfer erthygl ar wahân, y gallwch chi ddarllen amdano
Datrysiad # 3: galwadau gwirion
Ond dyma'n union beth ddylai ddigwydd i chi gwaith ar yr un pryd gyda'r un cofnod? Neu a wnaethoch chi lanast gyda'r algorithmau ar gyfer galw rhesymeg busnes ar ochr y cleient, er enghraifft? Ac os ydych chi'n meddwl amdano? ...
Ffynhonnell: hab.com