Skip to content

Latest commit

ย 

History

History
386 lines (305 loc) ยท 28.1 KB

File metadata and controls

386 lines (305 loc) ยท 28.1 KB

DataBase

Connection

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๊ธฐ์œ„ํ•ด ํ•„์š”ํ•œ ๊ฐ์ฒด

Connection Pool

Connection Pool์€ Connection์„ ํŠน์ • ๊ณต๊ฐ„(์บ์‹œ ๊ณต๊ฐ„)์— ๋ฏธ๋ฆฌ ์ƒ์„ฑ ํ•ด๋‘”๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์— Thread์—์„œ Connection Pool์— ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘” Connection์„ ๊บผ๋‚ด ์“ฐ๊ณ  ๋‹ค์‹œ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์›น ์„œ๋ฒ„(์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„)์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ Connection ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋น„์šฉ์€ ์ž‘์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์— ๋งค๋ฒˆ Connection์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ๋งŽ์€ ๋น„์šฉ์„ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Connection Pool์˜ ์„ค์ • ๊ฐ’

  • maxActive : ๋™์‹œ์— ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜
  • maxIdle : Connection Pool์— ๋ฐ˜๋‚ฉํ•  ๋•Œ ์ตœ๋Œ€๋กœ ์œ ์ง€ํ•  ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜
  • minIdle : ์ตœ์†Œํ•œ์œผ๋กœ ์œ ์ง€ํ•  ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜
  • initialSize : ์ตœ์ดˆ๋กœ getConnection() Method๋ฅผ ํ†ตํ•ด ์ปค๋„ฅ์…˜ ํ’€์— ์ฑ„์›Œ๋„ฃ์„ ์ปค๋„ฅ์…˜์˜ ๊ฐœ์ˆ˜

maxActive >= initialSize
๋™์‹œ์— ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ๋Š” ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜(maxActive)๋Š” ์ตœ์ดˆ๋กœ ์ƒ์„ฑํ•  ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜(initialSize)๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์•„์•ผํ•ฉ๋‹ˆ๋‹ค. maxActive < initialSize๋„ ์„ค์ •์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋…ผ๋ฆฌ์ ์ธ ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค.
maxIdle > minIdle
์ตœ๋Œ€๋กœ ์œ ์ง€ํ•  ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜๋Š”(maxActive)๋Š” ์ตœ์†Œ๋กœ ์œ ์ง€ํ•  ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜(minIdle)๋ณด๋‹ค ์ปค์•ผํ•ฉ๋‹ˆ๋‹ค. maxIdle < minIdle๋„ ์„ค์ •์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋…ผ๋ฆฌ์  ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค.
maxActive = maxIdle
maxActive์™€ maxIdle ๊ฐ’์€ ๊ฐ™์€๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•ฉ๋‹ˆ๋‹ค.
maxActive = 10, maxIdle = 5 ์„ค์ •๋œ ์ƒํƒœ๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์ปค๋„ฅ์…˜์„ ๋™์‹œ์— 5๊ฐœ ์‚ฌ์šฉ์ค‘์ธ ์ƒํ™ฉ์—์„œ ์ถ”๊ฐ€๋กœ 1๊ฐœ์˜ ์ปค๋„ฅ์…˜ ์š”์ฒญ์ด ์˜ค๋ฉด maxActive = 10 ์ด๋ฏ€๋กœ ์ปค๋„ฅ์…˜์„ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„ ์ปค๋„ฅ์…˜์„ ํ’€์— ๋ฐ˜๋‚ฉํ•˜๋ฉด ํ˜„์žฌ ์ƒ์„ฑ๋œ ์ปค๋„ฅ์…˜์ด 6๊ฐœ์ด๋ฏ€๋กœ maxIdle = 5 ์„ค์ •๊ฐ’์— ์˜ํ•ด ์ปค๋„ฅ์…˜์ด ๋‹ซํž™๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ maxActive์™€ maxIdle์„ค์ •์ด ๊ฐ™์ง€์•Š๋‹ค๋ฉด ๋งค๋ฒˆ ์ปค๋„ฅ์…˜์„ ์ƒ์„ฑํ•˜๊ณ  ๋‹ซ๋Š” ๋น„์šฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

maxActive ๊ฐ’์€ DBMS ์„ค์ •๊ณผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์˜ ๊ฐœ์ˆ˜, Apache, Tomcat์—์„œ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž(์š”์ฒญ)์˜ ์ˆ˜๋ฅผ ๊ณ ๋ คํ•ด์„œ ์„ค์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
DBMS๊ฐ€ ์ˆ˜์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜๋ฅผ ํ™•์ธํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„ 1๋Œ€๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ ์ ˆํ•œ ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜๋ฅผ ํ™•์ธํ•ด์„œ ์„ค์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋ชฐ๋ ค์„œ ์ปค๋„ฅ์…˜์„ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค๋ฉด maxActive ๊ฐ’์ด ์ถฉ๋ถ„ํžˆ ํฌ์ง€์•Š๋‹ค๋ฉด ๋ณ‘๋ชฉ์ง€์ ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

maxWait

maxWait ์„ค์ •๊ฐ’์€ ์ปค๋„ฅ์…˜์„ ์–ป๊ธฐ ์ „ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ์ปค๋„ฅ์…˜ ํ’€ ์•ˆ์— ์ปค๋„ฅ์…˜์ด ์—†์„ ๋•Œ ์ปค๋„ฅ์…˜ ๋ฐ˜๋‚ฉ์„ ๋Œ€๊ธฐํ•˜๋Š” ์‹œ๊ฐ„์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ’์„ ๋ฌดํ•œ์ •์ž…๋‹ˆ๋‹ค.
maxWait ๊ฐ’์„ ์„ค์ •ํ•˜์ง€ ์•Š๊ณ  ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ฌดํ•œ์ • ๋Œ€๊ธฐํ•˜๋„๋ก ํ•ด๋„ ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ๋ฌธ์ œ๊ฐ€ ์•ˆ๋ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž๊ฐ€ ๊ธ‰์ฆํ•˜๊ฑฐ๋‚˜ DBMS์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ์žฅ์• ๋ฅผ ๋”์šฑ ํฌ๊ฒŒ ํ™•์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ ์ ˆํ•œ maxWait ๊ฐ’์„ ์„ค์ •ํ•˜๋ ค๋ฉด TPS(transaction per seconds)์™€ Tomcat์—์„œ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅํ•œ ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜ ๋“ฑ์„ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

TPS(Transaction per second)

์‚ฌ์šฉ์ž์˜ ์š”์ฒญ ํ•˜๋‚˜์— ์ฟผ๋ฆฌ 10๊ฐœ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๊ฐ ์ฟผ๋ฆฌ๋Š” 50๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฐ๋‹ค๊ณ  ํ•˜๋ฉด 10๊ฐœ์˜ ์ฟผ๋ฆฌ๋Š” 500 ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.
๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ์‹œ๊ฐ„์€ ์ƒ๊ฐํ•˜์ง€์•Š๊ณ  ์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ์‹œ๊ฐ„๋งŒ ์ƒ๊ฐํ–ˆ์„ ๋•Œ 1์š”์ฒญ์— ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ด 500๋ฐ€๋ฆฌ์ดˆ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋งŒ์•ฝ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปค๋„ฅ์…˜์ด 5๊ฐœ๋ผ๋ฉด ๋™์‹œ์— 5๊ฐœ์˜ ์š”์ฒญ์„ ๊ฐ๊ฐ 500๋ฐ€๋ฆฌ์ดˆ(0.5์ดˆ)๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, 1์ดˆ ๋™์•ˆ 10๊ฐœ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋•Œ ์„ฑ๋Šฅ ์ง€์ˆ˜๋Š” 10TPS๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

TPS์™€ ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜์™€์˜ ๊ด€๊ณ„

