InnoDB Storage Engine Lock
InnoDB ์คํ ๋ฆฌ์ง ์์ง์ ๋ค๋ฅธ MySQL ์คํ ๋ฆฌ์ง ์์ง๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ ์ฐจ์ด์ ์ด ์๋ค.
๋ ์ฝ๋ ๊ธฐ๋ฐ์ ์ ๊ธ(Row-level Lock)์ ์ ๊ณตํ์ฌ ๋์ ๋์์ฑ ์ฒ๋ฆฌ ๊ฐ๋ฅ
์ ๊ธ ์ ๋ณด๋ฅผ ํจ์จ์ ์ธ ์๋ฃ๊ตฌ์กฐ๋ก ๊ด๋ฆฌํ๋ฏ๋ก ์ ๊ธ์ ๊ฐ์๊ฐ ๋ง์์ ธ๋ ๋ ์ฝ๋ ๋ฝ์ด ํ์ด์ง ๋ฝ์ด๋ ํ ์ด๋ธ ๋ฝ์ผ๋ก ํ์ฅ๋๋ ์ ๊ธ ์์ค์ปฌ๋ ์ด์ (Lock Escalation)์ด ๋ฐ์ํ์ง ์์
์ ๊ธ์ ๊ธฐ๋ณธ ๋ชจ๋
InnoDB์ ๋ชจ๋ ๋ ์ฝ๋ ์์ค ์ ๊ธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ณต์ (Shared) ๋ชจ๋์ ๋ฐฐํ์ (Exclusive) ๋ชจ๋๋ก ๋๋๋ค.
๊ณต์ ์ ๊ธ (Shared Lock, S-Lock): ์ฌ๋ฌ ํธ๋์ญ์ ์ด ๋์์ ๋์ผํ ๋ ์ฝ๋์ ๋ํด ๊ณต์ ์ ๊ธ์ ๊ฐ์ง ์ ์์
๋ฐ์ดํฐ๋ฅผ ์ฝ๋ ๊ฒ์ ํ์ฉํ์ง๋ง, ๋ค๋ฅธ ํธ๋์ญ์ ์ด ํด๋น ๋ ์ฝ๋๋ฅผ ๋ณ๊ฒฝ(๋ฐฐํ์ ์ ๊ธ ํ๋)ํ๋ ๊ฒ์ ํ์ฉํ์ง ์์
SELECT ... LOCK IN SHARE MODE
๊ตฌ๋ฌธ์ ํตํด ํ๋
๋ฐฐํ์ ์ ๊ธ (Exclusive Lock, X-Lock): ์ค์ง ์ ๊ธ์ ์์ ํ ํธ๋์ญ์ ๋ง์ด ํด๋น ๋ ์ฝ๋๋ฅผ ์ฝ๊ณ ๋ณ๊ฒฝํ ์ ์์
๋ฐฐํ์ ์ ๊ธ์ด ์ค์ ๋ ๋ ์ฝ๋๋ ๋ค๋ฅธ ์ด๋ค ํธ๋์ญ์ ์์๋ ๊ณต์ ์ ๊ธ์ด๋ ๋ฐฐํ์ ์ ๊ธ์ ์ถ๊ฐ๋ก ํ๋ํ ์ ์์
SELECT ... FOR UPDATE
,UPDATE
,DELETE
๊ตฌ๋ฌธ์ ํตํด ํ๋
๋ ์ฝ๋ ๋ฝ(Record Lock)
๋ ์ฝ๋ ๋ฝ์ ์ธ๋ฑ์ค์ ๋ ์ฝ๋์ ์ ๊ธ์ ์ค์ ํ๋ ๊ฐ์ฅ ๋จ์ํ ํํ์ ์ ๊ธ์ด๋ค.
๋์ ๋ฐฉ์: ๋ฐ์ดํฐ ๋ ์ฝ๋ ์์ฒด๊ฐ ์๋, ํด๋น ๋ ์ฝ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ์ธ๋ฑ์ค ์ํธ๋ฆฌ๋ฅผ ์ ๊ธ
ํ ์ด๋ธ์ ์ธ๋ฑ์ค๊ฐ ์๋ค๋ฉด, InnoDB๊ฐ ๋ด๋ถ์ ์ผ๋ก ์์ฑํ ํด๋ฌ์คํฐ ์ธ๋ฑ์ค(ROW_ID)๋ฅผ ์ฌ์ฉํด ์ ๊ธ ์ค์
์ ๊ธ ๋ฒ์: ์ฟผ๋ฆฌ๊ฐ ์ด๋ค ์ธ๋ฑ์ค๋ฅผ ํตํด ๋ฐ์ดํฐ์ ์ ๊ทผํ๋์ง์ ๋ฐ๋ผ ์ ๊ธ์ ๋ฒ์๊ฐ ๊ฒฐ์
ํ๋ผ์ด๋จธ๋ฆฌ ํค๋ ์ ๋ํฌ ์ธ๋ฑ์ค๋ฅผ ํตํด ๋จ์ผ ๋ ์ฝ๋๋ฅผ ์กฐํํ๊ณ ์ ๊ทธ๋ ๊ฒฝ์ฐ, ์ ํํ ํด๋น ์ธ๋ฑ์ค ๋ ์ฝ๋ ํ๋์๋ง ์ ๊ธ์ด ์ค์
๋ ์ฝ๋ ์์ฒด ์ ๊ธ & ์ธ๋ฑ์ค์ ๋ ์ฝ๋ ์ ๊ธ ์ฐจ์ด
๋ ์ฝ๋ ๋ฝ์ ํ ์ด๋ธ ๋ ์ฝ๋๊ฐ ์๋ ์ธ๋ฑ์ค๋ฅผ ์ ๊ทธ๋ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์, ์๋์ ๊ฐ์ ์ํฉ์ ์ฃผ์ํด์ผ ํ๋ค.
-- ํ
์ด๋ธ ์ ๋ณด
-- TABLE NAME: employees
-- KEY ix_firstname (first_name)
SELECT COUNT(*)
FROM employees; -- 300000
SELECT COUNT(*)
FROM employees
WHERE first_name = 'Kwon'; -- 253
SELECT COUNT(*)
FROM employees
WHERE first_name = 'Kwon'
AND last_name = 'Ogu'; -- 1
UPDATE employees
SET hire_date = NOW()
WHERE first_name = 'Kwon'
AND last_name = 'Ogu';
์์ ์คํ ๋ฌธ์์
UPDATE
๋ฌธ์ฅ์ ๋จ ํ ๊ฑด์ ๋ ์ฝ๋๋ง ๋ณ๊ฒฝํ์ง๋ง ์ด ๋ฌธ์ฅ์ ์กฐ๊ฑด์์ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ ์ ์๋ ์กฐ๊ฑด์
first_name
์ปฌ๋ผ ํ๋๋ง ์กด์ฌ๋๋ฌธ์
first_name
์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ ๊ทธ๊ฒ ๋๊ณ , ์ด์ ๋ฐ๋ผfirst_name
์ปฌ๋ผ์ ๊ฐ์ดKwon
์ธ ๋ชจ๋ ๋ ์ฝ๋๊ฐ ๋ฝ ์์ฑ์ธ๋ฑ์ค๋ฅผ ํตํด ์ค์บํ ์ ์๋ ์ํฉ์๋ ๋ ์ฝ๋ ์กฐํ ์ ํ ์ด๋ธ์ ํ ์ค์บํ๋ฉด์ 30๋ง ๊ฑด์ ๋ ์ฝ๋ ์ ๋ถ ๋ฝ์ด ๊ฑธ๋ฆฌ๊ฒ ๋จ
๊ฐญ ๋ฝ(Gap Lock)
๋ ์ฝ๋๊ฐ ์ง์ ๋ ๋ฒ์์ ํด๋นํ๋ ์ธ๋ฑ์ค ํ ์ด๋ธ ๊ณต๊ฐ์ ๋์์ผ๋ก ๊ฑฐ๋ ์ ๊ธ์ผ๋ก, ์ค์ ๋ ์ฝ๋๊ฐ ์๋ ๊ตฌ๊ฐ(Gap)์ ๋ํด ์ค์ ๋๋ค.
๋ชฉ์ : ์ด ๊ฐ๊ฒฉ ๋ด์ ๋ค๋ฅธ ํธ๋์ญ์ ์ด ์๋ก์ด ๋ฐ์ดํฐ
INSERT
๋ฐฉ์ง๋์: ๊ฐญ ๋ฝ์ ๊ทธ ์์ฒด๋ก ํน์ ๋ ์ฝ๋๋ฅผ ์ ๊ทธ๋ ํจ๊ณผ๋ ์์ผ๋ฉฐ, ์ค์ง ์๋ก์ด ํญ๋ชฉ์ ์ฝ์ ๋ง ๋ฐฉ์ง
๊ฐญ ๋ฝ๋ผ๋ฆฌ๋ ์๋ก ์ถฉ๋ํ์ง ์์ผ๋ฉฐ, ์ฌ๋ฌ ํธ๋์ญ์ ์ด ๋์ผํ ๊ฐญ์ ๋ํด ๊ฐญ ๋ฝ์ ๋์์ ๋ณด์ ๊ฐ๋ฅ
-- 51 ~ 55 ์ฌ์ด์ ๋ ์ฝ๋์ ๋ํด ๋ฒ ํ์ ์ ๊ธ ํ๋ํ๋ ์ฟผ๋ฆฌ
SELECT *
FROM member
WHERE 51 <= age
AND age <= 55
FOR
UPDATE;
age 52 / 53์ ๊ฐ์ง ๋ ์ฝ๋๊ฐ ์์ ๋, ์ ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ค๋ฉด, ์ค์ ์กด์ฌํ๋ ๋ ์ฝ๋ ๋ฟ๋ง ์๋๋ผ, 51๊ณผ 55 ์ฌ์ด์ ๊ณต๊ฐ์ ๋ํด ๊ฐญ ๋ฝ์ด ๊ฑธ๋ฆฌ๊ฒ ๋๋ค.
...
...
...
50
59
X
๊ฐญ ๋ฝ(51 ~ 52 ์ฌ์ด์ ๊ณต๊ฐ)
52
61
๋ ์ฝ๋ ๋ฝ
53
62
๋ ์ฝ๋ ๋ฝ
๊ฐญ ๋ฝ(53 ~ 55 ์ฌ์ด์ ๊ณต๊ฐ)
56
65
X
๋ฅ์คํธ ํค ๋ฝ(Next-Key Lock)
๋ฅ์คํธ ํค ๋ฝ์ ๋ ์ฝ๋ ๋ฝ๊ณผ ๊ฐญ ๋ฝ์ ํฉ์น ํํ๋ก, InnoDB์ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์์ค์ธ REPEATABLE READ
์์ ํฌํ
๋ฆฌ๋(Phantom Read)๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํ ํต์ฌ์ ์ธ ๋ฉ์ปค๋์ฆ์ด๋ค.
ํน์ ์ธ๋ฑ์ค ๋ ์ฝ๋์ ๋ํ ๋ ์ฝ๋ ๋ฝ + ํด๋น ์ธ๋ฑ์ค ๋ ์ฝ๋ ์ด์ ์ ๊ฐ๊ฒฉ์ ๋ํ ๊ฐญ ๋ฝ
ํน์ ๋ ์ฝ๋์ ๊ทธ ์๋ค ๊ฐ๊ฒฉ์ ํฌํจํ๋ ๋ฒ์์ ๋ํด
(prev, current]
๋ฐฉ์์ผ๋ก ์ ๊ธ ์ค์
์ฆ, ์ฟผ๋ฆฌ์์ ์ฐธ์กฐํ ์ธ๋ฑ์ค ๋ ์ฝ๋๋ฟ๋ง ์๋๋ผ ๊ทธ ์ด์ ๊ณผ ๋ค์ ๋ ์ฝ๋์์ ๊ฐญ๊น์ง ํจ๊ป ์ ๊ธ์ด ๊ฑธ๋ฆฌ๋ฏ๋ก, ์กฐํ๋ ๋ฒ์ ๋ด์ ์๋ก์ด ๋ ์ฝ๋๊ฐ ์ฝ์ ๋๋ ๊ฒ์ ์ฐจ๋จํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
์์
50
101
52
102
56
103
age
์ปฌ๋ผ์ ๋ํ ์ธ๋ฑ์ค๋ฅผ ๊ฐ์ง member ํ
์ด๋ธ์ด ์๊ณ , ๋ค์๊ณผ ๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ฉด InnoDB๋ ๋ฅ์คํธ ํค ๋ฝ์ ์ค์ ํ๊ฒ ๋๋ค.
SELECT *
FROM member
WHERE age = 52 FOR
UPDATE;
์ ์ฟผ๋ฆฌ๋ ๋จ์ผ ๊ฐ(age = 52)๋ง ์กฐํํ์ง๋ง, ์ค์ ๋ก๋ ๋ค์๊ณผ ๊ฐ์ ๋ฅ์คํธ ํค ๋ฝ์ด ์ค์ ๋๋ค.
(50, 52] ๋ฒ์: ๋ ์ฝ๋ 52์ ๊ทธ ์ ๊ณต๊ฐ
(52, 56] ๋ฒ์: ๋ ์ฝ๋ 52 ๋ค์ ๊ฐ๊ณผ์ ๊ฐญ๋ ํฌํจ
์ด์ฒ๋ผ ์ ๋ํฌ ํ์ง ์์ ์ธ๋ฑ์ค์ ๋จ์ผ ๊ฐ์ ์กฐํํ๋๋ผ๋ ๋ฅ์คํธ ํค ๋ฝ์ ์ธ๋ฑ์ค ์์์ ์๋ค ๊ฐญ์ ๋ชจ๋ ํฌํจํด์ ์ ๊ธํ๊ฒ ๋๋ค.
๋ฅ์คํธ ํค ๋ฝ
(50, 52]
๋ ์ฝ๋ 52์ ์์ ๊ฐญ ํฌํจ
๋ฅ์คํธ ํค ๋ฝ
(52, 56]
๋ ์ฝ๋ 52 ์ดํ ์ธ๋ฑ์ค์ ๋ค์ ๋ ์ฝ๋์์ ๊ฐญ
๋ ์ฝ๋ ๋ฝ
52
๋ช ์์ ์ผ๋ก ์ ํ๋ ๋ ์ฝ๋ ์์ฒด
๋จ์ผ ์กฐํ ์์๋ ๋ฒ์์ ๋ํด ๋ฅ์คํธ ํค ๋ฝ์ด ๊ฑธ๋ฆฌ๋ ์ด์
๋ฝ์ ์ด์ฉํ ์ฝ๊ธฐ, UPDATE, DELETE์ ๊ฐ์ ๋ช ๋ น๋ฌธ์ SQL ๋ช ๋ น๋ฌธ ์ฒ๋ฆฌ ์ InnoDB๋ ์ ํํ WHERE ์กฐ๊ฑด์ ๊ธฐ์ตํ์ง ์๊ณ , ์ค์บ๋ ์ธ๋ฑ์ค ๋ฒ์์ ๋ํด ์ ๊ธ์ ์ค์ ํ๋ค.
์ ๋ํฌํ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ: InnoDB๋ ๋ฐ๊ฒฌ๋ ์ธ๋ฑ์ค ๋ ์ฝ๋๋ง ์ ๊ธ
์ ๋ํฌํ์ง ์์ ์ธ๋ฑ์ค or ๋ฒ์ ์กฐ๊ฑด: InnoDB๋ ์ค์บ๋ ์ธ๋ฑ์ค ๋ฒ์์ ๋ํด ๋ฅ์คํธ ํค ๋ฝ์ ์ค์
์๋ ์ฆ๊ฐ ๋ฝ(Auto-Increment Lock)
AUTO_INCREMENT
์์ฑ์ ๊ฐ์ง ์ปฌ๋ผ์ ๋ํด ์ค๋ณต๋์ง ์๋ ์ ๋ํฌํ ๊ฐ์ ํ ๋นํ๊ธฐ ์ํด ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉ๋๋ ํน์ํ ํ
์ด๋ธ ์์ค์ ์ ๊ธ์ด๋ค.
๋ด๋ถ์ ์ผ๋ก ํ ์ด๋ธ ์์ค์ ์ ๊ธ์ ๊ฑธ์ด ์ค๋ณต๋์ง ์๋ ๊ฐ์ ๋ณด์ฅ
๋ช ์์ ์ผ๋ก ํ๋ํ๊ฑฐ๋ ํด์ ํ ์ ์์
MySQL 8.0์์๋ ์ ๊ธ์ ๊ฑธ์ง ์๋ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ์ฌ์ฉ ์ค์ด๋ฉฐ
innodb_autoinc_lock_mode
์์คํ ๋ณ์๋ฅผ ์ด์ฉํ์ฌ ๋ณ๊ฒฝ ๊ฐ๋ฅ(๊ธฐ๋ณธ๊ฐ: 1)
0
(TRADITIONAL)
ํญ์ ์ฐ์์
๋งค์ฐ ๋ฎ์ (์ง๋ ฌ ์ฒ๋ฆฌ)
๋ชจ๋ INSERT์์ ํ ์ด๋ธ ๋จ์ ๋ฝ์ ๊ฑธ๊ณ ์์ฐจ์ ์ผ๋ก AUTO_INCREMENT ๊ฐ์ ํ ๋น
1
(CONSECUTIVE)
๋๋ถ๋ถ ์ฐ์์
๋ณดํต
์ฝ์
์๋ฅผ ์ ์ ์๋ ๋จ์ผ INSERT๋ ๋ฝ์ ์ต์ํ์ผ๋ก ๊ฑธ์ / INSERT ... SELECT
๊ฐ์ ์ฝ์
์๋ฅผ ์ ์ ์๋ ๊ฒฝ์ฐ ๊ตฌ๋ฌธ์ด ๋๋ ๋๊น์ง ํ
์ด๋ธ ๋จ์ ๋ฝ ์ ์ง
2
(INTERLEAVED)
์ฐ์์ฑ ๋ณด์ฅ ์ ๋จ
๋งค์ฐ ๋์
๋ฝ์ ์ก์ง ์์ ๋น ๋ฅด๊ฒ ์ฝ์ ํ๋ ID๋ ๋น์ฐ์์ ์ผ ์ ์์
๋ ์ฝ๋ ์์ค์ ์ ๊ธ ํ์ธ ๋ฐ ํด์
ํ ์ด๋ธ ์ ๊ธ์ ์ ๊ธ์ ๋์์ด ํ ์ด๋ธ ์์ฒด์ด๋ฏ๋ก ์ฝ๊ฒ ๋ฌธ์ ํ์ ์ด ๋์ง๋ง, ๋ ์ฝ๋ ์์ค์ ์ ๊ธ์ ๊ฑธ๋ ค์๋์ง ํ์ธํ๊ธฐ๊ฐ ์ด๋ ต๋ค.
BEGIN;
UPDATE employees SET birth_date=NOW() WHERE emp_no=10001;
UPDATE employees SET hire_date=NOW() WHERE emp_no=10001;
UPDATE employees SET hire_date=NOW(), birth_date=NOW() WHERE emp_no=10001;
์ ์๋๋ฆฌ์ค๋ ์ปค๋ฅ์
1์ด ์์ง COMMIT
์ ์คํํ์ง ์์ ์ํ์ด๋ฏ๋ก ํด๋น ๋ ์ฝ๋์ ์ ๊ธ์ ๊ทธ๋๋ก ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ์ปค๋ฅ์
2 / ์ปค๋ฅ์
3์ ํด๋น ๋ ์ฝ๋์ ์ ๊ธ์ ๋๊ธฐํ๊ณ ์์์ ํ์ธํ ์ ์๋ค.
SELECT
-- ๋๊ธฐ ์ค์ธ ํธ๋์ญ์
์ ๋ณด
r.trx_id waiting_trx_id,
r.trx_mysql_thread_id waiting_thread,
r.trx_query waiting_query,
-- ์ ๊ธ์ ๋ณด์ ํ ํธ๋์ญ์
์ ๋ณด
b.trx_id blocking_trx_id,
b.trx_mysql_thread_id blocking_thread,
b.trx_query blocking_query
FROM performance_schema.data_lock_waits w
INNER JOIN information_schema.innodb_trx b
ON b.trx_id = w.blocking_engine_transaction_id
INNER JOIN information_schema.innodb_trx r
ON r.trx_id = w.requesting_engine_transaction_id
MySQL 8.0 ๊ธฐ์ค performance_schema
ํ
์ด๋ธ์ ์ด์ฉํ์ฌ ์ ๊ธ๊ณผ ๋๊ธฐ ์์๋ฅผ ํ์ธํ ์ ์๋ค.
0x7f9b1c0003
3
UPDATE employees...
0x7f9b1c0002
2
UPDATE employees...
0x7f9b1c0003
3
UPDATE employees...
0x7f9b1c0001
1
NULL
0x7f9b1c0002
2
UPDATE employees...
0x7f9b1c0001
1
NULL
์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ ๊ฐ ์ค๋ ๋๊ฐ ์ด๋ค ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ์ด๋ค ์ค๋ ๋์ ์ ๊ธ์ ๋๊ธฐํ๊ณ ์๋์ง ํ์ธํ ์ ์๋ค.
2๋ฒ ์ค๋ ๋: 1๋ฒ ์ค๋ ๋์ ๋ฝ ๋๊ธฐ
3๋ฒ ์ค๋ ๋: 2๋ฒ ์ค๋ ๋ + 1๋ฒ ์ค๋ ๋์ ๋ฝ ๋๊ธฐ
์ฐธ๊ณ ์๋ฃ
Last updated
Was this helpful?