MVCC(Multiversion Concurrency Control)

์ •๋ฏผ๊ตยท2023๋…„ 6์›” 24์ผ
0

DB

๋ชฉ๋ก ๋ณด๊ธฐ
10/12
post-thumbnail

๐Ÿ“’

์ง€๋‚œ ์‹œ๊ฐ„์— lock๊ณผ lock-based concurrency control์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

lock์„ ๊ธฐ๋ฐ˜์œผ๋กœ concurrency control์„ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•˜์˜€๋Š”๋ฐ lock์„ ์‚ฌ์šฉํ•˜๊ธฐ๋งŒ ํ•ด์„œ๋Š” deadlockํ˜„์ƒ์ด ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ตœ์ดˆ์˜ unlock operation ์ „๊นŒ์ง€๋Š” locking operation๋งŒ ์‚ฌ์šฉํ•˜๋Š” 2PL protocol์„ ์ ์šฉํ•œ lock-based concurrency control์„ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

2PL protocol์—๋Š” conservative 2PL, strict 2PL, strong strict 2PL์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ 2PL protocol์„ ์ ์šฉํ•œ lock-based concurrency control์€ ์„œ๋กœ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ๊ฐ™์€ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ๋•Œ read-read ์ž‘์—…๋งŒ ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—

์ „์ฒด DB ์ฒ˜๋ฆฌ๋Ÿ‰์ด ๋‚ฎ์•„์ ธ์„œ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด MVCC๋ฅผ ๊ฐœ๋ฐœํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค๊ณ  ์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜์€ MVCC์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

โœ”๏ธMVCC

MVCC๋„ lock์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ 2PL protocol์—์„œ read-lock๊ณผ write-lock์˜ ๊ด€๊ณ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

read-lockwrite-lock
read-lockOX
write-lockXX

MVCC์—์„œ read-lock๊ณผ write-lock์˜ ๊ด€๊ณ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

read-lockwrite-lock
read-lockOO
write-lockOX

๊ฐ™์€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด์„œ ์„œ๋กœ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด write-write ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ block๋˜๊ณ  ๋‚˜๋จธ์ง€ ๊ฒฝ์šฐ์—๋Š” ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํŠธ๋žœ์žญ์…˜์ด 2PL lock-based concurrency control๋ณด๋‹ค ๋†’์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ๋ฅผ ๋“ค์–ด MVCC๋ฅผ ์„ค๋ช…ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

x=10

tx1. x๋ฅผ ์ฝ๋Š”๋‹ค.

A. read(x)

tx2. x๋ฅผ 50์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

A. write-lock(x)
B. write(x=50)

๋‹ค์Œ๊ณผ ๊ฐ™์€ schedule์ด ์žˆ์Šต๋‹ˆ๋‹ค.

write-lock(tx2,x) - write(tx2,x=50) - read(tx1,x) - commit2 - unlock(x)

tx2๊ฐ€ x์— ๋Œ€ํ•œ ์“ฐ๊ธฐ ์ž‘์—…์„ ํ•˜๊ธฐ ์œ„ํ•ด write-lock์„ ์ทจ๋“ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  x=50 ์“ฐ๊ธฐ ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค.

MVCC๋Š” snapshot์œผ๋กœ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์ด๋ ฅ์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

tx2๊ฐ€ ์ž‘์—…ํ•œ x=50์€ ๋ฐ”๋กœ ๋””์Šคํฌ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ์ด ๋ณ€ํ™”๋ฅผ snapshot์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  tx1์ด x๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ํŠน์ง•์ด ์žˆ๋Š”๋ฐ MVCC๋Š” commit๋œ ๋ฐ์ดํ„ฐ๋งŒ ์ฝ๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

MVCC๊ฐ€ ์ ์šฉ๋˜๋ฉด readํ•  ๋•Œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฝ ์—†์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