์œ„์—์„œ ๋ดค๋“ฏ์ด ์ปค๋„ฅ์…˜ํ’€์˜ ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜๊ฐ€ 5๊ฐœ๋ผ๋ฉด 10TPS ์ด์ƒ์˜ ์„ฑ๋Šฅ์„ ๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
์ปค๋„ฅ์…˜ํ’€์—์„œ ์šด์˜ํ•˜๋Š” ์ปค๋„ฅ์…˜์ด 5๊ฐœ์ด๊ณ  10๊ฐœ์˜ ์š”์ฒญ์ด๋ผ๋ฉด 5๊ฐœ์˜ ์š”์ฒญ์€ ์ฒ˜๋ฆฌ๋˜์ง€๋งŒ ๋‚˜๋จธ์ง€ 5๊ฐœ์˜ ์š”์ฒญ์€ ๋Œ€๊ธฐ(wait)์ƒํƒœ๊ฐ€ ๋˜์–ด ์—ฌ๋ถ„์˜ ์ปค๋„ฅ์…˜์ด ์ƒ๊ธธ๋•Œ๊นŒ์ง€ maxWait ๊ฐ’๋งŒํผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์„œ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ maxActive๊ฐ’์„ ๋Š˜๋ฆฌ๋Š”๊ฒƒ์ž…๋‹ˆ๋‹ค.ํ˜„์žฌ maxActive = 5 ์ด์ง€๋งŒ maxActive = 10์œผ๋กœ ๋Š˜๋ฆฌ๋ฉด 10TPS์—์„œ 20TPS๋กœ ๋Š˜์–ด๋‚ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ DBMS์˜ ๋ฆฌ์†Œ์Šค๋Š” ๋‹ค๋ฅธ ์„œ๋น„์Šค์™€ ๊ณต์œ ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„์„œ ๋ฌด์กฐ๊ฑด ์ปค๋„ฅ์…˜ ์ˆ˜๋ฅผ ๋Š˜๋ฆด ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.
(DBMS๋„ ์ˆ˜์šฉ ๊ฐ€๋Šฅํ•œ ์ปค๋„ฅ์…˜์ด ์„ค์ •๊ฐ’์œผ๋กœ ์ •ํ•ด์ ธ์žˆ์Šต๋‹ˆ๋‹ค.)
๋”ฐ๋ผ์„œ ์ปค๋„ฅ์…˜ ํ’€์˜ ์ปค๋„ฅ์…˜ ์ˆ˜๋ฅผ ๋ฌด์กฐ๊ฑด ๋Š˜๋ฆฌ๋Š”๊ฒƒ๋ณด๋‹ค ์˜ˆ์ƒ ์ ‘์†์ž์ˆ˜์™€ ์‹ค์ œ ๋ถ€ํ•˜๋ฅผ ์ธก์ •ํ•ด์„œ ์ตœ์ ์˜ ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
๋Œ€๊ธฐ ์‹œ๊ฐ„(wait) ๊ฐ’์„ ์ž˜ ์กฐ์ ˆํ•˜๋Š”๊ฒƒ์ด ์ปค๋„ฅ์…˜ ๊ฐœ์ˆ˜๋ฅผ ๋ฌดํ•œํžˆ ๋Š˜๋ฆฌ์ง€์•Š๊ณ  ์ตœ์ ์˜ ์‹œ์Šคํ…œ ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•˜๋Š”๋ฐ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
maxWait ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ์„ค์ •ํ–ˆ๋Š”์ง€๊ฐ€ ์ผ์‹œ์ ์ธ ๊ณผ๋ถ€ํ•˜ ์ƒํƒœ์—์„œ ๋“œ๋Ÿฌ๋‚˜๋Š” ์‹œ์Šคํ…œ์˜ ์ „์ฒด์ ์ธ ๊ฒฌ๊ณ ํ•จ์„ ๊ฒฐ์ •์ง“์Šต๋‹ˆ๋‹ค.

์ ์ ˆํ•œ maxWait ์„ค์ •๊ฐ’ ์ฐพ๋Š” ๋ฐฉ๋ฒ•?

์ ๋‹นํ•œ ์„ค์ •๊ฐ’์„ ์ฐพ๊ธฐ์œ„ํ•ด์„œ๋Š” Commons DBCP์™ธ์— Tomcat์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ๊ณ ๋ คํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
Tomcat์€ ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•ด์„œ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
Commons DBCP๊ฐ€ ์Šค๋ ˆ๋“œ ํ’€์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๊ฒƒ์ฒ˜๋Ÿผ Tomcat๋„ ๋‚ด๋ถ€์ ์œผ๋กœ ์Šค๋ ˆ๋“œ ํ’€(wait set)์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์œ„์—์„œ ์ฒ˜๋Ÿผ 5๊ฐœ์˜ ์ปค๋„ฅ์…˜์ด ์‚ฌ์šฉ์ค‘์ด๊ณ  6๋ฒˆ์งธ ์š”์ฒญ์ด ์™”์„ ๋•Œ maxWait๋งŒํผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ฃผ์ฒด๋Š” Tomcat์˜ ์Šค๋ ˆ๋“œ์ž…๋‹ˆ๋‹ค.
maxWait = 10000 ์œผ๋กœ ์„ค์ •ํ•˜๋ฉด 10์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์ฆ‰, ์ฒ˜๋ฆฌ๋Ÿ‰์„ ๋„˜์–ด์„œ๋ฉด ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค์Œ ์ปค๋„ฅ์…˜์„ ์š”์ฒญํ•˜๊ธฐ๊นŒ์ง€ 10์ดˆ๋™์•ˆ ๋Œ€๊ธฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ณ„์† ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ๊ฒฐ๊ตญ Tomcat์˜ ์Šค๋ ˆ๋“œ ํ’€์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๊ณ  Tomcat์€ ์Šค๋ ˆ๋“œ๊ฐ€ ์—†์Œ์„ ์•Œ๋ฆฌ๋Š” ์˜ค๋ฅ˜๋ฅผ ์ถœ๋ ฅํ•˜๋ฉฐ ๋ฉˆ์ถฅ๋‹ˆ๋‹ค.

์‹ฌ๊ฐ: All threads (512) are currently busy, waiting. Increase maxThreads (512) or check the servlet status

10์ดˆ๊ฐ€ ์ง€๋‚˜์„œ ์ปค๋„ฅ์…˜์„ ํš๋“ํ•˜๊ณ  ์ž‘์—…์„ ์™„๋ฃŒํ•˜์—ฌ ์„ฑ๊ณต์ ์œผ๋กœ ์‘๋‹ต์„ ๋ณด๋‚ด๋„ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋Š” ์ด๋ฏธ ๋– ๋‚œ ํ›„์ž…๋‹ˆ๋‹ค.(๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋Š” 2~3์ดˆ๋‚ด์— ์‘๋‹ต์ด ์—†์œผ๋ฉด ์š”์ฒญ ํŽ˜์ด์ง€๋ฅผ ๋– ๋‚ฉ๋‹ˆ๋‹ค.)
์ฆ‰, ์‚ฌ์šฉ์ž๊ฐ€ ์ธ๋‚ดํ•  ์ˆ˜ ์—†๋Š” ์‹œ๊ฐ„์„ ๋„˜๋Š” maxWait๊ฐ’์€ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋Œ€๋กœ maxWait๊ฐ’์ด ๋„ˆ๋ฌด ์ž‘์œผ๋ฉด ์ปค๋„ฅ์…˜์ด ์—†์œผ๋ฉด ์ž์ฃผ ์ปค๋„ฅ์…˜์„ ์š”์ฒญํ•˜๊ฒŒ ๋ ๊ฒƒ์ด๊ณ  ์‚ฌ์šฉ์ž๋Š” ์˜ค๋ฅ˜๋ฉ”์„ธ์ง€๋ฅผ ์ž์ฃผ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ maxWait๋Š” ์‚ฌ์šฉ์ž์˜ ๋Œ€๊ธฐ ๊ฐ€๋Šฅํ•œ ์‹œ๊ฐ„, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํŠน์„ฑ๊ณผ ์ฃผ๋ณ€์˜ ๋‹ค๋ฅธ ์„ค์ •, ์ž์›์˜ ์ƒํ™ฉ๋“ฑ์„ ๊ณ ๋ คํ•ด์„œ ๊ฐ’์„ ์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ ๊ธ‰์ฆํ•ด์„œ maxWait์•ˆ์— ์ปค๋„ฅ์…˜์„ ์–ป์ง€ ๋ชปํ•˜๋Š” ๋นˆ๋„๊ฐ€ ์ฆ๊ฐ€ํ•œ๋‹ค๋ฉด maxWait๊ฐ’์„ ์ค„์—ฌ์„œ ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜๊ฐ€ ํ•œ๊ณ„์— ๋„๋‹ฌํ•˜์ง€ ์•Š๋„๋ก ๋ฐฉ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (maxWait๋ฅผ ์ค„์—ฌ์„œ ์‹คํŒจํ•œ ์Šค๋ ˆ๋“œ๋Š” ๋น ๋ฅด๊ฒŒ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์œ ๋„ํ•˜์—ฌ ์Šค๋ ˆ๋“œ ์ˆœํ™˜์ด ๋น ๋ฅด๊ฒŒ ๋Œ๋„๋ก ํ•จ)

์œ„์™€ ๊ฐ™์€ ์ƒํ™ฉ์ด ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด Commons DBCP์˜ ์ปค๋„ฅ์…˜ ํ’€ maxActive๊ฐ’๊ณผ Tomcat์˜ ์Šค๋ ˆ๋“œ ํ’€์˜ ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์‹œ์Šคํ…œ ์ž์›์ด ํ•œ๋„๋ฅผ ๋„˜์–ด์„ฐ๋‹ค๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์˜ ํ™•์ถฉ(์Šค์ผ€์ผ ์—… or ์Šค์ผ€์ผ ์•„์›ƒ)์„ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

