PostgreSQL АнтипатСрни: промСнямС Π΄Π°Π½Π½ΠΈ Π±Π΅Π· Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈ

Π Π°Π½ΠΎ ΠΈΠ»ΠΈ късно ΠΌΠ½ΠΎΠ³ΠΎ Ρ…ΠΎΡ€Π° сС ΡΠ±Π»ΡŠΡΠΊΠ²Π°Ρ‚ с нСобходимостта ΠΎΡ‚ масови ΠΊΠΎΡ€Π΅ΠΊΡ†ΠΈΠΈ Π² записитС Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π°. Аз Π²Π΅Ρ‡Π΅ Ρ€Π°Π·ΠΊΠ°Π·Π²Π°Ρ… ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅, Π° ΠΊΠ°ΠΊ β€” ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅ Π΄Π° Π½Π΅ сС ΠΏΡ€Π°Π²ΠΈ. ДнСс Ρ‰Π΅ говоря Π·Π° втория аспСкт Π½Π° масовото ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ β€” сработванСто Π½Π° Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈΡ‚Π΅.

НапримСр, Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π°, Π² която Π²ΠΈ трябва Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Π½Π΅Ρ‰ΠΎ, ΠΈΠΌΠ° Π·Π»ΠΎΠ²Π΅Ρ‰ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ ON UPDATE, ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»Ρ всички ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² някакви Π°Π³Ρ€Π΅Π³Π°Ρ‚ΠΈ. А Π½Π° вас Π²ΠΈ трябва всичко Π΄Π° сС ΠΎΠ±Π½ΠΎΠ²ΠΈ (Π΄Π° Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°Ρ‚Π΅ Π½ΠΎΠ²ΠΎ ΠΏΠΎΠ»Π΅) Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° Π΄Π΅Π»ΠΈΠΊΠ°Ρ‚Π½ΠΎ, Ρ‡Π΅ Ρ‚Π΅Π·ΠΈ Π°Π³Ρ€Π΅Π³Π°Ρ‚ΠΈ Π΄Π° Π½Π΅ Π±ΡŠΠ΄Π°Ρ‚ засягани.

НСка просто Π΄Π΅Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π°ΠΌΠ΅ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈΡ‚Π΅!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
  UPDATE ...; -- Ρ‚ΡƒΠΊ дълго-дълго
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

БобствСнно, Ρ‚ΡƒΠΊ ΠΈ всичко β€” всичко Π²Π΅Ρ‡Π΅ висяло.

Π—Π°Ρ‰ΠΎΡ‚ΠΎ ALTER TABLE Π½Π°Π»Π°Π³Π° AccessExclusive-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°Ρ‚Π°, ΠΏΠΎΠ΄ която Π½ΠΈΠΊΠΎΠΉ ΡΡŠΠΏΠΎΡΡ‚Π°Π²ΡΡ‰ ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎ, Π΄ΠΎΡ€ΠΈ прост SELECT, Π½ΠΈΡ‰ΠΎ ΠΎΡ‚ Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° няма Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅. ВоСст, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Ρ‚Π°Π·ΠΈ транзакция Π½Π΅ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡ΠΈ, всички ΠΆΠ΅Π»Π°Π΅Ρ‰ΠΈ, Π΄ΠΎΡ€ΠΈ β€žΠΏΡ€ΠΎΡΡ‚ΠΎ Π΄Π° ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π°Ρ‚β€œ, Ρ‰Π΅ Ρ‡Π°ΠΊΠ°Ρ‚. А Π½ΠΈΠ΅ ΠΏΠΎΠΌΠ½ΠΈΠΌ, Ρ‡Π΅ ΠΠšΠ’Π£ΠΠ›Π˜Π—Π˜Π ΠΠ™ ΠΈΠΌΠ°ΠΌΠ΅ мнооого…

Π’ΠΎΠ³Π°Π²Π° Π΄Π° Π΄Π΅Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π°ΠΌΠ΅ Π±ΡŠΡ€Π·ΠΎ, слСд Ρ‚ΠΎΠ²Π° Π±ΡŠΡ€Π·ΠΎ Π΄Π° Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
COMMIT;

UPDATE ...;

BEGIN;
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

