Search

MVCC

MVCC

โ€ข
์ผ๋ฐ˜์ ์œผ๋กœ ๋ ˆ์ฝ”๋“œ ๋ ˆ๋ฒจ์˜ ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๋Š” DBMS๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.
โ€ข
MVCC์˜ ๊ฐ€์žฅ ํฐ ๋ชฉ์ ์€ ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ผ๊ด€๋œ ์ฝ๊ธฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด๋‹ค. (InnoDB ์–ธ๋‘ ๋กœ๊ทธ๋ฅผ ํ†ตํ•ด ์ œ๊ณต)
โ€ข
MVCC๋Š” Multi Version Concurreny Control์˜ ์•ฝ์ž๋กœ, ํ•˜๋‚˜์˜ ๋ ˆ์ฝ”๋“œ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฒ„์ „์ด ๋™์‹œ์— ๊ด€๋ฆฌ๋œ๋‹ค.

MVCC ์˜ˆ์‹œ

๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด READ_COMMITTED์ธ MySQL ์„œ๋ฒ„์—์„œ InnoDB ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์„ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž. READ_COMMITED๋Š” COMMIT๋œ ๋ฐ์ดํ„ฐ๋งŒ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.
START TRANSACTION; CREATE TABLE member ( m_id INT NOT NULL, m_name VARCHAR(20) NOT NULL, m_area VARCHAR(100) NOT NULL, PRIMARY KEY (m_id), INDEX ix_area (m_area) ); INSERT INTO member (m_id, m_name, m_area) VALUES (1, 'ํ™๊ธธ๋™', '์„œ์šธ'); COMMIT;
Plain Text
๋ณต์‚ฌ
INSERT ๋ฌธ์ด ์‹คํ–‰๋˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ(๋ฒ„ํผํ’€)์™€ ๋””์Šคํฌ ๊ฐ๊ฐ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ๋‹ค.
๊ทธ๋ฆฌ๊ณ , ๋‹ค์Œ๊ณผ ๊ฐ™์ด UPDATE ๋ฌธ์„ ์‹คํ–‰ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐฑ์‹ ํ•œ๋‹ค๊ณ  ํ•˜์ž.
Transaction A> START TRANSACTION; Transaction A> UPDATE member SET m_area="๊ฒฝ๊ธฐ" WHERE id=1;
Plain Text
๋ณต์‚ฌ
UPDATE ๋ฌธ์ด ์‹คํ–‰๋˜๋ฉด ์ปค๋ฐ‹ ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ์ผ๋‹จ InnoDB ๋ฒ„ํผํ’€์˜ ๋ฐ์ดํ„ฐ๋Š” ๊ฐฑ์‹ ๋˜๊ณ  ์–ธ๋‘ ๋กœ๊ทธ์—๋Š” ๋ณ€๊ฒฝ ์ „์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณต์‚ฌ๋œ๋‹ค.
๋””์Šคํฌ์—๋„ ์ˆ˜์ •ํ•œ ๊ฐ’์œผ๋กœ ๊ฐฑ์‹ ๋ผ์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์“ฐ๋ ˆ๋“œ์— ์˜ํ•ด์„œ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜๋ฏ€๋กœ ์‹œ์ ์— ๋”ฐ๋ผ ์•„์ง ๊ฐฑ์‹ ๋˜์ง€ ์•Š์•˜์„ ์ˆ˜ ์žˆ๋‹ค. (MySQL์€ ACID๋ฅผ ๋ณด์žฅํ•˜๋ฏ€๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฒ„ํผํ’€๊ณผ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์€ ๋™์ผํ•œ ์ƒํƒœ๋ผ๊ณ  ๊ฐ€์ •ํ•ด๋„ ๋œ๋‹ค.)
MVCC๋ฅผ ํ†ตํ•ด ๋™์ผํ•œ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒ„์ „์œผ๋กœ ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ๊ณ , ์ด๋ฅผ ํ†ตํ•ด ์ปค๋ฐ‹ ์ด์ „์˜ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ, ๋ฐ์ดํ„ฐ ๋กค๋ฐฑ ๋“ฑ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด, ํŠธ๋žœ์žญ์…˜์ด COMMIT์ด๋‚˜ ROLLBACK๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ํ•ด๋‹น ๋ ˆ์ฝ”๋“œ๋ฅผ ์กฐํšŒํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?
Transaction B> SELECT * FROM member WHERE id=1; +------+-----------+--------+ | m_id | m_name | m_area | +------+-----------+--------+ | 12 | ํ™๊ธธ๋™ | ์„œ์šธ | +------+-----------+--------+
Plain Text
๋ณต์‚ฌ
ํ˜„์žฌ๋Š” READ_COMMITTED ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด๊ธฐ ๋•Œ๋ฌธ์— ์–ธ๋‘ ์˜์—ญ์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด m_area๊ฐ€ '์„œ์šธ'๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.
ํ•ด๋‹น ๊ฒฐ๊ณผ๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€(Isolation level)์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง„๋‹ค. ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด READ_UNCOMMITED์ธ ๊ฒฝ์šฐ์—๋Š” InnoDB ๋ฒ„ํผ ํ’€์˜ ๋ณ€๊ฒฝ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด READ_COMMITED, REPEATABLE_READ, SERIALIZABLE์ธ ๊ฒฝ์šฐ์—๋Š” ์•„์ง ์ปค๋ฐ‹๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ธ๋‘ ์˜์—ญ์˜ ๋ณ€๊ฒฝ ์ „ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
๋งŒ์•ฝ COMMIT์„ ํ•˜๋ฉด InnoDB๋Š” ๋” ์ด์ƒ์˜ ๋ณ€๊ฒฝ ์—†์ด ์ง€๊ธˆ์˜ ์ƒํƒœ๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ๋งŒ๋“ ๋‹ค. ์ปค๋ฐ‹์ด ๋œ๋‹ค๊ณ  ์–ธ๋‘ ์˜์—ญ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•ญ์ƒ ๋ฐ”๋กœ ์‚ญ์ œ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค. ์–ธ๋‘ ์˜์—ญ์„ ํ•„์š”๋กœ ํ•˜๋Š” ํŠธ๋žœ์žญ์…˜์ด ๋”๋Š” ์—†์„ ๋•Œ ๋น„๋กœ์†Œ ์‚ญ์ œ๋œ๋‹ค. ROLLBACK์„ ํ•˜๋ฉด ์–ธ๋‘ ์˜์—ญ์— ๋ฐฑ์—…๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„ํผ ํ’€๋กœ ๋‹ค์‹œ ๋ณต๊ตฌํ•˜๊ณ , ์–ธ๋‘ ์˜์—ญ์˜ ๋‚ด์šฉ์€ ์‚ญ์ œํ•ด๋ฒ„๋ฆฐ๋‹ค.