DBMS์˜ ์ปค๋„ฅ์…˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜ ์„ค์ •ํ•˜๊ธฐ

DBMS์˜ ์ปค๋„ฅ์…˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜ ์„ค์ • ๋ณด๋Š”๋ฒ•

show variables like '%max_connection%';

DBMS์—์„œ ์‚ฌ์šฉ๋๋˜ ๋™์‹œ ์ตœ๋Œ€ ์ปค๋„ฅ์…˜ ์ˆซ์ž

show status like '%max_used_connections%';

DBMS์—์„œ ์ˆ˜์šฉ ๊ฐ€๋Šฅํ•œ ์ตœ๋Œ€ ์ปค๋„ฅ์…˜ ์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฒ• (๋Œ€๋ถ€๋ถ„ default๋กœ 151์ด ์„ค์ •๋จ)

set global max_connections = 500;

์ฐธ๊ณ ์ž๋ฃŒ


Index

์‚ฌ์ „์  ์˜๋ฏธ : ์ƒ‰์ธ, ์–ด๋–ค๊ฒƒ์„ ๋’ค์ ธ์„œ ์ฐพ์•„๋ƒ„
๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—์„œ์˜ ์ธ๋ฑ์Šค : ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์กฐํšŒ(READ)์‹œ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œ์ผœ์ฃผ๋Š” ๊ฐ์ฒด
R(select)์—์„œ ์„ฑ๋Šฅํ–ฅ์ƒ ๋ฐ˜๋ฉด์— CUD(insert,update,delete)์—์„œ ์„ฑ๋Šฅ ํฌ์ƒ

์ธ๋ฑ์Šค์˜ ์ €์žฅ๊ณต๊ฐ„

  • ์ธ๋ฑ์Šค๋„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ ์ถ”๊ฐ€ ์ €์žฅ๊ณต๊ฐ„์ด ํ•„์š”(์ €์žฅ๋œ ๋ฐ์ดํ„ฐ์˜ 10% ์ •๋„๊ฐ€ ํ•„์š”)
  • InnoDB (MySQL)๋Š” ๋””์Šคํฌ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ ๋‹จ์œ„๋ฅผ ํŽ˜์ด์ง€๋ผ๊ณ  ํ•จ
  • ์ธ๋ฑ์Šค ์—ญ์‹œ ํŽ˜์ด์ง€ ๋‹จ์œ„๋กœ ๊ด€๋ฆฌ
  • MySQL 5.5 - ํŽ˜์ด์ง€๋Š” 16KB ๋กœ ํฌ๊ธฐ๊ฐ€ ๊ณ ์ •
  • MySQL 5.6 - ์„ค์ • ์˜ต์…˜์—๋”ฐ๋ผ ํŽ˜์ด์ง€ ํฌ๊ธฐ ์ œ์–ด๊ฐ€๋Šฅ 4KB, 8KB, 16KB (innodb_page_size ์„ค์ •)
  • MYSQL 5.7์ดํ›„ - 32KB, 64KBํฌ๊ธฐ๋ฅผ ์ง€์›(32KB, 64KB๋Š” FOW_FORMAT= COMPRESSED ์ง€์›ํ•˜์ง€์•Š์Œ)

https://sungwookkang.com/1213

์ธ๋ฑ์Šค ํ‚ค

  • ์ธ๋ฑ์Šค๋กœ ์ง€์ •ํ•œ ์ปฌ๋Ÿผ์˜ ํฌ๊ธฐ(์šฉ๋Ÿ‰) ex. varchar(20)๊ณผ varchar(255)๋Š” varchar(255)์˜ ์ธ๋ฑ์Šค ํ‚ค์˜ ํฌ๊ธฐ๊ฐ€ ํฌ๋‹ค ๋ผ๊ณ  ํ•จ
  • ์ธ๋ฑ์Šค ํ‚ค์—๋Š” ์ œํ•œ ์šฉ๋Ÿ‰์ด ์žˆ์Œ. 767byte / mariadb 10.5 dump 10.1๋ฒ„์ „์— ๋ณต๊ตฌํ•˜๋‹ˆ๊นŒ ์ธ๋ฑ์Šค ํ‚ค ์šฉ๋Ÿ‰๋•Œ๋ฌธ์— ๋ณต๊ตฌ๊ฐ€ ์•ˆ๋œ๋‹คํ•จ
  • varchar(255)๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ์œ„์˜ ์šฉ๋Ÿ‰์„ ์ดˆ๊ณผํ•  ์ˆ˜ ์žˆ์Œ
  • ํŽ˜์ด์ง€๊ฐ€ 16KB์ผ ๋•Œ ์ธ๋ฑ์Šค ํ‚ค๊ฐ€ 50byte๋ผ๋ฉด (์ธ๋ฑ์Šค ํ‚ค ์™ธ์— ๋‹ค๋ฅธ ์šฉ๋Ÿ‰๋„ ๊ณ ๋ คํ•ด์•ผํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„  ์ œ์™ธ)
    16*1024 / 50
    ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€์— ์•ฝ 327๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Œ.
  • ์ธ๋ฑ์Šค ํ‚ค๊ฐ€ 100byte๋ผ๋ฉด? ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€์— ์•ฝ 164๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Œ. โ†’ 300๊ฐœ์˜ ๋ฐ์ดํ„ฐ row๋ฅผ ์ฝ์„ ๋•Œ 50byte๋ผ๋ฉด 1๊ฐœ์˜ ํŽ˜์ด์ง€๋งŒ ์ฝ์–ด๋„๋˜์ง€๋งŒ 100byte๋ฉด 2๊ฐœ์˜ ํŽ˜์ด์ง€๋ฅผ ์ฝ์–ด์•ผํ•จ
    โ†’ ์ธ๋ฑ์Šค ํ‚ค๋„ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์ด ์žˆ๋‹ค.

Clustered Index

  • ํ…Œ์ด๋ธ”๋‹น 1๊ฐœ๋งŒ ์กด์žฌ
  • PK์ œ์•ฝ์กฐ๊ฑด์œผ๋กœ ์ปฌ๋Ÿผ์„ ์ƒ์„ฑํ•˜๋ฉด ์ž๋™ ์ƒ์„ฑ(PK๊ฐ€ ์—†์„ ๋•Œ Unique ์ปฌ๋Ÿผ์„ ์ƒ์„ฑํ•˜๋ฉด Clustered Index ์ž๋™ ์ƒ์„ฑ)
    • Unique ์ปฌ๋Ÿผ์„ ๋จผ์ € ์ƒ์„ฑํ•˜๊ณ  ์ดํ›„์— PK ์ปฌ๋Ÿผ์„ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๋ฉด PK์ปฌ๋Ÿผ์— Clustered Index ์ƒ์„ฑ๋˜๊ณ  Unique ์ปฌ๋Ÿผ์€ Non-Clustered Index๋กœ ๋ณ€๊ฒฝ๋จ)
    • 48kb ํžˆ๋“  ์ปฌ๋Ÿผ โ†’ ๋ณ„ ๊ธฐ๋Šฅ์—†์–ด์„œ PK ๋งŒ๋“ค์–ด์ฃผ๋Š”๊ฒŒ ์ข‹์Œ
  • ์ธ๋ฑ์Šค์— ๋ฐ์ดํ„ฐ ํŽ˜์ด์ง€๊ฐ€ ํ•จ๊ป˜ ์กด์žฌ
  • ๋ฆฌํ”„ ํŽ˜์ด์ง€ == ๋ฐ์ดํ„ฐ ํŽ˜์ด์ง€(BTree)
  • ๋ฐ์ดํ„ฐ๊ฐ€ ์ •๋ ฌ๋œ ์ƒํƒœ์—ฌ์•ผ ํ•œ๋‹ค.
  • CUD(์ถ”๊ฐ€, ์ˆ˜์ •,์‚ญ์ œ)์—์„œ ๋ฐ์ดํ„ฐํŽ˜์ด์ง€๋ฅผ ์ •๋ ฌ์‹œ์ผœ์•ผํ•จ ์ •๋ ฌ๋œ ์ƒํƒœ

