λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
🌾BackEnd/βœ…DataBase

MYSQL - LOCK

by MuGeon Kim 2023. 2. 28.
λ°˜μ‘ν˜•

Lock

  • 락은 기본적으둜 λ™μ‹œμ„±μ„ 보μž₯ν•œλ‹€. 즉. 락은 λ™μ‹œμ„±μ„ μ œμ–΄ν•  λ•Œ 락의 λ²”μœ„λ₯Ό μ΅œμ†Œν™”λ₯Ό ν•˜λŠ”κ²Œ μ€‘μš”ν•˜λ‹€.

μ™œλƒν•˜λ©΄ 락의 λ²”μœ„κ°€ 길어지면 λŒ€μ§€μ€‘μΈ 컀λ„₯μ…˜μ΄ λ§Žμ•„μ§€κ³  λ‚˜μ€‘μ—λŠ” 컀λ„₯μ…˜ 풀이 고갈둜 μ΄μ–΄μ§ˆ 수 μžˆλ‹€.

  • 기본적으둜 MySQLμ—μ„œλŠ” νŠΈλžœμž­μ…˜ 컀밋 , λ‘λ°±μ‹œμ μ— 락이 ν’€λ¦°λ‹€.
  • νŠΈλžœμž­μ…˜μ΄ 곧 락의 λ²”μœ„κ°€ λœλ‹€κ³  μƒκ°ν•˜λ©΄ λœλ‹€.
  • MySQLμ—μ„œ 락은 크게 InnoDB 엔진 , MySQL 엔진 레벨둜 λ‚˜λˆŒ 수 μžˆλ‹€.

 

πŸ“Œ 비관적 λ™μ‹œμ„± μ œμ–΄(PCC, Pessimistic Concurrency Control)

비관적 락이라고도 ν•˜λ©° νŠΈλžœμž­μ…˜μ΄ μΆ©λŒν•˜λŠ” κ°€μ •ν•˜μ— μž κΈˆμ„ κ±°λŠ” 방식

  • 일반적으둜 Shared Lock, Exclusive Lock을 톡해 이λ₯Ό κ΅¬ν˜„ν•œλ‹€.

πŸ“Œ 낙관적 λ™μ‹œ μˆ˜ν–‰ μ œμ–΄(OCC, Optimistic concurrency control)

  • 낙관적 락이라고도 ν•˜λ©° νŠΈλžœμž­μ…˜μ΄ μ„œλ‘œ μΆ©λŒν•˜μ§€ μ•ŠλŠ”λ‹€κ³  κ°€μ •ν•˜λŠ” 방식

λ ˆμ½”λ“œ μž κΈˆμ„ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€μ— μ‚¬μš©λ˜λŠ” λ™μ‹œμ„± μ œμ–΄ 방법이닀.

 

MySQL 엔진이 μ œκ³΅ν•˜λŠ” Lock


1. κΈ€λ‘œλ²Œ 락

Flush Tables with Read Lock

  • κ°€μž₯ λ²”μœ„κ°€ 큰 Lock이닀.
  • 락을 κ±Έλ©΄ Read, Writeκ°€ 싀행이 λΆˆκ°€λŠ₯ν•˜λ‹€.
  • Flush Tables with Read Lock을 싀행을 ν•˜λ €λ©΄ 기쑴의 쿼리가 λ‹€ 싀행이 되고 κ°€λŠ₯ν•˜λ‹€
    • λ§Œμ•½μ— κΈ΄ select쿼리λ₯Ό μ‹€ν–‰ν•˜κ³  있으면 락을 μ‚¬μš©ν•˜μ§€ λͺ»ν•œλ‹€.
  • 락은 μ‹€ν–‰ν•œ μ„œλ²„μ—μ„œ 풀어야지 쿼리가 싀행이 κ°€λŠ₯ν•˜λ‹€.

 

2. ν…Œμ΄λΈ” 락

  • κ°œλ³„ ν…Œμ΄λΈ” λ‹¨μœ„λ‘œ μ„€μ •λ˜λŠ” 잠금
  • Lock Tables ν…Œμ΄λΈ” 이름 [Read | Write ] λ₯Ό ν•˜μ—¬ Read락 or Write락을 μ„€μ •ν•œλ‹€.
  • Read Lock은 λ‹€λ₯Έ μ‚¬λžŒλ“€μ΄ Insertλ₯Ό ν•˜μ§€ λͺ»ν•œλ‹€.
  • Write Lock은 λ‹€λ₯Έ μ‚¬λžŒμ΄ 락 μ‚¬μš©μžκ°€ Insert ν•˜κΈ° μ „κΉŒμ§€ Selectλ₯Ό ν•˜μ§€ λͺ»ν•œλ‹€.

 

3. λ„€μž„λ“œ 락

  • Get_Lock()을 ν†΅ν•˜μ—¬ μž„μ˜μ˜ λ¬Έμžμ—΄μ— λŒ€ν•΄ μž κΈˆμ„ 섀정이 κ°€λŠ₯ν•˜λ‹€.
