PostgreSQL ์•ˆํ‹ฐํŒจํ„ด: ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์šฐํšŒํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ

์กฐ๋งŒ๊ฐ„ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ํ…Œ์ด๋ธ” ๋ ˆ์ฝ”๋“œ์—์„œ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋Œ€๊ทœ๋ชจ๋กœ ์ˆ˜์ •ํ•ด์•ผ ํ•  ํ•„์š”์„ฑ์— ์ง๋ฉดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๋ฏธ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋” ์ž˜ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋งํ•ด์ค˜, ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ป๊ฒŒ-ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ ๋Œ€๋Ÿ‰ ์—…๋ฐ์ดํŠธ์˜ ๋‘ ๋ฒˆ์งธ ์ธก๋ฉด์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ํŠธ๋ฆฌ๊ฑฐ ์ •๋ณด.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฌด์–ธ๊ฐ€๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ํ…Œ์ด๋ธ”์—์„œ ์•…์˜์ ์ธ ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ON UPDATE, ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ผ๋ถ€ ์ง‘๊ณ„๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋Ÿฌํ•œ ์ง‘๊ณ„๊ฐ€ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋„๋ก ๋ชจ๋“  ๊ฒƒ์„ ์‹ ์ค‘ํ•˜๊ฒŒ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ์ƒˆ ํ•„๋“œ ์ดˆ๊ธฐํ™”).

ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ์‹œ๋‹ค!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
  UPDATE ...; -- ั‚ัƒั‚ ะดะพะปะณะพ-ะดะพะปะณะพ
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

์‚ฌ์‹ค ๊ทธ๊ฒŒ ๋‹ค์•ผ - ๋ชจ๋“  ๊ฒƒ์ด ๊ฑธ๋ ค์žˆ๋‹ค.

๋•Œ๋ฌธ์— ALTER TABLE ๋ถ€๊ณผํ•˜๋‹ค ์•ก์„ธ์Šค ๋…์ - ๋‹จ์ˆœํ•œ ๊ฒƒ์ผ์ง€๋ผ๋„ ์•„๋ฌด๋„ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š” ์ž ๊ธˆ SELECT, ํ…Œ์ด๋ธ”์—์„œ ์•„๋ฌด ๊ฒƒ๋„ ์ฝ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ด ํŠธ๋žœ์žญ์…˜์ด ๋๋‚  ๋•Œ๊นŒ์ง€ "๊ทธ๋ƒฅ ์ฝ๊ธฐ"๋ผ๋„ ์›ํ•˜๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๊ธฐ๋‹ค๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค UPDATE ์šฐ๋ฆฌ๋Š” ๊ธด ...

๋นจ๋ฆฌ ๊ป๋‹ค๊ฐ€ ๋นจ๋ฆฌ ์ผœ์ž!

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

UPDATE ...;

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

์—ฌ๊ธฐ์„œ ์ƒํ™ฉ์€ ์ด๋ฏธ ๋” ์ข‹๊ณ  ๋Œ€๊ธฐ ์‹œ๊ฐ„์€ ํ›จ์”ฌ ์ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ๋งŒ์ด ๋ชจ๋“  ์•„๋ฆ„๋‹ค์›€์„ ๋ง์นฉ๋‹ˆ๋‹ค.

  • ALTER TABLE ๊ธด ์ž‘์—…์„ ํฌํ•จํ•˜์—ฌ ํ…Œ์ด๋ธ”์˜ ๋‹ค๋ฅธ ๋ชจ๋“  ์ž‘์—…์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. SELECT
  • ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๊บผ์ ธ ์žˆ๋Š” ๋™์•ˆ ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ "๋น„ํ–‰" ํ…Œ์ด๋ธ”์—, ์‹ฌ์ง€์–ด ์šฐ๋ฆฌ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ง‘๊ณ„์— ํฌํ•จ๋˜์–ด์•ผ ํ•˜์ง€๋งŒ ์ง‘๊ณ„์— ํฌํ•จ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ!

์„ธ์…˜ ๋ณ€์ˆ˜ ๊ด€๋ฆฌ

๋”ฐ๋ผ์„œ ์ด์ „ ๋ฒ„์ „์—์„œ ์šฐ๋ฆฌ๋Š” ๊ทผ๋ณธ์ ์ธ ์ ์„ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํ…Œ์ด๋ธ”์˜ "์šฐ๋ฆฌ" ๋ณ€๊ฒฝ ์‚ฌํ•ญ๊ณผ "์šฐ๋ฆฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์•„๋‹Œ" ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ตฌ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ป๊ฒŒ๋“  ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ๊ฐ€๋ฅด์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค. "Ours"๋Š” ๊ทธ๋Œ€๋กœ ๊ฑด๋„ˆ๋›ฐ์ง€๋งŒ "not ours"์—์„œ๋Š” ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ธ์…˜ ๋ณ€์ˆ˜.

์„ธ์…˜_๋ณต์ œ_์—ญํ• 

์šฐ๋ฆฌ๋Š” ์ฝ์—ˆ๋‹ค. ์ˆ˜๋™:

ํŠธ๋ฆฌ๊ฑฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ๊ตฌ์„ฑ ๋ณ€์ˆ˜์˜ ์˜ํ–ฅ๋„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์„ธ์…˜_๋ณต์ œ_์—ญํ• . ์ถ”๊ฐ€ ์ง€์นจ ์—†์ด ํ™œ์„ฑํ™”(๊ธฐ๋ณธ๊ฐ’), ๋ณต์ œ ์—ญํ• ์ด "์›๋ณธ"(๊ธฐ๋ณธ๊ฐ’) ๋˜๋Š” "๋กœ์ปฌ"์ผ ๋•Œ ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ง€์ •ํ•˜์—ฌ ํ™œ์„ฑํ™”๋œ ํŠธ๋ฆฌ๊ฑฐ 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

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€