Non-Clustered Index(Secondary Index)

  • ๋‹ค์ˆ˜๊ฐ€ ์กด์žฌ ํ•  ์ˆ˜ ์žˆ์Œ
  • Unique ์ œ์•ฝ์กฐ๊ฑด์œผ๋กœ ์ปฌ๋Ÿผ์„ ์ƒ์„ฑํ•˜๋ฉด Non-Clustered Index๊ฐ€ ์ž๋™ ์ƒ์„ฑ
  • ์ธ๋ฑ์Šค์— ๋ฐ์ดํ„ฐํŽ˜์ด์ง€๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Œ
    • ์ตœ์ข…์ ์œผ๋กœ ๋ฐ์ดํ„ฐํŽ˜์ด์ง€์˜ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ด
  • CUD(์ถ”๊ฐ€, ์ˆ˜์ •,์‚ญ์ œ)์—์„œ ๋ฐ์ดํ„ฐํŽ˜์ด์ง€๋ฅผ ์ •๋ ฌํ•˜์ง€ ์•Š์•„๋„๋จ โ†’ ๋ฐ์ดํ„ฐ๊ฐ€ ์ •๋ ฌ๋˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
  • ๋ฐ์ดํ„ฐ ํŽ˜์ด์ง€๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— Clustered Index์™€ ๋น„๊ตํ•ด์„œ ์กฐํšŒ ์†๋„๊ฐ€ ์กฐ๊ธˆ ๋–จ์–ด์ง(Clustered Index์™€ ๋น„๊ตํ•ด์„œ ๋–จ์–ด์ง€๋Š”๊ฒƒ์ด ๋А๋ฆฐ๊ฒƒ์ด ์•„๋‹˜)
  • ๋ฐ์ดํ„ฐ ํŽ˜์ด์ง€ ์ •๋ ฌ์ด ํ•„์š”์—†์œผ๋ฏ€๋กœ CUD ์„ฑ๋Šฅ์ด Clustered Index์™€ ๋น„๊ต์‹œ ๋ถ€ํ•˜๊ฐ€ ์ ์Œ

์นด๋””๋„๋ฆฌํ‹ฐ(Cardinality)

์ธ๋ฑ์Šค์˜ ํšจ์œจ์„ฑ์„ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์น˜ ์ค‘ ํ•˜๋‚˜
์‚ฌ์ „์  ์˜๋ฏธ: ์ง‘ํ•ฉ์˜ ํฌ๊ธฐ ๋˜๋Š” ๋†๋„, ์ง‘ํ•ฉ์˜ ์›์†Œ ๊ฐœ์ˆ˜์— ๋Œ€ํ•œ ์ฒ™๋„

https://ko.wikipedia.org/wiki/์ง‘ํ•ฉ์˜_ํฌ๊ธฐ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š” ํ•ด๋‹น ์ปฌ๋Ÿผ์˜ ์ค‘๋ณต๋œ ์ˆ˜์น˜๋ฅผ ์˜๋ฏธ

์ข€ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๋ ค๋ฉด ์นด๋””๋„๋ฆฌํ‹ฐ๋Š” '์ปฌ๋Ÿผ ๋‚ด๋ถ€์˜ ์œ ๋‹ˆํฌํ•œ ๊ฐ’์˜ ๊ฐœ์ˆ˜' ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.
ex. ์—ฐํ•„, ์—ฐํ•„, ์ง€์šฐ๊ฐœ, ๋ณผํŽœ, ํ˜•๊ด‘ํŽœ, ํ˜•๊ด‘ํŽœ, ํ˜•๊ด‘ํŽœ ์ด๋ ‡๊ฒŒ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด ์œ ๋‹ˆํฌํ•œ ๊ฐ’์€ [์—ฐํ•„, ์ง€์šฐ๊ฐœ, ๋ณผํŽœ, ํ˜•๊ด€ํŽœ] 4๊ฐœ๋‹ค

  • ์นด๋””๋„๋ฆฌํ‹ฐ๊ฐ€ ๋†’๋‹ค == '์ค‘๋ณต๋„๊ฐ€ ๋‚ฎ๋‹ค'
    • ์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ, ์šฐํŽธ๋ฒˆํ˜ธ, ์ฃผ์†Œ, ์ „ํ™”๋ฒˆํ˜ธ ๋“ฑ๋“ฑ์€ ์ค‘๋ณต๋„๊ฐ€ ๋‚ฎ์œผ๋ฏ€๋กœ ์นด๋””๋„๋ฆฌํ‹ฐ๊ฐ€ ๋†’๋‹ค.
  • ์นด๋””๋„๋ฆฌํ‹ฐ๊ฐ€ ๋‚ฎ๋‹ค == '์ค‘๋ณต๋„๊ฐ€ ๋†’๋‹ค'
    • ์„ฑ๋ณ„, ๊ตญ๊ฐ€ ์˜ ๊ฒฝ์šฐ ์ค‘๋ณต๋„๊ฐ€ ๋†’์œผ๋ฏ€๋กœ ์นด๋””๋„๋ฆฌํ‹ฐ๊ฐ€ ๋‚ฎ๋‹ค.

์ธ๋ฑ์Šค๋Š” ์นด๋””๋„๋ฆฌํ‹ฐ๊ฐ€ ๋†’์€ ์ปฌ๋Ÿผ์— ์ƒ์„ฑํ•˜๋ฉด ํšจ์œจ์ด ์ƒ์Šนํ•œ๋‹ค.

  • ์„ฑ๋ณ„์˜ ๊ฒฝ์šฐ ๋‚จ,์—ฌ ๋งŒ ์กด์žฌํ•˜๊ธฐ๋•Œ๋ฌธ์— 50%์˜ ๋ฐ์ดํ„ฐ๋งŒ ํ•„ํ„ฐ๋ง โ†’ ๋‚˜๋จธ์ง€ 50%์—์„œ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ์ฐพ์•„์•ผํ•จ
  • ์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ์˜ ๊ฒฝ์šฐ ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ๋Œ€๋ถ€๋ถ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•„ํ„ฐ๋ง โ†’ ๋น ๋ฅธ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅ

์ธ๋ฑ์Šค ์ž๋ฃŒ๊ตฌ์กฐ

  • HashTable
  • B-Tree
  • B+Tree

HashTable

  • ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์•„๋Š” HashTable์ž„
  • ๋‹จ์ผ ์กฐํšŒ์— ํŠนํ™”๋จ (where name = xxx) O(1)
  • ๋ฒ”์œ„ ๊ฒ€์ƒ‰์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ (where age > 10)

B-Tree

  • ๋ฐ์ดํ„ฐ๊ฐ€ ํ•ญ์ƒ ์ •๋ ฌ๋œ ์ƒํƒœ
  • ๊ฐ€์žฅ ์ƒ๋‹จ์„ '๋ฃจํŠธ ๋…ธ๋“œ'
  • ์ค‘๊ฐ„ ๋…ธ๋“œ๋ฅผ '๋ธŒ๋žœ์น˜ ๋…ธ๋“œ'
  • ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ '๋ฆฌํ”„ ๋…ธ๋“œ'
  • ๊ฐ™์€ ๋†’์ด๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ด๋„ ๋น„์Šทํ•œ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š”๊ฒŒ ํŠน์ง• = ๊ท ์ผ์„ฑ
  • ๋ธŒ๋žœ์น˜ ๋…ธ๋“œ์—์„œ๋„ 'ํ‚ค-๊ฐ’'์˜ ํ˜•ํƒœ๋กœ ์žˆ์–ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋” ๋นจ๋ฆฌ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค. โ†’ ํ‚ค-๊ฐ’์„ ๊ฐ€์ง€๋Š” ๋งŒํผ ์šฉ๋Ÿ‰์€ ๋” ํฌ๋ฏ€๋กœ ๋ฐ์ดํ„ฐ์˜ ์ˆซ์ž๊ฐ€ ์ค„์–ด๋“ฌ โ†’ ํŠธ๋ฆฌ์˜ ๋†’์ด๋Š” ๋” ํฌ๋‹ค

img_3.png

B+Tree

  • B-Tree์™€ ๊ตฌ์กฐ๋Š” ๋˜‘๊ฐ™์Œ
  • ๋‹จ ์ค‘๊ฐ„ ๋…ธ๋“œ(๋ธŒ๋žœ์น˜ ๋…ธ๋“œ)์—์„œ 'ํ‚ค-๊ฐ’'์„ ๊ฐ€์ง€๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ํ‚ค๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ์Œ
  • ์ค‘๊ฐ„ ๋…ธ๋“œ๋Š” ํ‚ค๋งŒ์„ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ํ‚ค-๊ฐ’์„ ๊ฐ€์ง€๋Š”๊ฒƒ๋ณด๋‹ค ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ์šฉ๋Ÿ‰์ด ์ž‘์Œ โ†’ ๋” ๋งŽ์€ ํ‚ค๋ฅผ ๊ฐ€์ง โ†’ ํŠธ๋ฆฌ์˜ ๋†’์ด๊ฐ€ ๋‚ฎ์•„์ง
  • ๋ฆฌํ”„ ๋…ธ๋“œ์—์„œ๋งŒ ํ‚ค-๊ฐ’์„ ๊ฐ€์ง
  • ๊ฐ™์€ ๋ ˆ๋ฒจ์˜ ๋…ธ๋“œ๋ผ๋ฆฌ๋Š” Doubly-LinkedList๋กœ ์—ฐ๊ฒฐ๋จ
  • ์ž์‹ ๋…ธ๋“œ์™€๋Š” Singly-LinkedList๋กœ ์—ฐ๊ฒฐ๋จ

img_2.png

InnoDB


Transaction

  • ๋ฐ์ดํ„ฐ์˜ ์ •ํ•ฉ์„ฑ์„ ๋ณด์žฅํ•ด์ค๋‹ˆ๋‹ค. (์ž‘์—…์˜ ์™„์ „์„ฑ์„ ๋ณด์žฅ)
  • ๋…ผ๋ฆฌ์ ์ธ ์ž‘์—…์…‹์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ฒ˜๋ฆฌ or ํ•˜๋‚˜๋ผ๋„ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•  ๊ฒฝ์šฐ ์›์ƒํƒœ๋กœ ๋ณต๊ตฌํ•ด์„œ ์ž‘์—…์˜ ์ผ๋ถ€๋งŒ ๋ฐ˜์˜๋˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ธฐ๋Šฅ
  • ์ž ๊ธˆ(Lock)์€ ๋™์‹œ์„ฑ์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋Šฅ (๋™์‹œ์„ฑ์„ ๋ณด์žฅํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ Lock์„ ํ™œ์šฉํ•ด์„œ ๋‹ค๋ฅธ ์ž‘์—…์„ ๋ง‰์Œ)

์Šคํ† ๋ฆฌ์ง€ ์—”์ง„(Strage Engine)

  • MyISAM, MEMORY -> ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜์ง€ ์•Š์Œ
    • ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ด๋ธ”์ด ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ ๋˜๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)
      • ex. ์ƒํ’ˆ ์ฃผ๋ฌธ ์‹œ ์ƒํ’ˆ ์ฃผ๋ฌธ์— ๋Œ€ํ•œ ๋ ˆ์ฝ”๋“œ ์ถ”๊ฐ€์™€, ์ƒํ’ˆ ๊ฐœ์ˆ˜ ์ˆ˜์ •์ด ๋ฐœ์ƒํ•ด์•ผํ•˜๋Š”๋ฐ ์ƒํ’ˆ ์ฃผ๋ฌธ ์ถ”๊ฐ€๋Š” ์„ฑ๊ณต์ ์œผ๋กœ ํ–ˆ์ง€๋งŒ ์‚ผํ’ˆ ๊ฐœ์ˆ˜ ์ˆ˜์ •์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ƒํ’ˆ ์ฃผ๋ฌธ์€ ์ด๋ค„์กŒ์ง€๋งŒ ๊ฐœ์ˆ˜๊ฐ€ ์ค„์–ด๋“ค์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์ด๋Ÿฐ ์ƒํ™ฉ์„ ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ผ์–ด๋‚ฌ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์„ ๋งž์ถ”๋Š”๊ฒŒ ์ƒ๋‹นํžˆ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • InnoDB -> ํŠธ๋žœ์žญ์…˜์„ ์ง€์›
    • ํ•˜๋‚˜์˜ ํŠธ๋ž™์žญ์…˜์€ 1๊ฐœ ์ด์ƒ์˜ ์ฟผ๋ฆฌ๋“  ๋…ผ๋ฆฌ์ ์ธ ์ž‘์—…์…‹ ํ•˜๋‚˜๋กœ 100% ์™„๋ฃŒ ๋˜๊ฑฐ๋‚˜ or ๋…ผ๋ฆฌ์ ์ธ ์ž‘์—…์…‹ ๋‚ด๋ถ€์—์„œ ์ฟผ๋ฆฌ ํ•˜๋‚˜๋ผ๋„ ์™„๋ฃŒ๋˜์ง€ ๋ชปํ•˜๋ฉด ์–ด๋–ค๊ฒƒ๋„ ์ ์šฉํ•˜์ง€ ์•Š๋Š”๊ฒƒ์ž…๋‹ˆ๋‹ค.
      • 100% ์™„๋ฃŒ๋ผ์„œ ์ž‘์—…์„ ์ ์šฉ์‹œํ‚ด (commit)
      • ์ฟผ๋ฆฌ ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•ด์„œ ์–ด๋–ค ์ฟผ๋ฆฌ๋„ ์ ์šฉํ•˜์ง€ ์•Š์Œ (roll back)

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํŠธ๋žœ์žญ์…˜์„ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•  ์ 

  • ํ”„๋กœ๊ทธ๋žจ ์ฝ”๋“œ๊ฐ€ DB ์ปค๋„ฅ์…˜์„ ๊ฐ€์ง€๋Š” ๋ฒ”์œ„์™€ ํŠธ๋žœ์žญ์…˜์˜ ๋ฒ”์œ„๋ฅผ ์ตœ์†Œํ™” ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
  • 1~2์ค„์˜ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋ผ๋„ ๋„คํŠธ์›Œํฌ ์ž‘์—…์ด๋ผ๋ฉด ํŠธ๋žœ์žญ์…˜์—์„œ ์ œ์™ธ์‹œ์ผœ์•ผํ•ฉ๋‹ˆ๋‹ค.
    • DBMS ์„œ๋ฒ„๊ฐ€ ๋†’์€ ๋ถ€ํ•˜์ƒํƒœ or ์œ„ํ—˜ํ•œ ์ƒํƒœ์— ๋น ์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

MySQL ์—”์ง„์˜ ์ž ๊ธˆ

  • MySQL ์—”์ง„ ๋ ˆ๋ฒจ ์ž ๊ธˆ
    • MySQL ์„œ๋ฒ„์—์„œ

Transaction ACID

A(Atomicity), ์›์ž์„ฑ : Commit or Rollback. ๋ชจ๋‘ ์ ์šฉ๋˜๊ฑฐ๋‚˜, ๋ชจ๋‘ ์ ์šฉ๋˜์ง€ ์•Š๊ฑฐ๋‚˜ C(Consistency), ์ผ๊ด€์„ฑ : ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘๊ณผ ๋ ์ „ํ›„๋กœ ๋ฐ์ดํ„ฐ๋Š” ์ผ๊ด€์ ์ด์–ด์•ผ ํ•œ๋‹ค. (ํŠธ๋žœ์žญ์…˜ ์ค‘๊ฐ„์— DataType, ๋˜๋Š” ์ œ์•ฝ์กฐ๊ฑด์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์•ˆ๋œ๋‹ค.) I(Isolation), ๊ณ ๋ฆฝ์„ฑ : ํŠธ๋žœ์žญ์…˜์€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์— ์˜ํ•ด ๋ฐฉํ•ด๋ฐ›์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค. D(Durability), ์ง€์†์„ฑ : Commit๋œ ๋ฐ์ดํ„ฐ๋Š” ์‹œ์Šคํ…œ์— ์ง€์†์ ์œผ๋กœ ์ €์žฅ๋˜์–ด ์žˆ์–ด์•ผํ•œ๋‹ค.

MySQL ์—”์ง„์˜ ์ž ๊ธˆ

  • MySQL ์—”์ง„๋ ˆ๋ฒจ์˜ ์ž ๊ธˆ
    • MySQL ์—”์ง„์ด๋ž€? MySQL ์„œ๋ฒ„์—์„œ ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„ ๋ถ€๋ถ„์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ์˜๋ฏธ
    • ๋ชจ๋“  ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์— ์˜ํ–ฅ์„ ๋ฏธ์นจ
  • ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„ ๋ ˆ๋ฒจ ์ž ๊ธˆ
    • ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„ ๊ฐ„์˜ ์ƒํ˜ธ ์˜ํ–ฅ์ด ์—†์Šต๋‹ˆ๋‹ค.

๊ธ€๋กœ๋ฒŒ ๋ฝ (Global Lock)

  • 'FLUSH TABLES WITH READ LOCK' ๋ช…๋ น์œผ๋กœ๋งŒ ํš๋“์ด ๊ฐ€๋Šฅ
  • MySQL ์„œ๋ฒ„ ์ „์ฒด์— ์˜ํ–ฅ์„ ์คŒ (๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋‹ฌ๋ผ๋„ ๋™์ผํ•˜๊ฒŒ ์˜ํ–ฅ์„ ์คŒ)
  • MySQL์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฝ ์ค‘์— ๊ฐ€์žฅ ๋ฒ”์œ„๊ฐ€ ํผ
    • ํ•œ ์„ธ์…˜์—์„œ ๊ธ€๋กœ๋ฒŒ ๋ฝ์„ ํš๋“ํ•˜๋ฉด ๋‹ค๋ฅธ ์„ธ์…˜์—์„œ SELECT๋ฌธ์„ ์ œ์™ธํ•œ ๋Œ€๋ถ€๋ถ„์˜ DDL๋ฌธ์ด๋‚˜ DML๋ฌธ์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ๊ธ€๋กœ๋ฒŒ ๋ฝ์ด ํ•ด์ œ๋  ๋•Œ ๊นŒ์ง€ ๋Œ€๊ธฐ์ƒํƒœ๋กœ ๋‚จ์Šต๋‹ˆ๋‹ค.
  • ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜๋Š” MyISAM์ด๋‚˜ MEMORY ํ…Œ์ด๋ธ”์— ๋Œ€ํ•ด์„œ mysqldump๋กœ ์ผ๊ด€๋œ ๋ฐฑ์—…์„ ๋ฐ›์•„์•ผํ•  ๋•Œ ๊ธ€๋กœ๋ฒŒ ๋ฝ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