SELECT GET_LOCK('my_lock',2); //락을 κ±°λŠ”λ° 이미 잠금이면 2초 λ™μ•ˆλ§Œ λŒ€κΈ°
SELECT IS_FREE_LOCK('my_lock');//λ¬Έμžμ—΄μ΄ 잠금이 λ˜μ—ˆλŠ”μ§€ 확인
SELECT RELEASE_LOCK('my_lock');//락을 λ°˜λ‚© ν•œλ‹€.

 

 

InnoDB μ—μ„œ μ œκ³΅ν•˜λŠ” 락


Record Locks

  • λ ˆμ½”λ“œ μžμ²΄λ§Œμ„ μž κ·ΈλŠ” 락이닀.
  • νŠΈλžœμž­μ…˜μ—μ„œ 데이터λ₯Ό μ½κ±°λ‚˜ μˆ˜μ •ν•˜λŠ” κ²½μš°μ— μ‚¬μš©λœλ‹€. νŠΈλžœμž­μ…˜Aκ°€ 데이터λ₯Ό 읽으면 νŠΈλžœμž­μ…˜BλŠ” ν•΄λ‹Ή λ ˆμ½”λ“œλ₯Ό μˆ˜μ •ν•˜μ§€ λͺ»ν•˜μ—¬ λ°μ΄ν„°μ˜ 일관성을 보μž₯ν•œλ‹€.
  • λ ˆμ½”λ“œ 락은 곡유 락, 배타적 락으둜 κ΅¬λΆ„ν•œλ‹€.
곡유락  μ—¬λŸ¬ 개의 νŠΈλžœμž­μ…˜μ΄ ν•΄λ‹Ή λ ˆμ½”λ“œλ₯Ό 읽을 수 μžˆλ‹€.
배타적 락 ν•΄λ‹Ή λ ˆμ½”λ“œλ₯Ό μ†Œμœ ν•œ νŠΈλžœμž­μ…˜λ§Œ μˆ˜μ •μ΄λ‚˜ μ‚­μ œκ°€ κ°€λŠ₯ν•˜λ‹€.

 

 

Gap Locks

  • λ ˆμ½”λ“œμ™€ λ°”λ‘œ μΈμ ‘ν•œ λ ˆμ½”λ“œ μ‚¬μ΄μ˜ κ°„κ²©λ§Œμ„ μž κ·ΈλŠ” 락이닀.
  • 주둜 λ²”μœ„ κ²€μƒ‰μ—μ„œ μ‚¬μš©μ΄ λœλ‹€.
  • λ ˆμ½”λ“œμ™€ λ ˆμ½”λ“œ μ‚¬μ΄μ˜ 간격에 μƒˆλ‘œμš΄ λ ˆμ½”λ“œκ°€ μƒμ„±λ˜λŠ” 것을 μ œμ–΄ν•˜κ³ , λ„₯슀트 ν‚€ 락의 μΌλΆ€λ‘œ μ‚¬μš©λœλ‹€.
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(50)
);

μœ μ € ν…Œμ΄λΈ”μ— 1~10의 데이터가 μžˆλ‹€κ³  κ°€μ •ν•˜μž

-- νŠΈλžœμž­μ…˜ 1μ—μ„œ λ²”μœ„ 검색을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.
START TRANSACTION;
SELECT * FROM users WHERE id > 5 AND id < 8 FOR UPDATE;

-- νŠΈλžœμž­μ…˜ 2μ—μ„œ id 값이 6인 데이터λ₯Ό μ‚½μž…ν•©λ‹ˆλ‹€.
START TRANSACTION;
INSERT INTO users (id, name) VALUES (6, 'Alice');

μœ„ μ½”λ“œλ₯Ό 보면 5~8κΉŒμ§€ 갭락을 μ„€μ •ν•˜μ˜€κ³  νŠΈλžœμž­μ…˜ 2μ—μ„œ 갭락 λ²”μœ„μ— μžˆλŠ” 6을 μΆ”κ°€λ₯Ό ν•˜λ €κ³  ν•œλ‹€.

μ΄λ•Œ 갭락에 μ˜ν•΄ νŠΈλžœμž­μ…˜2λŠ” λŒ€κΈ° μƒνƒœμ— λΉ μ§€κ²Œ λœλ‹€.

 

Next-Key Locks

  • λ°μ΄ν„°μ˜ 일관성을 보μž₯ν•˜κΈ° μœ„ν•΄ 주둜 InnoDB μŠ€ν† λ¦¬μ§€ μ—”μ§„μ—μ„œ 기본으둜 μ‚¬μš©ν•œλ‹€.
  • 주둜 인덱슀 κ²€μƒ‰μ—μ„œ μ‚¬μš©μ΄ λœλ‹€.
  • λ ˆμ½”λ“œ, 갭락을 μ‘°ν•©ν•œ κ²ƒμœΌλ‘œ νŠΈλžœμž­μ…˜μ—μ„œ 인덱슀λ₯Ό 검색할 λ•Œ ν•΄λ‹Ή λ ˆμ½”λ“œμ— λŒ€ν•˜μ—¬ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ΄ μˆ˜μ •μ΄λ‚˜ μ‚­μ œλ₯Ό μ œν•œμ΄ κ°€λŠ₯ν•˜λ‹€.
  • REPEATABLE READ κ²©λ¦¬ μˆ˜μ€€μ—μ„œ νŒ¬ν…€ λ¦¬λ“œλ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•œ μž κΈˆμ΄λ‹€.

μ•„λž˜μ™€ 같은 ν…Œμ΄λΈ”μ΄ μžˆλ‹€κ³  κ°€μ •ν•˜μž

CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(50)
);

νŠΈλžœμž­μ…˜Aκ°€ λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯을 ν•˜μ˜€λ‹€.

SELECT * FROM users WHERE id = 5 FOR UPDATE;

μ΄λ•Œ ν•΄λ‹Ή λ ˆμ½”λ“œλŠ” 베타적 락이 섀정이 λ˜λŠ”λ° 그러면 λ‹€λ₯Έ νŠΈλžœμž­μ…˜N이 μˆ˜μ •μ΄λ‚˜ μ‚­μ œλ₯Ό ν•˜λ €κ³  ν•˜λ©΄ λŒ€κΈ° μƒνƒœλ‘œ λ³€κ²½λœλ‹€. 이것은 λ°μ΄ν„°μ˜ 일관성을 μœ μ§€ μ‹œμΌœμ€€λ‹€.

Next-Key Lock이 λ°œμƒν•˜λŠ” μ˜ˆμ‹œ μ½”λ“œ

-- νŠΈλžœμž­μ…˜ 1μ—μ„œ id 값이 5인 λ ˆμ½”λ“œλ₯Ό 락(lock)을 μ„€μ •ν•©λ‹ˆλ‹€.
START TRANSACTION;
SELECT * FROM users WHERE id = 5 FOR UPDATE;

-- νŠΈλžœμž­μ…˜ 2μ—μ„œ id 값이 6인 λ ˆμ½”λ“œλ₯Ό μ‚½μž…ν•©λ‹ˆλ‹€.
START TRANSACTION;
INSERT INTO users (id, name) VALUES (6, 'Bob');
  • IDκ°€ 5인 λ ˆμ½”λ“œμ— 락을 μ„€μ •ν•˜λ©΄ ν•΄λ‹Ή λ ˆμ½”λ“œμ— λŒ€ν•œ Next-Key Lock이 λ°œμƒν•œλ‹€.
  • νŠΈλžœμž­μ…˜2κ°€ idκ°€ 6인 λ ˆμ½”λ“œλ₯Ό μ‚½μž…ν•˜λ©΄ 인덱슀 갭에 λŒ€ν•œ Next-Key Lock이 λ°œμƒν•œλ‹€.
  • 즉 IDκ°€ 5의 μ–‘μͺ½ μΈλ±μŠ€μ— 락이 걸리게 λœλ‹€. → 4,6에 락이 κ±Έλ¦°λ‹€.

 

 

AUTO-INC Locks

  • AUTO_INCREMENT μΉΌλ¦Όμ΄ μ‚¬μš©λœ ν…Œμ΄λΈ”μ— λ™μ‹œμ— μ—¬λŸ¬ λ ˆμ½”λ“œκ°€ INSERTλ˜λŠ” 경우, 각 λ ˆμ½”λ“œλŠ” μ€‘λ³΅λ˜μ§€ μ•Šκ³  μ €μž₯된 μˆœμ„œλŒ€λ‘œ μ¦κ°€ν•˜λŠ” 일련번호 값을 κ°€μ Έμ•Ό ν•œλ‹€.
  • InnoDB λŠ” λ‚΄λΆ€μ μœΌλ‘œ AUTO-INC 락이라고 ν•˜λŠ” ν…Œμ΄λΈ” μˆ˜μ€€μ˜ μž κΈˆμ„ μ‚¬μš©ν•œλ‹€.
  • νŠΈλžœμž­μ…˜κ³Ό 관계 없이 INSERTλ‚˜ REPLACE λ¬Έμž₯μ—μ„œ AUTO_INCREMENT κ°’을 κ°€μ Έμ˜€λŠ” μˆœκ°„λ§Œ 락이 κ±Έλ Έλ‹€κ°€ ν•΄μ œλœλ‹€.

 

 

λ°˜μ‘ν˜•

'🌾BackEnd > βœ…DataBase' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

MySQL - 인덱슀  (0) 2023.02.28
MySQL - 격리 μˆ˜μ€€  (0) 2023.02.28
MySQL 엔진 μ•„ν‚€ν…μ²˜  (0) 2023.02.10