PostgreSQL์ ๋ด๋ถ ๋ฉ์ปค๋์ฆ์ ํน์ฑ์ผ๋ก ์ธํด ์ด๋ค ์ํฉ์์๋ ๋งค์ฐ ๋น ๋ฅด์ง๋ง ๋ค๋ฅธ ์ํฉ์์๋ "๋ณ๋ก ๋น ๋ฅด์ง ์์" ์ ์์ต๋๋ค. ์ค๋ ์ฐ๋ฆฌ๋ DBMS์ ์๋ ๋ฐฉ์๊ณผ ๊ฐ๋ฐ์๊ฐ DBMS๋ฅผ ์ฌ์ฉํ์ฌ ์ํํ๋ ์์ ๊ฐ์ ์ถฉ๋์ ๋ํ ์ ํ์ ์ธ ์์ โโ์ค์ ์ ๋ ๊ฒ์ ๋๋ค. ์ ๋ฐ์ดํธ์ MVCC ์์น.
์ ๊ฐ๋ตํ ์ด์ผ๊ธฐ
UPDATE ๋ช ๋ น์ผ๋ก ํ์ด ์์ ๋๋ฉด ์ค์ ๋ก DELETE ๋ฐ INSERT๋ผ๋ ๋ ๊ฐ์ง ์์ ์ด ์ํ๋ฉ๋๋ค. ์์ ๋ฌธ์์ด์ ํ์ฌ ๋ฒ์ xmax๋ UPDATE๋ฅผ ์ํํ ํธ๋์ญ์ ์ ์์ ๋์ผํ๊ฒ ์ค์ ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ์์ฑ๋ฉ๋๋ค ์ ๋ฒ์ ๊ฐ์ ์ค; xmin ๊ฐ์ ์ด์ ๋ฒ์ ์ xmax ๊ฐ๊ณผ ์ผ์นํฉ๋๋ค.
์ด ๊ฑฐ๋๊ฐ ์๋ฃ๋ ํ ์ผ์ ์๊ฐ์ด ์ง๋๋ฉด ์ด์ ๋ฒ์ ๋๋ ์ ๋ฒ์ ์ด ๊ฒฐ์ ๋ฉ๋๋ค. COMMIT/ROOLBACK
, ์ธ์๋ฉ๋๋ค "์ฃฝ์"(์ฃฝ์ ํํ) ์ง๋๊ฐ ๋ VACUUM
ํ์ ๋ฐ๋ผ ์ง์์ก์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด๊ฒ์ ์ฆ์ ์ผ์ด๋์ง๋ ์์ง๋ง "์ฃฝ์"๋ฌธ์ ๋ ๋งค์ฐ ๋น ๋ฅด๊ฒ ํ๋ ๋ ์ ์์ต๋๋ค.
#1: ๋๋ ๊ทธ๊ฒ์ ์ฎ๊ธฐ๋ ๊ฒ์ ์ข์ํ๋ค
๊ทํ์ ๋ฉ์๋๊ฐ ๋น์ฆ๋์ค ๋ก์ง์ ๋ํด ์์ ์ค์ธ๋ฐ ๊ฐ์๊ธฐ ์ผ๋ถ ๋ ์ฝ๋์์ 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๊ฐ๋ [์๋]VACUUM์ผ๋ก ์ ๋ฆฌํด์ผ ํฉ๋๋ค.
์ด๋ฐ ์์ผ๋กํ์ง ๋ง์ญ์์ค! ์ฌ์ฉ ํ๋์ ์์ฒญ์ผ๋ก ๋ชจ๋ ํ๋ ์ ๋ฐ์ดํธ โ ๊ฑฐ์ ํญ์ ๋ฉ์๋์ ๋ ผ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;
#2: ์ฌ์ฉ์ 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: ๊ถ๊ณ ์ ๊ธ
์ฝ์ ์ ์๋ ๋ณ๋์ ๊ธฐ์ฌ์ ๋ํ ํฐ ์ฃผ์ ์
๋๋ค.
๊ฒฐ์ ๋ฒํธ 3: ๋ฉ์ฒญํ ์ ํ
ํ์ง๋ง ์ด๊ฒ์ด ๋ฐ๋ก ๋น์ ์๊ฒ ์ผ์ด๋์ผ ํ ์ผ์
๋๋ค ๋์ผํ ๋ ์ฝ๋๋ก ๋์ ์์
? ์๋๋ฉด ํด๋ผ์ด์ธํธ ์ธก์์ ๋น์ฆ๋์ค ๋ก์ง์ ํธ์ถํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋ง์ณค์ต๋๊น? ๊ทธ๋ฆฌ๊ณ ์๊ฐํด๋ณด๋ฉด?..
์ถ์ฒ : habr.com