์ž ๊ธˆ ์—†๋Š” ์ผ๊ด€๋œ ์ฝ๊ธฐ(Non-Locking Consistent Read)

โ€ข
๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์œ„ํ•ด ๋ฝ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ๋™์‹œ ์š”์ฒญ ์ฒ˜๋ฆฌ ์†๋„๊ฐ€ ๋งค์šฐ ๋–จ์–ด์ง„๋‹ค.
โ€ข
๊ทธ๋ž˜์„œ, InnoDB ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์€ MVCC ๊ธฐ์ˆ ์„ ์ด์šฉํ•ด ์ž ๊ธˆ์„ ๊ฑธ์ง€ ์•Š๊ณ  ์ฝ๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
โ€ข
๊ฒฉ๋ฆฌ ์ˆ˜์ค€ SERIALIZABLE์„ ์ œ์™ธํ•œ ๋ชจ๋“  ์ˆ˜์ค€์—์„œ INSERT์™€ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ ์ˆœ์ˆ˜ํ•œ ์ฝ๊ธฐ(SELECT) ์ž‘์—…์€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ๋ณ€๊ฒฝ ์ž‘์—…๊ณผ ๊ด€๊ณ„์—†์ด ํ•ญ์ƒ ์ž ๊ธˆ์„ ๋Œ€๊ธฐํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์‹คํ–‰๋œ๋‹ค.
โ€ข
ํŠน์ • ์‚ฌ์šฉ์ž๊ฐ€ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์•„์ง ์ปค๋ฐ‹์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์•˜๋”๋ผ๋„, ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์˜ SELECT ์ž‘์—…์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๋Š”๋‹ค. (๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ์–ธ๋‘ ๋กœ๊ทธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์œผ๋ฏ€๋กœ)
โ€ข
์ด๋ฅผ ์ž ๊ธˆ ์—†๋Š” ์ผ๊ด€๋œ ์ฝ๊ธฐ(Consistent Non-Locking Read)๋ผ๊ณ  ํ‘œํ˜„ํ•˜๋ฉฐ, ์ด๋Š” ์–ธ๋‘ ๋กœ๊ทธ๋ฅผ ํ†ตํ•ด ๊ฐ€๋Šฅํ•˜๋‹ค.
์ฃผ์˜์ 
โ€ข
์˜ค๋žœ ์‹œ๊ฐ„๋™์•ˆ ํ™œ์„ฑ ์ƒํƒœ์ธ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ธํ•ด MySQL ์„œ๋ฒ„๊ฐ€ ๋Š๋ ค์ง€๊ฑฐ๋‚˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
โ€ข
์ผ๊ด€๋œ ์ฝ๊ธฐ๋ฅผ ์œ„ํ•ด ํ•ด๋‹น ํŠธ๋žœ์žญ์…˜์˜ ์–ธ๋‘ ๋กœ๊ทธ๋ฅผ ์‚ญ์ œํ•˜์ง€ ๋ชปํ•˜๊ณ  ์œ ์ง€ํ•ด์•ผ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
โ€ข
๋”ฐ๋ผ์„œ, ํŠธ๋žœ์žญ์…˜์˜ ๋ฒ”์œ„๋ฅผ ์ตœ์†Œํ™”ํ•˜์—ฌ ๊ผญ ํ•„์š”ํ•œ ๊ณณ์—๋งŒ ํ•œ์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

Reference

โ€ข
RealMySQL 8.0