'FLUSH TABLES WITH READ LOCK' ๋ช…๋ น์€ ์‹คํ–‰๊ณผ ๋™์‹œ์— MySQL ์„œ๋ฒ„์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ํ…Œ์ด๋ธ”์— ์ž ๊ธˆ์„ ๊ฒ๋‹ˆ๋‹ค.
์ด๋ฏธ ํ…Œ์ด๋ธ”์ด๋‚˜ ๋ ˆ์ฝ”๋“œ์— ์“ฐ๊ธฐ ์ž ๊ธˆ์„ ๊ฑธ๊ณ  ์žˆ๋Š” SQL์ด ์‹คํ–‰๋˜๊ณ  ์žˆ์—ˆ๋‹ค๋ฉด, 'FLUSH TABLES WITH READ LOCK' ๋ช…๋ น์€ ํ•ด๋‹น ํ…Œ์ด๋ธ”์˜ ์ฝ๊ธฐ ์ž ๊ธˆ์„ ๊ฑธ๊ธฐ ์œ„ํ•ด SQL์ด ์™„๋ฃŒ๋˜๊ณ  ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.
'FLUSH TABLES WITH READ LOCK' ๋ช…๋ น์€ ํ…Œ์ด๋ธ”์— ์ฝ๊ธฐ ์ž ๊ธˆ๋งŒ ๊ฑธ๊ธฐ ์ „์— ๋จผ์ € ํ…Œ์ด๋ธ”์„ ํ”Œ๋Ÿฌ์‹œ(flush)ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ด๋ธ”์— ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  ์ข…๋ฅ˜์˜ ์ฟผ๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜์•ผ๋งŒ ํ…Œ์ด๋ธ”์„ ํ”Œ๋Ÿฌ์‹œํ•˜๊ณ  ์ž ๊ธˆ์„ ๊ฑธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ์žฅ์‹œ๊ฐ„ ์‹คํ–‰๋˜๋Š” SELECT ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰์ค‘์ด๋ผ๋ฉด 'FLUSH TABLES WITH READ LOCK'๋ช…๋ น์–ด๋Š” ํ•ด๋‹น SELECT ์ฟผ๋ฆฌ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผํ•ฉ๋‹ˆ๋‹ค.
์žฅ์‹œ๊ฐ„ ์‹คํ–‰๋˜๋Š” SELECT ์ฟผ๋ฆฌ์™€ 'FLUSH TABLES WITH READ LOCK' ๋ช…๋ น์–ด๊ฐ€ ์ตœ์•…์˜ ์ผ€์ด์Šค๋กœ ์‹คํ–‰๋˜๋ฉด ๋ชจ๋“  ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ INSERT, UPDATE, DELETE๊ฐ€ ์žฅ์‹œ๊ฐ„ ์‹คํ–‰๋˜์ง€ ๋ชปํ•˜๊ณ  ๊ธฐ๋‹ค๋ ค์•ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ์›น์„œ๋น„์Šค์šฉ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” MySQL ์„œ๋ฒ„์—๋Š” ๊ฐ€๊ธ‰์  'FLUSH TABLES WITH READ LOCK'๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
mysqldump ๊ฐ™์€ ๋ฐฑ์—… ํ”„๋กœ๊ทธ๋žจ์€ 'FLUSH TABLES WITH READ LOCK' ๋ช…๋ น์„ ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐฑ์—…ํ•  ๋•Œ๋„ ์žˆ์œผ๋ฏ€๋กœ mysqldump์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ช…๋ น์— ๋”ฐ๋ผ ์–ด๋–ค ์ž ๊ธˆ์„ ๊ฑฐ๋Š”์ง€ ์•Œ์•„๋ด์•ผํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ด๋ธ” ๋ฝ (Table Lock)

  • ๊ฐœ๋ณ„ ํ…Œ์ด๋ธ” ๋‹จ์œ„๋กœ ์„ค์ •๋˜๋Š” ์ž ๊ธˆ์ด๋ฉฐ, ๋ช…์‹œ์  ๋˜๋Š” ๋ฌต์‹œ์ ์œผ๋กœ ํŠน์ • ํ…Œ์ด๋ธ”์˜ ๋ฝ์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ช…์‹œ์  ํ…Œ์ด๋ธ” ๋ฝ ํš๋“ : LOCK TABLES table_name [READ | WRITE] ๋ช…๋ น
  • ๋ช…์‹œ์  ํ…Œ์ด๋ธ” ๋ฝ์„ ํ•ด์ œ(๋ฐ˜๋‚ฉ) : UNLOCK TABLES
  • ๋ช…์‹œ์  ํ…Œ์ด๋ธ” ๋ฝ๋„ ํŠน๋ณ„ํ•œ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ฉด ๊ฑฐ์˜ ์“ธ ์ผ์ด ์—†์Œ -> ๊ธ€๋กœ๋ฒŒ ๋ฝ ์ฒ˜๋Ÿผ ์›น ์„œ๋น„์Šค์— ์ƒ๋‹นํ•œ ์˜ํ–ฅ์„ ๋ฏธ์นจ
  • ๋ฌต์‹œ์  ํ…Œ์ด๋ธ” ๋ฝ
    • MyISAM์ด๋‚˜ MEMORY ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ฌต์‹œ์ ์ธ ํ…Œ์ด๋ธ” ๋ฝ์ด ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
      • MySQL์„œ๋ฒ„๊ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ํ…Œ์ด๋ธ”์„ ์ž ๊ธˆํ•˜๊ณ  ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ํ›„, ์ฆ‰์‹œ ์ž ๊ธˆ์„ ํ•ด์ œํ•˜๋Š” ํ˜•ํƒœ๋กœ ์‚ฌ์šฉ
    • InnoDB ํ…Œ์ด๋ธ”์˜ ๊ฒฝ์šฐ ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„ ์ฐจ์›์—์„œ ๋ ˆ์ฝ”๋“œ ๊ธฐ๋ฐ˜์˜ ์ž ๊ธˆ์„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์ˆœ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์ฟผ๋ฆฌ๋กœ ์ธํ•ด ๋ฌต์‹œ์ ์ธ ํ…Œ์ด๋ธ” ๋ฝ์ด ์„ค์ •๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
      • ์ •ํ™•ํžˆ๋Š” InnoDB ํ…Œ์ด๋ธ”์—๋„ ํ…Œ์ด๋ธ” ๋ฝ์ด ์„ค์ •์€ ๋˜์ง€๋งŒ
        • ๋Œ€๋ถ€๋ถ„์˜ ํ…Œ์ด๋ธ” ๋ณ€๊ฒฝ DML ์ฟผ๋ฆฌ์—์„œ๋Š” ๋ฌด์‹œ๋˜๊ณ 
        • ์Šคํ‚ค๋งˆ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” DDL ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

์œ ์ € ๋ฝ (User Lock)

  • GET_LOCK() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ์ž„์˜๋กœ ์ž ๊ธˆ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ด ์ž ๊ธˆ์˜ ํŠน์ง•์€ ํ…Œ์ด๋ธ”์ด๋‚˜ ๋ ˆ์ฝ”๋“œ ๋˜๋Š” AUTO_INCREMENT๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ์ 
  • ์œ ์ € ๋ฝ์€ ๋‹จ์ˆœํžˆ ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •ํ•œ ๋ฌธ์ž์—ด(String, ์ž ๊ธˆ์˜ ์ด๋ฆ„์ฒ˜๋Ÿผ ์‚ฌ์šฉ๋จ)์— ๋Œ€ํ•ด ํš๋“ํ•˜๊ณ  ๋ฐ˜๋‚ฉํ•˜๋Š” ์ž ๊ธˆ ์ž…๋‹ˆ๋‹ค.
  • ์œ ์ €๋ฝ์€ ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋ถ„์‚ฐ ๋ฝ ๊ตฌํ˜„ - ์šฐ์•„ํ•œ ํ˜•์ œ๋“ค ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ
    • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค 1๋Œ€๋ฅผ ์›น ์„œ๋ฒ„ 5๋Œ€๊ฐ€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ 5๋Œ€์˜ ์›น ์„œ๋ฒ„๊ฐ€ ์–ด๋–ค ์ •๋ณด๋ฅผ ๋™๊ธฐํ™”ํ•ด์•ผ ํ•˜๋Š” ์š”๊ฑด์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ƒํ˜ธ ๋™๊ธฐํ™” ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๋•Œ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์˜ ์œ ์ € ๋ฝ์„ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ ์ € ๋ฝ ์‚ฌ์šฉ ์˜ˆ์ œ

  • ์œ ์ €๋ฝ์€ ๋งŽ์€ ๋ ˆ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ์— ๋ณ€๊ฒฝํ•˜๋Š” ํŠธ๋žœ์žญ์…˜์˜ ๊ฒฝ์šฐ์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐฐ์น˜์ฒ˜๋Ÿผ ํ•œ๊บผ๋ฒˆ์— ๋งŽ์€ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ ๋ฐ๋“œ๋ฝ์˜ ์›์ธ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ด๋•Œ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์ฐธ์กฐํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ๋ผ๋ฆฌ ์œ ์ € ๋ฝ์„ ๊ฑธ๊ณ  ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
// "mylock"์ด๋ผ๋Š” ๋ฌธ์ž์—ด์— ๋Œ€ํ•ด ์ž ๊ธˆ์„ ํš๋“ํ•œ๋‹ค.
// ์ด๋ฏธ ์ž ๊ธˆ์ด ์‚ฌ์šฉ ์ค‘์ด๋ฉด 2์ดˆ ๋™์•ˆ๋งŒ ๋Œ€๊ธฐํ•œ๋‹ค.
mysql > SELECT GET_LOCK('mylock', 2);

// "mylock"์ด๋ผ๋Š” ๋ฌธ์ž์—ด์— ๋Œ€ํ•ด ์ž ๊ธˆ์ด ์„ค์ •๋ผ ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
mysql > SELECT IS_FREE_LOCK('mysql');

// "mylock"์ด๋ผ๋Š” ๋ฌธ์ž์—ด์— ๋Œ€ํ•ด ํš๋“ํ–ˆ๋˜ ์ž ๊ธˆ์„ ๋ฐ˜๋‚ฉ(ํ•ด์ œ)ํ•œ๋‹ค.
mysql > SELECT RELEASE_LOCK('mysql');

// 3๊ฐœ ํ•จ์ˆ˜ ๋ชจ๋‘ ์ •์ƒ์ ์œผ๋กœ ๋ฝ์„ ํš๋“ํ•˜๊ฑฐ๋‚˜ ํ•ด์ œํ•œ ๊ฒฝ์šฐ์—๋Š” 1์„, ์•„๋‹ˆ๋ฉด NULL์ด๋‚˜ 0์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋„ค์ž„ ๋ฝ (Name Lock)

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ์ฒด์˜ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒฝ์šฐ ํš๋“ํ•˜๋Š” ์ž ๊ธˆ์ž…๋‹ˆ๋‹ค. (ํ…Œ์ด๋ธ”์ด๋‚˜ ๋ทฐ ๋“ฑ๋“ฑ)
  • ๋ช…์‹œ์ ์œผ๋กœ ํš๋“ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ํ…Œ์ด๋ธ” ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ž‘์—…์ด ์ผ์–ด๋‚˜๋ฉด ์ž๋™์œผ๋กœ ํš๋“ํ•˜๋ฉด ์ž ๊ธˆ์ž…๋‹ˆ๋‹ค.
  • ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ…Œ์ด๋ธ”์„ ๋ฐ”๊ฟ”์•ผ ํ•˜๋Š” ์š”๊ฑด์ด ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฐฐ์น˜ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ด๊ณ ์žˆ๋‹ค.

์ฐธ๊ณ  : MySQL์˜ ์ž ๊ธˆ

InnoDB ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„ ์ž ๊ธˆ

  • InnoDB๋Š” ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„ ๋‚ด๋ถ€์—์„œ ๋ ˆ์ฝ”๋“œ ๊ธฐ๋ฐ˜์˜ ์ž ๊ธˆ ๋ฐฉ์‹์„ ํƒ์žฌ
    • MySQL์—์„œ ์ œ๊ณตํ•˜๋Š” ์ž ๊ธˆ๊ด€๋Š” ๋ณ„๊ฐœ
    • ๋ ˆ์ฝ”๋“œ ๊ธฐ๋ฐ˜์˜ ์ž ๊ธˆ๋ฐฉ์‹ ๋•๋ถ„์— MyISAM๋ณด๋‹ค ํ›จ์”ฌ ๋›ฐ์–ด๋‚œ ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ๋ฅผ ์ œ๊ณต
  • ์ž ๊ธˆ ์ •๋ณด๋Š” ์ƒ๋‹นํžˆ ์ž‘์€ ๊ณต๊ฐ„์—์„œ ๊ด€๋ฆฌํ•จ
    • ๋ ˆ์ฝ”๋“œ๋ฝ -> ํŽ˜์ด์ง€๋ฝ ๋˜๋Š” ํ…Œ์ด๋ธ”๋ฝ ์œผ๋กœ ๋ ˆ๋ฒจ์—…(์—์Šค์ปฌ๋ ˆ์ด์…˜) ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์—†์Œ

๋ ˆ์ฝ”๋“œ ๋ฝ

  • ๋ ˆ์ฝ”๋“œ ์ž์ฒด๋งŒ ์ž ๊ธˆ
  • InnoDB ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์€ ๋ ˆ์ฝ”๋“œ ์ž์ฒด๋ฅผ ์ž ๊ธˆ X, ์ธ๋ฑ์Šค์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ž ๊ธˆ

๊ฐญ ๋ฝ (Gap Lock)

  • ๋ ˆ์ฝ”๋“œ์™€ ๋ฐ”๋กœ ์ธ์ ‘ํ•œ ๋ ˆ์ฝ”๋“œ ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ๋งŒ ์ž ๊ธˆ
  • ๋ ˆ์ฝ”๋“œ์™€ ๋ ˆ์ฝ”๋“œ ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ์— ์ƒˆ๋กœ์šด ๋ ˆ์ฝ”๋“œ๊ฐ€ ์ƒ์„ฑ(Insert)๋˜๋Š” ๊ฒƒ์„ ์ œ์–ดํ•˜๋Š” ์—ญํ• 

๋„ฅ์ŠคํŠธ ํ‚ค ๋ฝ

  • ๋ ˆ์ฝ”๋“œ ๋ฝ + ๊ฐญ ๋ฝ
  • ์†Œ์Šค ์„œ๋ฒ„์—์„œ ๋งŒ๋“  ๊ฒฐ๊ณผ == ๋ ˆํ”Œ๋ฆฌ์นด ์„œ๋ฒ„์—์„œ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋กœ๊ทธ(statement ํฌ๋งท)์— ๊ธฐ๋ก๋˜๋Š” ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์ด ์ฃผ ๋ชฉ์ 
  • ๊ฐญ ๋ฝ + ๋„ฅ์ŠคํŠธ ํ‚ค ๋ฝ์œผ๋กœ ์ธํ•ด ๋ฐ๋“œ๋ฝ์ด ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์„ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ํ•˜๋Š” ์ผ์ด ๋ฐœ์ƒํ•จ
    • ์ด๋•Œ๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ๋กœ๊ทธ์˜ ํฌ๋งท์„ Statement ํฌ๋งท -> Row ํฌ๋งท์œผ๋กœ ๋ณ€๊ฒฝํ•ด์„œ ๊ฐญ ๋ฝ, ๋„ฅ์ŠคํŠธ ํ‚ค ๋ฝ์„ ์ค„์—ฌ์ฃผ๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค.

์ž๋™ ์ฆ๊ฐ€ ๋ฝ (Auto Increment Lock)

  • ํ…Œ์ด๋ธ” ์ˆ˜์ค€์˜ ์ž ๊ธˆ
  • ๋ช…์‹œ์ ์œผ๋กœ ํš๋“ํ•˜๊ณ  ํ•ด์ œํ•˜๋Š”๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅ
  • ์•„์ฃผ ์งง์€ ์‹œ๊ฐ„๋™์•ˆ ๊ฑธ๋ ธ๋‹ค๊ฐ€ ํ•ด์ œ๋˜๋Š” ์ž ๊ธˆ -> ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Œ
  • Auto_Increment ๊ฐ’์ด ํ•œ๋ฒˆ ์ฆ๊ฐ€ํ•˜๋ฉด ์ค„์–ด๋“ค์ง€ ์•Š๋Š” ์ด์œ  (Roll back์ด ์ผ์–ด๋‚˜๋„ auto_increment๋Š” ๊ทธ๋Œ€๋กœ์ธ ์ด์œ )
    • ์ž๋™ ์ฆ๊ฐ€ ๋ฝ์„ ์ตœ์†Œํ™” ํ•˜๊ธฐ ์œ„ํ•จ
    • INSERT ์ฟผ๋ฆฌ ์‹คํŒจ -> auto_increment ๊ฐ’์€ ์ด๋ฏธ ์ฆ๊ฐ€ -> auto_increment์˜ ๊ฐ’์„ ๊ตณ์ด ์ค„์ด์ง€ ์•Š๊ณ  ๊ทธ๋Œ€๋กœ ๋‘ 

