MVCC in Mysql(with νŠΈλžœμž­μ…˜ κ²©λ¦¬μˆ˜μ€€)

2024. 2. 25. 21:28ㆍDatabase/DB μŠ€ν„°λ””

이번 κΈ€μ—μ„œλŠ” MVCC의 κ°œλ…κ³Ό μ–΄λ–»κ²Œ λ™μž‘ν•˜λŠ” 것인지, 그리고 νŠΈλžœμž­μ…˜ κ²©λ¦¬μˆ˜μ€€μ„ κ΅¬ν˜„ν•  λ•Œ 이λ₯Ό μ–΄λ–»κ²Œ ν™œμš©ν•˜κ³  μžˆλŠ”μ§€μ— λŒ€ν•΄ κ°€μž₯ 많이 μ“°μ΄λŠ” λ°μ΄ν„°λ² μ΄μŠ€ 쀑 ν•˜λ‚˜μΈ Mysql을 톡해 μ •λ¦¬ν•˜κ³ μž ν•œλ‹€.

λ“€μ–΄κ°€κΈ° μ•žμ„œ

이번 κΈ€μ—μ„œ μ€‘μ μ μœΌλ‘œ λ‹€λ£¨κ²Œ 될 MVCC 주제둜 λ“€μ–΄κ°€κΈ° 전에, λ¨Όμ € νŠΈλžœμž­μ…˜ κ²©λ¦¬μˆ˜μ€€μ— λŒ€ν•œ 배경지식이 ν•„μš”ν•˜λ‹€.

νŠΈλžœμž­μ…˜ κ²©λ¦¬μˆ˜μ€€μ΄λž€, λ°μ΄ν„°λ² μ΄μŠ€ λ‚΄μ—μ„œ νŠΈλžœμž­μ…˜λ“€μ΄ λ™μ‹œλ‹€λ°œμ μœΌλ‘œ 싀행될 λ•Œ ν•΄λ‹Ή νŠΈλžœμž­μ…˜μ˜ 쑰회 κ²°κ³Όκ°€ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ— μ–Όλ§ˆλ‚˜ 영ν–₯을 λ°›κ²Œν• μ§€μ— λŒ€ν•œ μˆ˜μ€€μ„ μ˜λ―Έν•œλ‹€.

READ UNCOMMITED, READ COMMITED, REPEATABLE READ, SERIALIZABLE의 총 4가지 μˆ˜μ€€μœΌλ‘œ κ΅¬μ„±λ˜κ³  μ–ΈκΈ‰ν•œ μˆœμ„œμ˜ μ—­μˆœμœΌλ‘œ 격리 μˆ˜μ€€μ΄ 높아진닀. (READ UNCOMMITED -> ... -> SERIALIZABLE)

각 κ²©λ¦¬μˆ˜μ€€μ— λŒ€ν•œ 정보와 그에 μ—°κ΄€λœ λ¬Έμ œλ“€μ€ μ˜ˆμ „μ— μž‘μ„±ν•΄λ‘” ν¬μŠ€νŠΈκ°€ 있기 λ•Œλ¬Έμ— 링크둜 λŒ€μ²΄ν•˜κ² λ‹€.

 

νŠΈλžœμž­μ…˜ 격리 μˆ˜μ€€

νŠΈλžœμž­μ…˜ 격리 μˆ˜μ€€μ΄λž€? DBμ—μ„œ νŠΈλžœμž­μ…˜μ΄λž€ νŠΉμ • μž‘μ—…μ„ μœ„ν•œ DB μ—°μ‚°λ“€μ˜ λͺ¨μž„μœΌλ‘œ, ν•˜λ‚˜μ˜ μž‘μ—… λ‹¨μœ„μ΄λ‹€. νŠΈλžœμž­μ…˜μ€ ACID둜 λΆˆλ¦¬λŠ” 4가지 νŠΉμ§•μ„ κ°–λŠ”λ‹€. λ‹€λ§Œ 이λ₯Ό μ™„λ²½ν•˜κ²Œ 지킀기 μœ„ν•΄μ„œ

one-armed-boy.tistory.com

 

MVCC

κ°œλ…

MVCCλž€ Multi Version Concurrency Control의 μ•½μžλ‘œ, μ§μ—­ν•˜μžλ©΄ 닀쀑 버전 λ™μ‹œμ„± μ œμ–΄ 쯀이 λœλ‹€.