Π’ΡƒΠΊ ситуацията Π²Π΅Ρ‡Π΅ Π΅ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π°, Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π½Π° ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°Π½Π΅ Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ. Но Π΄Π²Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° развалят цялата красота:

  • ALTER TABLE Π’ΠΎΠΉ самият Ρ‡Π°ΠΊΠ° всички Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π°, Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Π΄ΡŠΠ»Π³ΠΈΡ‚Π΅ SELECT
  • Π”ΠΎΠΊΠ°Ρ‚ΠΎ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΡŠΡ‚ Π΅ ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½, всяка промяна Π² Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π°, Π΄ΠΎΡ€ΠΈ Π½Π΅ Π½Π°ΡˆΠ°Ρ‚Π°, Ρ‰Π΅ β€žΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ ΠΏΠΎΠΊΡ€Π°ΠΉβ€œ. И Π² Π°Π³Ρ€Π΅Π³Π°Ρ‚ΠΈΡ‚Π΅ ΠΏΠΎ никакъв Π½Π°Ρ‡ΠΈΠ½ няма Π΄Π° ΠΏΠΎΠΏΠ°Π΄Π½Π΅, ΠΌΠ°ΠΊΠ°Ρ€ Ρ‡Π΅ трябва. Π‘Π΅Π΄Π°!

Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈΡ‚Π΅ Π½Π° сСсията

И Ρ‚Π°ΠΊΠ°, Π½Π° ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈΡ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ сС Π½Π°Ρ‚ΡŠΠΊΠ½Π°Ρ…ΠΌΠ΅ Π½Π° принципния ΠΌΠΎΠΌΠ΅Π½Ρ‚ β€” трябва някак Π΄Π° Π½Π°ΡƒΡ‡ΠΈΠΌ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€Π° Π΄Π° Ρ€Π°Π·Π»ΠΈΡ‡Π°Π²Π° β€žΠ½Π°ΡˆΠΈΡ‚Π΅β€œ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° ΠΎΡ‚ β€žΠ½Π΅ Π½Π°ΡˆΠΈΡ‚Π΅β€œ. β€žΠΠ°ΡˆΠΈΡ‚Π΅β€œ Π΄Π° ΠΌΠΈΠ½Π°Π²Π°Ρ‚ ΠΊΠ°ΠΊΡ‚ΠΎ са, Π° Π½Π° β€žΠ½Π΅ Π½Π°ΡˆΠΈΡ‚Π΅β€œ β€” Π΄Π° сработват. Π—Π° Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° сСсията.

session_replication_role

Π§Π΅Ρ‚Π΅ΠΌ ΠΌΠ°Π½ΡƒΠ°Π»:

На ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° Π½Π° сработванС Π½Π° Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈΡ‚Π΅ ΡΡŠΡ‰ΠΎ влияС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ‚Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° session_replication_role. Π’ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ‚Π΅ Π±Π΅Π· Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ указания (ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅) Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈ Ρ‰Π΅ сработват, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ролята Π½Π° рСпликация Π΅ β€” β€žoriginβ€œ (ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅) ΠΈΠ»ΠΈ β€žlocalβ€œ. Π’Ρ€ΠΈΠ³Π΅Ρ€ΠΈ, Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈ с ΡƒΠΊΠ°Π·Π²Π°Π½Π΅ ENABLE REPLICA, Ρ‰Π΅ сработват само Π°ΠΊΠΎ тСкущият Ρ€Π΅ΠΆΠΈΠΌ Π½Π° сСсия Π΅ β€žΡ€Π΅ΠΏΠ»ΠΈΠΊΠ°β€œ, Π° Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈ, Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈ с ΡƒΠΊΠ°Π·Π²Π°Π½Π΅ ENABLE ALWAYS, Ρ‰Π΅ сработват нСзависимо ΠΎΡ‚ тСкущия Ρ€Π΅ΠΆΠΈΠΌ Π½Π° рСпликация.

ОсобСно ΠΏΠΎΠ΄Ρ‡Π΅Ρ€Ρ‚Π°Π²Π°ΠΌ, Ρ‡Π΅ настройката сС отнася Π½Π΅ към всички-всички навСднъТ, ΠΊΠ°ΠΊΡ‚ΠΎ ALTER TABLE, Π° само ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ само с нашия ΠΎΡ‚Π΄Π΅Π»Π΅Π½ спСциалСн ΠΊΠΎΠ½Π΅ΠΊΡ‚ΠΎΡ€. Π’ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, Π·Π° Π΄Π° Π½Π΅ сС задСйстват Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ½ΠΈ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈ:

SET session_replication_role = replica; -- ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈΡ‚Π΅
UPDATE ...;
SET session_replication_role = DEFAULT; -- Π²ΡŠΡ€Π½Π°Ρ‚ΠΈ Π² ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎΡ‚ΠΎ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅

УсловиС Π² Ρ‚Ρ€ΠΈΠ³Π΅Ρ€Π°

Но ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½Π°Ρ‚Π° ΠΏΠΎ-Π³ΠΎΡ€Π΅ опция Ρ€Π°Π±ΠΎΡ‚ΠΈ Π·Π° всички Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈ навСднъТ (ΠΈΠ»ΠΈ трябва ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½ΠΎ Π΄Π° сС 'Π°Π»Ρ‚Π΅Ρ€ΠΈΡ€Π°Ρ‚' Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ΠΈΡ‚Π΅, ΠΊΠΎΠΈΡ‚ΠΎ Π½Π΅ искамС Π΄Π° Π΄Π΅Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π°ΠΌΠ΅). А Π°ΠΊΠΎ Π½ΠΈ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° 'ΠΈΠ·ΠΊΠ»ΡŽΡ‡ΠΈΠΌ' Π΅Π΄ΠΈΠ½ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π΅Π½ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€?

Π’ Ρ‚ΠΎΠ²Π° Π½ΠΈ ΠΏΠΎΠΌΠ°Π³Π° 'потрСбитСлска' ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° Π½Π° сСсията:

Π˜ΠΌΠ΅Π½Π°Ρ‚Π° Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΡ‚Π΅ Π½Π° Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΡΡ‚Π° сС записват ΠΏΠΎ слСдния Π½Π°Ρ‡ΠΈΠ½: ΠΈΠΌΠ΅ Π½Π° Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΠ΅, Ρ‚ΠΎΡ‡ΠΊΠ° ΠΈ слСд Ρ‚ΠΎΠ²Π° собствСно ΠΈΠΌΠ΅ Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€Π°, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° ΠΏΡŠΠ»Π½ΠΈΡ‚Π΅ ΠΈΠΌΠ΅Π½Π° Π½Π° ΠΎΠ±Π΅ΠΊΡ‚ΠΈ Π² SQL. НапримСр: plpgsql.variable_conflict.
Въй ΠΊΠ°Ρ‚ΠΎ Π½Π΅ систСмнитС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Π·Π°Π΄Π°Π΄Π΅Π½ΠΈ Π² процСси, ΠΊΠΎΠΈΡ‚ΠΎ Π½Π΅ Π·Π°Ρ€Π΅ΠΆΠ΄Π°Ρ‚ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ ΠΌΠΎΠ΄ΡƒΠ» Π½Π° Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΠ΅Ρ‚ΠΎ, PostgreSQL ΠΏΡ€ΠΈΠ΅ΠΌΠ° стойности Π·Π° всякакви ΠΈΠΌΠ΅Π½Π° с Π΄Π²Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°.

ΠŸΡŠΡ€Π²ΠΎ Π΄ΠΎΡ€Π°Π·Π²ΠΈΠ²Π°ΠΌΠ΅ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€Π°, Π³ΠΎΡ€Π΅-Π΄ΠΎΠ»Ρƒ Ρ‚Π°ΠΊΠ°:

BEGIN
    -- ΠΏΡ€ΠΎΡ†Π΅ΡΡŠΡ‚ Π½Π° ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€Π°Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡ€Π°Π²ΠΈ всичко
    IF current_setting('mycfg.my_table_convert_process') = 'TRUE' THEN
        IF TG_OP IN ('INSERT', 'UPDATE') THEN
            RETURN NEW;
        ELSE
            RETURN OLD;
        END IF;
    END IF;
...

ΠœΠ΅ΠΆΠ΄Ρƒ Π΄Ρ€ΡƒΠ³ΠΎΡ‚ΠΎ, Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° станС 'Π½Π° ΠΆΠΈΠ²ΠΎ', Π±Π΅Π· Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ, Ρ‡Ρ€Π΅Π· CREATE OR REPLACE Π·Π° Ρ‚Ρ€ΠΈΠ³Π΅Ρ€Π½Π°Ρ‚Π° функция. А слСд Ρ‚ΠΎΠ²Π° Π² спСциалния ΠΊΠΎΠ½Π΅ΠΊΡ‚ΠΎΡ€ Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ 'Π½Π°ΡˆΠ°Ρ‚Π°' ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°:


SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- Π²ΡŠΡ€Π½Π°Ρ‚ΠΈ Π² ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎΡ‚ΠΎ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅

Π—Π½Π°Π΅Ρ‚Π΅ Π»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ? Π‘ΠΏΠΎΠ΄Π΅Π»Π΅Ρ‚Π΅ Π² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡ‚Π΅.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster