ΠΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ ΡΠ°Π±ΠΎΡΡ Π²Π½ΡΡΡΠ΅Π½Π½ΠΈΡ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠΎΠ² PostgreSQL ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ Π΅ΠΌΡ Π±ΡΡΡ ΠΎΡΠ΅Π½Ρ Π±ΡΡΡΡΡΠΌ Π² ΠΎΠ΄Π½ΠΈΡ ΡΠΈΡΡΠ°ΡΠΈΡ ΠΈ Β«Π½Π΅ ΠΎΡΠ΅Π½ΡΒ» Π² Π΄ΡΡΠ³ΠΈΡ . Π‘Π΅Π³ΠΎΠ΄Π½Ρ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΠΌΡΡ Π½Π° ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ΅ΠΌ, ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π‘Π£ΠΠ ΠΈ ΡΠ΅ΠΌ, ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ Ρ Π½Π΅ΠΉ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ β UPDATE vs ΠΏΡΠΈΠ½ΡΠΈΠΏΡ MVCC.
ΠΡΠ°ΡΠΊΠΎ ΡΡΠΆΠ΅Ρ ΠΈΠ·
ΠΠΎΠ³Π΄Π° ΡΡΡΠΎΠΊΠ° ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ UPDATE, ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Π΄Π²Π΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ: DELETE ΠΈ INSERT. Π ΡΠ΅ΠΊΡΡΠ΅ΠΉ Π²Π΅ΡΡΠΈΠΈ ΡΡΡΠΎΠΊΠΈ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ xmax, ΡΠ°Π²Π½ΡΠΉ Π½ΠΎΠΌΠ΅ΡΡ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΈ, Π²ΡΠΏΠΎΠ»Π½ΠΈΠ²ΡΠ΅ΠΉ UPDATE. ΠΠ°ΡΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π½ΠΎΠ²Π°Ρ Π²Π΅ΡΡΠΈΡ ΡΠΎΠΉ ΠΆΠ΅ ΡΡΡΠΎΠΊΠΈ; Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ xmin Ρ Π½Π΅Π΅ ΡΠΎΠ²ΠΏΠ°Π΄Π°Π΅Ρ Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ xmax ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ Π²Π΅ΡΡΠΈΠΈ.
Π§Π΅ΡΠ΅Π· ΠΊΠ°ΠΊΠΎΠ΅-ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΏΠΎΡΠ»Π΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΡΡΠΎΠΉ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΈ ΡΡΠ°ΡΠ°Ρ ΠΈΠ»ΠΈ Π½ΠΎΠ²Π°Ρ Π²Π΅ΡΡΠΈΠΈ, Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ COMMIT/ROOLBACK
, Π±ΡΠ΄ΡΡ ΠΏΡΠΈΠ·Π½Π°Π½Ρ Β«ΠΌΠ΅ΡΡΠ²ΡΠΌΠΈΒ» (dead tuples) ΠΏΡΠΈ ΠΏΡΠΎΡ
ΠΎΠ΄Π΅ VACUUM
ΠΏΠΎ ΡΠ°Π±Π»ΠΈΡΠ΅ ΠΈ Π·Π°ΡΠΈΡΠ΅Π½Ρ.
ΠΠΎ ΡΡΠΎ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ Π΄Π°Π»Π΅ΠΊΠΎ Π½Π΅ ΡΡΠ°Π·Ρ, Π° Π²ΠΎΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Ρ Β«ΠΌΠ΅ΡΡΠ²Π΅ΡΠ°ΠΌΠΈΒ» ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΆΠΈΡΡ ΠΎΡΠ΅Π½Ρ Π±ΡΡΡΡΠΎ β ΠΏΡΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡΠ°ΡΠ½ΠΎΠΌ ΠΈΠ»ΠΈ
#1: I Like To Move It
ΠΠΎΠΏΡΡΡΠΈΠΌ, Π²Π°Ρ ΠΌΠ΅ΡΠΎΠ΄ Π½Π° Π±ΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΠ΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΠ΅Π±Π΅, ΠΈ Π²Π΄ΡΡΠ³ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ, ΡΡΠΎ Π½Π°Π΄ΠΎ Π±Ρ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ ΠΏΠΎΠ»Π΅ X Π² ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ Π·Π°ΠΏΠΈΡΠΈ:
UPDATE tbl SET X = <newX> WHERE pk = $1;
ΠΠΎΡΠΎΠΌ, ΠΏΠΎ Ρ ΠΎΠ΄Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ, Π²ΡΡΡΠ½ΡΠ΅Ρ, ΡΡΠΎ ΠΏΠΎΠ»Π΅ Y Π½Π°Π΄ΠΎ Π±Ρ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ ΡΠΎΠΆΠ΅:
UPDATE tbl SET Y = <newY> WHERE pk = $1;
β¦ Π° ΠΏΠΎΡΠΎΠΌ Π΅ΡΠ΅ ΠΈ Z β ΡΠ΅Π³ΠΎ ΡΠΆ ΠΌΠ΅Π»ΠΎΡΠΈΡΡΡΡ-ΡΠΎ?
UPDATE tbl SET Z = <newZ> WHERE pk = $1;
Π‘ΠΊΠΎΠ»ΡΠΊΠΎ Π²Π΅ΡΡΠΈΠΉ ΡΡΠΎΠΉ Π·Π°ΠΏΠΈΡΠΈ ΡΠ΅ΠΏΠ΅ΡΡ ΠΈΠΌΠ΅Π΅ΠΌ Π² Π±Π°Π·Π΅? ΠΠ³Π°, 4 ΡΡΡΠΊΠΈ! ΠΠ· Π½ΠΈΡ ΠΎΠ΄Π½Π° Π°ΠΊΡΡΠ°Π»ΡΠ½Π°Ρ, Π° 3 Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΠ΄Π΅Ρ ΠΏΡΠΈΠ±ΡΠ°ΡΡ Π·Π° Π²Π°ΠΌΠΈ [auto]VACUUM.
ΠΠ΅ Π½Π°Π΄ΠΎ ΡΠ°ΠΊ! ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π²ΡΠ΅Ρ ΠΏΠΎΠ»Π΅ΠΉ Π·Π° ΠΎΠ΄ΠΈΠ½ Π·Π°ΠΏΡΠΎΡ β ΠΏΠΎΡΡΠΈ Π²ΡΠ΅Π³Π΄Π° Π»ΠΎΠ³ΠΈΠΊΡ ΡΠ°Π±ΠΎΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°ΠΊ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ:
UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;
#2: Use IS DISTINCT FROM, Luke!
ΠΡΠ°ΠΊ, Π²Π°ΠΌ Π²ΡΠ΅-ΡΠ°ΠΊΠΈ Π·Π°Ρ
ΠΎΡΠ΅Π»ΠΎΡΡ
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;
ΠΡΠΈΠΌΠ΅ΡΠ½ΠΎ Π² ΡΠ°ΠΊΠΎΠΌ Π²ΠΈΠ΄Π΅ Π·Π°ΠΏΡΠΎΡ Π²ΡΡΡΠ΅ΡΠ°Π΅ΡΡΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΡΠ°ΡΡΠΎ ΠΈ ΠΏΠΎΡΡΠΈ Π²ΡΠ΅Π³Π΄Π° Π½Π΅ Π΄Π»Ρ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΡΡΡΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»Ρ, Π° Π΄Π»Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠΈΠΈ ΠΊΠ°ΠΊΠΈΡ -ΡΠΎ ΠΎΡΠΈΠ±ΠΎΠΊ Π² Π΄Π°Π½Π½ΡΡ . ΠΡΠΈ ΡΡΠΎΠΌ ΡΠ°ΠΌΠ° ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΡΡΡ ΡΠΆΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΡ Π΄Π°Π½Π½ΡΡ Π²ΠΎΠΎΠ±ΡΠ΅ Π½Π΅ ΡΡΠΈΡΡΠ²Π°Π΅ΡΡΡ β Π° Π·ΡΡ! Π’ΠΎ Π΅ΡΡΡ Π·Π°ΠΏΠΈΡΡ ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ, Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ ΡΠ°ΠΌ Π»Π΅ΠΆΠ°Π»ΠΎ ΡΠΎΠ²Π½ΠΎ ΡΠΎ, ΡΡΠΎ ΠΈ Ρ ΠΎΡΠ΅Π»ΠΎΡΡ β Π° Π·Π°ΡΠ΅ΠΌ? ΠΠΎΠΏΡΠ°Π²ΠΈΠΌ:
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;
ΠΠ½ΠΎΠ³ΠΈΠ΅ Π½Π΅ Π² ΠΊΡΡΡΠ΅ ΠΏΡΠΎ ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ°ΠΊΠΎΠ³ΠΎ Π·Π°ΠΌΠ΅ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ°, ΠΏΠΎΡΡΠΎΠΌΡ Π²ΠΎΡ ΡΠΏΠ°ΡΠ³Π°Π»ΠΊΠ° ΠΏΠΎ IS DISTINCT FROM
ΠΈ Π΄ΡΡΠ³ΠΈΠΌ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠΌ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ°ΠΌ Π² ΠΏΠΎΠΌΠΎΡΡ:
β¦ ΠΈ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Π½Π°Π΄ ΡΠ»ΠΎΠΆΠ½ΡΠΌΠΈ ROW()
-Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡΠΌΠΈ:
#3: Π Ρ ΠΌΠΈΠ»ΠΎΠ³ΠΎ ΡΠ·Π½Π°Ρ ΠΏΠΎβ¦ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ΅
ΠΠ°ΠΏΡΡΠΊΠ°ΡΡΡΡ Π΄Π²Π° ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΡΡ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠ°, ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· ΠΊΠΎΡΠΎΡΡΡ ΠΏΡΡΠ°Π΅ΡΡΡ ΠΏΠΎΠΌΠ΅ΡΠΈΡΡ Π½Π° Π·Π°ΠΏΠΈΡΠΈ, ΡΡΠΎ ΠΎΠ½Π° Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Β«Π² ΡΠ°Π±ΠΎΡΠ΅Β»:
UPDATE tbl SET processing = TRUE WHERE pk = $1;
ΠΠ°ΠΆΠ΅ Π΅ΡΠ»ΠΈ ΡΡΠΈ ΠΏΡΠΎΡΠ΅ΡΡΡ ΠΏΡΠ΅Π΄ΠΌΠ΅ΡΠ½ΠΎ Π΄Π΅Π»Π°ΡΡ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΡΠ΅ Π΄ΡΡΠ³ ΠΎΡ Π΄ΡΡΠ³Π° Π²Π΅ΡΠΈ, Π½ΠΎ Π² ΡΠ°ΠΌΠΊΠ°Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ID, Π½Π° ΡΡΠΎΠΌ Π·Π°ΠΏΡΠΎΡΠ΅ Π²ΡΠΎΡΠΎΠΉ ΠΊΠ»ΠΈΠ΅Π½Ρ Β«Π·Π°Π»ΠΎΡΠΈΡΡΡΒ», ΠΏΠΎΠΊΠ° Π½Π΅ Π·Π°ΠΊΠΎΠ½ΡΠΈΡΡΡ ΠΏΠ΅ΡΠ²Π°Ρ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΡ.
Π Π΅ΡΠ΅Π½ΠΈΠ΅ β1: Π·Π°Π΄Π°ΡΠ° ΡΠ²Π΅Π΄Π΅Π½Π° ΠΊ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ
ΠΡΠΎΡΡΠΎ ΡΠ½ΠΎΠ²Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ IS DISTINCT FROM
:
UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;
Π ΡΠ°ΠΊΠΎΠΌ Π²ΠΈΠ΄Π΅ Π²ΡΠΎΡΠΎΠΉ Π·Π°ΠΏΡΠΎΡ ΠΏΡΠΎΡΡΠΎ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΠΌΠ΅Π½ΡΡΡ Π² Π±Π°Π·Π΅, ΡΠ°ΠΌ ΠΈ ΡΠ°ΠΊ ΡΠΆΠ΅ Β«Π²ΡΠ΅ ΠΊΠ°ΠΊ Π½Π°Π΄ΠΎΒ» β ΠΏΠΎΡΡΠΎΠΌΡ ΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ. ΠΠ°Π»ΡΡΠ΅ ΡΠ°ΠΊΡ Β«Π½Π΅Π½Π°Ρ ΠΎΠΆΠ΄Π΅Π½ΠΈΡΒ» Π·Π°ΠΏΠΈΡΠΈ ΡΠΆΠ΅ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌ Π² ΠΏΡΠΈΠΊΠ»Π°Π΄Π½ΠΎΠΌ Π°Π»Π³ΠΎΡΠΈΡΠΌΠ΅.
Π Π΅ΡΠ΅Π½ΠΈΠ΅ β2: advisory locks
ΠΠΎΠ»ΡΡΠ°Ρ ΡΠ΅ΠΌΠ° Π΄Π»Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠΉ ΡΡΠ°ΡΡΠΈ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΈΡΠ°ΡΡ ΠΏΡΠΎ
Π Π΅ΡΠ΅Π½ΠΈΠ΅ β3: Π±Π΅Π·[Π΄]ΡΠΌΠ½ΡΠ΅ Π²ΡΠ·ΠΎΠ²Ρ
Π Π²ΠΎΡ ΡΠΎΡΠ½ΠΎ-ΡΠΎΡΠ½ΠΎ Ρ Π²Π°Ρ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΡΠ°Π±ΠΎΡΠ° Ρ ΠΎΠ΄Π½ΠΎΠΉ ΠΈ ΡΠΎΠΉ ΠΆΠ΅ Π·Π°ΠΏΠΈΡΡΡ? ΠΠ»ΠΈ Π²Ρ Π²ΡΠ΅-ΡΠ°ΠΊΠΈ Π½Π°ΠΊΠΎΡΡΡΠΈΠ»ΠΈ Ρ Π°Π»Π³ΠΎΡΠΈΡΠΌΠ°ΠΌΠΈ Π²ΡΠ·ΠΎΠ²ΠΎΠ² Π±ΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΠΈ ΡΠΎ ΡΡΠΎΡΠΎΠ½Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ? Π Π΅ΡΠ»ΠΈ ΠΏΠΎΠ΄ΡΠΌΠ°ΡΡ?..
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com