닀쀑 λ²„μ „μ΄λΌλŠ” λ§μ—λŠ” κ·Έ λŒ€μƒμ΄ λ˜λŠ” μ£Όμ–΄κ°€ λΉ μ ΈμžˆλŠ”λ°, μ—¬κΈ°μ—μ„œ 닀쀑 버전을 톡해 κ΄€λ¦¬λ˜λŠ” μ£Όμ²΄λŠ” λ°”λ‘œ DB λ ˆμ½”λ“œμ΄λ‹€.

즉, DBλŠ” ν•˜λ‚˜μ˜ λ ˆμ½”λ“œμ— λŒ€ν•΄ λ‚΄λΆ€μ μœΌλ‘œ μ—¬λŸ¬ 버전을 κ΄€λ¦¬ν•˜κ³  μžˆλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€.

μ‚¬μš© 이유

κ·Έλ ‡λ‹€λ©΄ DBλŠ” μ™œ 각 λ ˆμ½”λ“œμ— λŒ€ν•΄ μ—¬λŸ¬ 버전을 κ΄€λ¦¬ν•˜λŠ” κ²ƒμΌκΉŒ?

Mysql κ³΅μ‹λ¬Έμ„œμ— λ”°λ₯΄λ©΄ κ·Έ μ΄μœ λŠ” μ•„λž˜μ™€ κ°™λ‹€.

Mysql InnoDBλŠ” λ™μ‹œμ„±, λ‘€λ°±κ³Ό 같은 νŠΈλžœμž­μ…˜ κΈ°λŠ₯듀을 μ§€μ›ν•˜κΈ° μœ„ν•΄ "λ©€ν‹° 버저닝"을 μ§€μ›ν•©λ‹ˆλ‹€.

νŠΈλžœμž­μ…˜μ΄ μ’…λ£Œλ˜λŠ” 방식은 크게 컀밋과 둀백이 μ‘΄μž¬ν•˜λŠ”λ°, 이 쀑 둀백을 μœ„ν•΄μ„œλŠ” νŠΉμ • λ ˆμ½”λ“œκ°€ νŠΈλžœμž­μ…˜μ— μ˜ν•΄ μˆ˜μ •λ˜κΈ° μ „ 데이터λ₯Ό μ•Œκ³ μžˆμ–΄μ•Ό ν•œλ‹€.  λ”°λΌμ„œ νŠΉμ • λ ˆμ½”λ“œμ˜ 버전을 κ΄€λ¦¬ν•˜λŠ” μ΄μœ λ‘œλŠ” νƒ€λ‹Ήν•˜λ‹€. (μ΄λŠ” 사싀 언두 λ‘œκ·Έμ— λŒ€ν•œ μ„€λͺ…이기도 ν•˜λ‹€.)

κ·Έλ ‡λ‹€λ©΄ λ™μ‹œμ„±μ€ μ–΄λ–¨κΉŒ? μ—¬κΈ°μ—μ„œλŠ” λ‹¨μˆœνžˆ 'λ™μ‹œμ„±'으둜 μ–ΈκΈ‰λ˜μ–΄ μžˆμ§€λ§Œ, 더 κ΅¬μ²΄μ μœΌλ‘œλŠ” μ—¬λŸ¬ νŠΈλžœμž­μ…˜μ΄ λ™μ‹œμ— λ™μž‘ν•˜λŠ” μƒν™©μ—μ„œλ„ λ°μ΄ν„°μ˜ 일관성을 μœ μ§€ν•˜λŠ” 것을 μ˜λ―Έν•œλ‹€κ³  보면 λœλ‹€. 이λ₯Ό κ΅¬ν˜„ν•˜λŠ” κ°€μž₯ λ‹¨μˆœν•œ 방법은 λ°”λ‘œ 락을 μ‚¬μš©ν•˜λŠ” κ²ƒμ΄μ§€λ§Œ, 맀번 락을 ν™œμš©ν•˜κ²Œ 될 경우 DB의 μ„±λŠ₯이 κ²°μ½” 쒋을 수 μ—†λ‹€. 이λ₯Ό μœ„ν•΄ DBκ°€ λ ˆμ½”λ“œ λ³„λ‘œ μ—¬λŸ¬ 버전을 κ΄€λ¦¬ν•˜κ³ , 각 νŠΈλžœμž­μ…˜μ—μ„œ 쑰회λ₯Ό μˆ˜ν–‰ν•  λ•Œ μ μ ˆν•œ λ²„μ „μ˜ λ ˆμ½”λ“œλ₯Ό 읽게만 ν•  수 μžˆλ‹€λ©΄ 락을 ν™œμš©ν•˜μ§€ μ•ŠμœΌλ©΄μ„œλ„ 데이터 쑰회의 일관성을 μœ μ§€ν•  수 μžˆλ‹€.

즉, MVCCλŠ” 이 버전듀을 ν™œμš©ν•˜μ—¬ λ™μ‹œλ‹€λ°œμ μœΌλ‘œ μ‹€ν–‰λ˜λŠ” νŠΈλžœμž­μ…˜μ—μ„œλ„ 쑰회λ₯Ό μœ„ν•œ 락을 νšλ“ν•˜μ§€ μ•ŠλŠ” λ°©ν–₯으둜 νŠΈλžœμž­μ…˜ κ²©λ¦¬μˆ˜μ€€μ„ κ΅¬ν˜„ν•œλ‹€κ³  λ³Ό 수 μžˆλ‹€.

λ™μž‘ 방식

MVCCλŠ” DB의 언두 λ‘œκ·Έμ™€ νŠΈλžœμž­μ…˜ ID(trx_id)λ₯Ό 톡해 κ΅¬ν˜„λœλ‹€.

μ—¬κΈ°μ„œ νŠΈλžœμž­μ…˜ IDλž€ Mysql이 각 νŠΈλžœμž­μ…˜μ— λΆ€μ—¬ν•˜λŠ” κ³„μ†ν•΄μ„œ μ¦κ°€ν•˜λŠ” 값을 μ˜λ―Έν•˜λŠ”λ°, Mysql은 ν•΄λ‹Ή ν•„λ“œλ₯Ό λ‚΄λΆ€μ μœΌλ‘œ μœ μ§€ν•˜λ˜ μ™ΈλΆ€λ‘œ λ…ΈμΆœν•˜μ§€λŠ” μ•ŠλŠ” λ°©μ‹μœΌλ‘œ 이λ₯Ό κ΄€λ¦¬ν•œλ‹€.

MVCC의 λ™μž‘ 방식을 μ΄ν•΄ν•˜κΈ° μœ„ν•΄ νŠΉμ • λ ˆμ½”λ“œμ— μ ‘κ·Όν•˜μ—¬ 칼럼 값을 μˆ˜μ •(value: 10 -> 20)ν•˜λŠ” νŠΈλžœμž­μ…˜(A)κ³Ό 이λ₯Ό μ‘°νšŒν•˜λŠ” νŠΈλžœμž­μ…˜(B)이 λ™μ‹œμ— μ‹€ν–‰λ˜λŠ” 상황을 μƒκ°ν•΄λ³΄μž.

이 λ•Œ 각 νŠΈλžœμž­μ…˜μ˜ μž‘μ—… μˆœμ„œλŠ” μ•„λž˜μ™€ κ°™λ‹€κ³  κ°€μ •ν•˜μž.

  1. λŒ€μƒ λ ˆμ½”λ“œ 쑴재 (trx_id: 5, value: 10)
  2. A νŠΈλžœμž­μ…˜ μ‹œμž‘ (trx_id: 10)
  3. A νŠΈλžœμž­μ…˜ μž‘μ—… μˆ˜ν–‰(value: 10 -> 20)
  4. B νŠΈλžœμž­μ…˜ μ‹œμž‘ (trx_id: 11)
  5. B νŠΈλžœμž­μ…˜ μž‘μ—… μˆ˜ν–‰(λ ˆμ½”λ“œ 쑰회)
  6. B νŠΈλžœμž­μ…˜ 컀밋
  7. A νŠΈλžœμž­μ…˜ 컀밋

μœ„ μƒν™©μ—μ„œ 2번 μž‘μ—…μ΄ μˆ˜ν–‰λ˜λŠ” 직후 버퍼 μΊμ‹œμ˜ λ°μ΄ν„°λŠ” 20으둜 μˆ˜μ •λ˜κ³  ν•΄λ‹Ή λ ˆμ½”λ“œμ˜ trx_id 값은 10이 λœλ‹€. 그리고 κΈ°μ‘΄ 값은 언두 λ‘œκ·Έμ— μ €μž₯λœλ‹€. (value: 10, trx_id: 5)