tx2๊ฐ€ ์“ฐ๊ธฐ ์ž‘์—…์„ ํ•œ ๊ฒƒ์ด ๋””์Šคํฌ์— ์ ์šฉ๋œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ x=10์€ commit๋œ ๋ฐ์ดํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— x=10์„ ์ฝ์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ ํ›„์— tx2๊ฐ€ commit์„ ํ•˜๊ฒŒ ๋˜๋ฉด์„œ tx2์—์„œ ์ž‘์—…ํ•œ x=50์ด ๋””์Šคํฌ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  x์— ๋Œ€ํ•œ lock์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

lock์„ ์ทจ๋“ํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜๋Š” ์ž‘์—…์€ RDBMS๊ฐ€ ํ•ด์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์•ž์œผ๋กœ์˜ ์˜ˆ์ œ์—์„œ lock์„ ์ทจ๋“ํ•˜๊ฑฐ๋‚˜ ๋ฐ˜ํ™˜ํ•˜๋Š” operation์€ schedule์ƒ์— ์ ์ง€ ์•Š๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  commitํ•œ ํ›„์— lock์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ด์œ ๋Š” recoverability๋ฅผ ์œ„ํ•ด์„œ ์ž…๋‹ˆ๋‹ค.


recoverability ํฌ์ŠคํŒ…์—๋„ ์†Œ๊ฐœ๋˜์–ด ์žˆ์ง€๋งŒ,

recoverable schedule์€ commit๋˜์ง€ ์•Š์€ txA๊ฐ€ writeํ•œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด txB๊ฐ€ read๋ฅผ ํ–ˆ๋‹ค๋ฉด txA๊ฐ€ ์ข…๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€ txB๋„ ์ข…๋ฃŒํ•˜์ง€ ์•Š๋Š” schedule์ž…๋‹ˆ๋‹ค.

recoverable schedule ์ค‘ ๋” ์—„๊ฒฉํ•œ schedule์ด ์žˆ์Šต๋‹ˆ๋‹ค.

cascadeless schedule์€ ๊ทธ ์–ด๋–ค tx๋„ commit๋˜์ง€ ์•Š์€ tx๊ฐ€ writeํ•œ ๋ฐ์ดํ„ฐ๋Š” readํ•˜์ง€ ์•Š๋Š” schedule์ž…๋‹ˆ๋‹ค.
commitํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค.

๋” ์—„๊ฒฉํ•œ strict schedule๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

strict schedule์€ ๊ทธ ์–ด๋–ค tx๋„ commit๋˜์ง€ ์•Š์€ tx๊ฐ€ writeํ•œ ๋ฐ์ดํ„ฐ๋Š” readํ•˜์ง€๋„ writeํ•˜์ง€๋„ ์•Š๋Š” schedule์ž…๋‹ˆ๋‹ค.
commitํ•œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด์„œ๋งŒ ์ฝ๊ธฐ, ์“ฐ๊ธฐ ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฑธ ๋ณด๋ฉด lock์„ commitํ•œ ํ›„์—๋งŒ lock์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œisolation level์— ๋”ฐ๋ฅธ MVCC ๋™์ž‘

๋‹ค์‹œ ๋Œ์•„์™€์„œ,

์ด๋ ‡๊ฒŒ ๋‘ ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ์ด ์ด ์‹œ์ ์—์„œ tx1์ด x๋ฅผ ํ•œ๋ฒˆ ๋” ์ฝ๋Š” read์ž‘์—…์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.

๊ทธ๋Ÿฌ๋‹ˆ๊นŒ tx1์ด x๋ฅผ ๋‘ ๋ฒˆ ์ฝ๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ๋งˆ์ง€๋ง‰ read(tx1, x)๋Š” ์–ด๋–ค ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋ ๊นŒ์š”?

์ด๊ฑด ํŠธ๋žœ์žญ์…˜ isolation level์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

๐Ÿ‘‰read uncommitted

MVCC๋Š” commit๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. read uncommitted level์—์„œ๋Š” ๋ณดํ†ต MVCC๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

MySQL์—์„œ๋Š” MVCC๊ฐ€ ์ ์šฉ๋˜๋Š” isolation level์€ read committed์™€ repeatable read์ž…๋‹ˆ๋‹ค.
PostgreSQL์—์„œ๋Š” read uncommitted level์ด์–ด๋„ read committed level์ฒ˜๋Ÿผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ‘‰read committed