Oracle์—๋Š” Sequence๊ฐ€ ์กด์žฌ. Sequence ๊ฐ™์€ ๊ฒฝ์šฐ ๋งŒ์•ฝ 50๋‹จ์œ„์˜ ID๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด (๋ฐฐ์น˜ Insert๋กœ 50๊ฐœ์˜ ํ–‰์„ ์ €์žฅ) 50size ๋งŒํผ์˜ ID๋“ค์„ ๊ฐ€์ ธ์™€์„œ ์ง„ํ–‰ InnoDB๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ Sequence๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„์„œ JPA์—์„œ batch insert๋ฅผ ํ•˜๊ฒŒ๋˜๋ฉด ๊ณ„์†ํ•ด์„œ DB์— ์ ‘๊ทผํ•ด์„œ ๋‹ค์Œ ์•„์ด๋”” ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. (50๋งŒ๊ฐœ๋ฉด 50๋งŒ๋ฒˆ ์ง„ํ–‰)

๋ ˆ์ฝ”๋“œ ์ˆ˜์ค€์˜ ์ž ๊ธˆ ํ™•์ธ ๋ฐ ํ•ด์ œ

  • ํŠธ๋žœ์žญ์…˜์ด ์–ด๋–ค ์ž ๊ธˆ์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š”์ง€, ์–ด๋–ค ํŠธ๋ž™์žญ์…˜์ด ํ•„์š”ํ•œ ์ž ๊ธˆ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” -> ๋ฉ”ํƒ€ ์ •๋ณด๋ฅผ ํ†ตํ•ด ์กฐํšŒ ๊ฐ€๋Šฅ
  • MySQL 5.1 ๋ถ€ํ„ฐ
    • infomation_schema์—์„œ INNODB_TRX, INNODB_LOCKS, INNODB_LOCK_WAITS๋ฅผ ํ†ตํ•ด ํ™•์ธ ๊ฐ€๋Šฅ -> Deprecated
    • performance_schema์—์„œ DATA_LOCKS, DATA_LOCK_WAITS๋ฅผ ํ†ตํ•ด ํ™•์ธ ๊ฐ€๋Šฅ

MySQL์˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€

img_4.png

  • ์ผ๋ฐ˜์ ์œผ๋กœ ์˜จ๋ผ์ธ ์„œ๋น„์Šค ์šฉ๋„์—์„œ๋Š” READ COMMITED ๋˜๋Š” REPEATABLE READ๋ฅผ ์‚ฌ์šฉ

READ UNCOMMITED

  • RDBMS ํ‘œ์ค€์—์„œ ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ์ˆ˜์ค€์œผ๋กœ ์ธ์ •ํ•˜์ง€ ์•Š์„ ์ •๋„๋กœ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์— ๋ฌธ์ œ๊ฐ€ ๋งŽ์€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€
  • MySQL์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์ตœ์†Œํ•œ READ COMMITED ์ด์ƒ์˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ์‚ฌ์šฉํ•ด์•ผํ•จ
  • DIRTY READ
    • ์–ด๋–ค ํŠธ๋žœ์žญ์…˜์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ์ž‘์—…์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋Š”๋ฐ, ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ํ˜„์ƒ
    • ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚˜ํƒ€๋‚ฌ๋‹ค ์‚ฌ๋ผ์กŒ๋‹ค ํ•˜๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ž์™€ ์‚ฌ์šฉ์ž ๋ชจ๋‘ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

READ COMMITED

  • Oracle์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€
  • ์˜จ๋ผ์ธ ์„œ๋น„์Šค์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์„ ํƒํ•˜๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€
  • ํŠธ๋žœ์žญ์…˜๊ฐ€์˜ ๊ณ ๋ฆฝ์„ ์™„์ „ํžˆ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•ด NON-REPEATABLE READ, PHANTOM READ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • NON-REPEATABLE READ
      • ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์—์„œ ๋˜‘๊ฐ™์€ SELECT ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ–ˆ์ง€๋งŒ, ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ค์ง€ ์•Š๋Š” ํ˜„์ƒ
      • ๊ธˆ์ „์ ์ธ ์ฒ˜๋ฆฌ์™€ ์—ฐ๊ฒฐ๋˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ
    • PHANTOM READ ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ
      • ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ณ€๊ฒฝ ์ž‘์—…์— ์˜ํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณด์˜€๋‹ค ์•ˆ๋ณด์˜€๋‹ค ํ•˜๋Š” ํ˜„์ƒ

REPEATABLE READ

  • MySQL์˜ InnoDB ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€
  • MVCC (Multi Version Concurrency Control)
    • ์ผ๋ฐ˜์ ์œผ๋กœ ๋ ˆ์ฝ”๋“œ ๋ ˆ๋ฒจ์˜ ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜๋Š” DBMS๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ
    • ๊ฐ€์žฅ ํฐ ๋ชฉ์ ์€ ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ผ๊ด€๋œ ์ฝ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. -> ์ด ๊ธฐ๋Šฅ์„ InnoDB๋Š” ์–ธ๋‘(undo) ๋กœ๊ทธ๋ฅผ ์ด์šฉํ•ด ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
    • READ_COMMITED ์ด์ƒ์˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์—์„œ๋Š” ์ปค๋ฐ‹๋˜๊ธฐ ์ „ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒ ์‹œ InnoDB ๋ฒ„ํผ ํ’€์ด๋‚˜ ๋ฐ์ดํ„ฐํŒŒ์ผ์˜ ๋‚ด์šฉ์ด ๋ณ€๊ฒฝ๋˜์ง€ ์ „์˜ ๋‚ด์šฉ์„ ๋ณด๊ด€ํ•˜๋Š” ์–ธ๋‘ ์˜์—ญ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ์ฆ‰ Update ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋์„ ๋•Œ InnoDB ๋ฒ„ํผ ํ’€์€ ์ฆ‰์‹œ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝ๋˜๋ฉฐ ๊ธฐ์กด์˜ ๋ฐ์ดํ„ฐ๋Š” ์–ธ๋‘๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
    • ๋งŒ์•ฝ update ์ฟผ๋ฆฌ๊ฐ€ ์ปค๋ฐ‹๋˜์ง€ ์•Š๊ณ  ๋กค๋ฐฑ๋˜๋ฉด InnoDB๋Š” ์–ธ๋‘ ์˜์—ญ์— ๋ฐฑ์—…๋œ ๋ฐ์ดํ„ฐ๋ฅผ InnoDB ๋ฒ„ํผํ’€๋กœ ๋ณต๊ตฌํ•˜๊ณ  ํ•ด๋‹น ์–ธ๋‘ ์˜์—ญ์˜ ๋‚ด์šฉ์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
  • InnoDB์˜ ํŠธ๋žœ์žญ์…˜์€ ๊ณ ์œ ํ•œ ํŠธ๋žœ์žญ์…˜ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.(์ˆœ์ฐจ์ ์œผ๋กœ ์ฆ๊ฐ€)
  • ํ…Œ์ด๋ธ”๊ณผ ์–ธ๋‘๋กœ๊ทธ์˜ ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ์—๋Š” ๋ณ€๊ฒฝ์„ ๋ฐœ์ƒ์‹œํ‚จ ํŠธ๋žœ์žญ์…˜์˜ ๋ฒˆํ˜ธ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • 1๊ฐœ์˜ ๋ ˆ์ฝ”๋“œ์— 1๊ฐœ ์ด์ƒ์˜ ๋ฐฑ์—… ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์‚ฌ์šฉ์ž๊ฐ€ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ  ์žฅ์‹œ๊ฐ„ ์ข…๋ฃŒํ•˜์ง€ ์•Š์œผ๋ฉด?
      • ์–ธ๋‘๋กœ๊ทธ ํฌ๊ธฐ๊ฐ€ ๋ฐฑ์—…๋ฐ์ดํ„ฐ๋กœ ์ธํ•ด ๋ฌดํ•œ์ • ์ปค์งˆ ์ˆ˜ ์žˆ์Œ
      • MySQL ์„œ๋ฒ„์˜ ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง
  • PHANTOM READ ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ

SERIALIZABLE

  • ๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ + ๊ฐ€์žฅ ์—„๊ฒฉํ•œ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€
  • ๋‹ค๋ฅธ ํŠธ๋ž™์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€๋ณด๋‹ค ๋™์‹œ ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง
  • ํ•œ ํŠธ๋žœ์žญ์…˜์—์„œ ์ฝ๊ธฐ or ์“ฐ๊ธฐ ์ž‘์—…์ค‘์ธ ๋ ˆ์ฝ”๋“œ๋Š” ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒํ•จ