κ·Έ λ’€μ—” B νŠΈλžœμž­μ…˜μ΄ μ‹œμž‘λ˜κ³  ν•΄λ‹Ή λ ˆμ½”λ“œλ₯Ό 읽게 λœλ‹€.

이 λ•Œ νŠΈλžœμž­μ…˜ 격리 μˆ˜μ€€μ— 따라 λ™μž‘μ΄ λ‹¬λΌμ§€κ²Œ λ˜λŠ”λ°, READ COMMITED와 REPEATABLE READ의 κ²½μš°μ—” 언두 둜그λ₯Ό ν™œμš©ν•˜μ—¬ μ»€λ°‹λœ 데이터 λ§Œμ„ μ½μ–΄λ‚΄λŠ” 반면 READ UNCOMMITEDλŠ” 아직 μ»€λ°‹λ˜μ§€ μ•Šμ€ λ ˆμ½”λ“œλ₯Ό κ³§λ°”λ‘œ 읽고, SERIALIZABLE은 언두 둜그 λŒ€μ‹  락을 ν™œμš©ν•œλ‹€.

즉 MVCC 방식은 READ COMMITED, REPEATABLE READμ—λ§Œ ν•΄λ‹Ήν•œλ‹€.

READ COMMITED vs REPEATABLE READ

λ‹€λ§Œ, 두 격리 μˆ˜μ€€μ΄ MVCCλ₯Ό ν™œμš©ν•˜λŠ” λ°©λ²•μ—λŠ” μ—„μ—°ν•œ 차이가 μ‘΄μž¬ν•œλ‹€.

μš°μ„  REPEATABLE READ의 κ²½μš°μ—λŠ”, 버퍼 μΊμ‹œμ˜ λ ˆμ½”λ“œμ™€ 언두 둜그의 λ ˆμ½”λ“œ 쀑 μžμ‹ μ˜ νŠΈλžœμž­μ…˜ ID 값보닀 μž‘μ€ λ ˆμ½”λ“œ 쀑 κ°€μž₯ 큰 데이터λ₯Ό μ½λŠ”λ‹€. νŠΈλžœμž­μ…˜ IDλŠ” ν•˜λ‚˜μ˜ νŠΈλžœμž­μ…˜ μ•ˆμ—μ„œλŠ” λ³€κ²½λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, ν•΄λ‹Ή 격리 μˆ˜μ€€μ—μ„œλŠ” μΌμ •ν•œ μŠ€λƒ…μƒ·μ„ νšλ“ν•  수 μžˆλ‹€.

READ COMMITED의 κ²½μš°μ—” 쑰금 λ‹€λ₯΄λ‹€. 버퍼 μΊμ‹œμ˜ λ ˆμ½”λ“œμ™€ 언두 둜그의 λ ˆμ½”λ“œ 쀑 κ°€μž₯ μ΅œκ·Όμ— μ»€λ°‹λœ 데이터λ₯Ό μ½λŠ”λ‹€. 이둜 인해 ν•΄λ‹Ή 격리 μˆ˜μ€€μ—μ„œλŠ” SELECTλ₯Ό μ—¬λŸ¬λ²ˆ μˆ˜ν–‰ν•΄λ„, 쑰회 사이사이에 λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ˜ UPDATE 컀밋이 μžˆλ‹€λ©΄ 맀번 읽게 λ˜λŠ” 데이터가 λ‹¬λΌμ§€λŠ” 것이닀. (이λ₯Ό NON-REPEATABLE READ 문제라고 λΆ€λ₯Έλ‹€.)

 

μ°Έμ‘°

 

MySQL :: MySQL 8.0 Reference Manual :: 17.3 InnoDB Multi-Versioning

17.3 InnoDB Multi-Versioning InnoDB is a multi-version storage engine. It keeps information about old versions of changed rows to support transactional features such as concurrency and rollback. This information is stored in undo tablespaces in a data str

dev.mysql.com

 

 

νŠΈλžœμž­μ…˜ 격리 μˆ˜μ€€

Transaction Isolation Level μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ 개발 쀑 λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό λ„μž…ν•˜λ©΄ 격리 μˆ˜μ€€μ— λŒ€ν•œ 이해가 μžμ—°μŠ€λŸ½κ²Œ μš”κ΅¬λ©λ‹ˆλ‹€. 격리 μˆ˜μ€€μ€ λ°μ΄ν„°λ² μ΄μŠ€μ˜ ACID μ„±μ§ˆ 쀑 Isolation…

tecoble.techcourse.co.kr