๋งŒ์•ฝ tx1์˜ isolation level์ด read commited๋ผ๋ฉด readํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ€์žฅ ์ตœ๊ทผ์— commit๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๊ธฐ ๋•Œ๋ฌธ์— commit๋œ x=50์„ ์ฝ์–ด์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

MySQL, PostgreSQL ๋‘˜ ๋‹ค ์ด๋ ‡๊ฒŒ read commited์—์„œ ์ด๋ ‡๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ‘‰repeatable read

๋งŒ์•ฝ tx1์˜ isolatio level์ด repeatable read๋ผ๋ฉด ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ์‹œ๊ฐ„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ€์žฅ ์ตœ๊ทผ์— commit๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ธฐ ๋•Œ๋ฌธ์— tx1 ์‹œ์ž‘ ์ „์— commit๋œ x=10์„ ๊ทธ๋Œ€๋กœ ๋‹ค์‹œ ์ฝ์–ด์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

MySQL, PostgreSQL ๋‘˜ ๋‹ค ์ด๋ ‡๊ฒŒ repeatable read์—์„œ ์ด๋ ‡๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

repeatable read๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๋ฐฉ์‹์€ RDBMS๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ค๋ช…์€ ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ์‹œ๊ฐ„ ๊ธฐ์ค€์œผ๋กœ ์„ค๋ช…ํ•˜์˜€์ง€๋งŒ,

์–ด๋–ค RDBMS๋Š” ํŠธ๋žœ์žญ์…˜์—์„œ ์ตœ์ดˆ์˜ read๊ฐ€ ๋ฐœ์ƒํ•œ ์‹œ์ ์„ ๊ธฐ์ค€์œผ๋กœ ํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๊ทธ ํŠธ๋žœ์žญ์…˜์—์„œ read๋“  write๋“  ์ตœ์ดˆ์˜ operation์ด ๋ฐœ์ƒํ•œ ์‹œ์ ์„ ๊ธฐ์ค€์œผ๋กœ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์‚ฌ์šฉํ•˜๋Š” RDBMS์˜ ๋งค๋‰ด์–ผ์„ ํ™•์ธํ•ด๋ณด์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ์ •๋ฆฌ

MVCC๋Š” ํŠธ๋žœ์žญ์…˜์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ๋•Œ ํŠน์ • ์‹œ์ ์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ€์žฅ ์ตœ๊ทผ์— commit๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.

ํŠน์ • ์‹œ์ ์€ isolation level์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.

์„œ๋กœ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ๊ฐ™์€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ read-write ์ž‘์—…์€ ์„œ๋กœ blockํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋ฐ์ดํ„ฐ ๋ณ€ํ™” ์ด๋ ฅ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ถ”๊ฐ€์ ์ธ ์ €์žฅ๊ณต๊ฐ„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€ํ™”๋๋‹ค๊ณ  ๋ฐ”๋กœ ๋””์Šคํฌ์— ์“ฐ๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋ณ€ํ™”๋œ ์ด๋ ฅ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ฐ€ commitํ•˜๋ฉด ๊ทธ ๋ณ€ํ™”๋œ ๋‚ด์šฉ์„ ๋””์Šคํฌ์— ์”๋‹ˆ๋‹ค.

์š”์ฆ˜ RDBMS๋Š” ๋Œ€๋ถ€๋ถ„ MVCC๋ฅผ ์‚ฌ์šฉํ•ด์„œ RDBMS๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

์ถ”๊ฐ€๋กœ MySQL์—์„œ๋Š” ํŠน์ • ์‹œ์  ๊ธฐ์ค€์œผ๋กœ ๊ฐ€์žฅ ์ตœ๊ทผ์— commit๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ๊ฒƒ์„ consistent read๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ๋Š” ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ด์ƒ ํ˜„์ƒ์— ๋Œ€ํ•ด์„œ MVCC๋ฅผ ์ ์šฉํ•œ RDBMS๋งˆ๋‹ค ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•˜๋Š”์ง€, serializable level์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š” ์ง€์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

profile
๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž

0๊ฐœ์˜ ๋Œ“๊ธ€