ํต์ฌ ์์ฝ
์ต๊ทผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ผ์ผ ์ ๊ฒ์ ์๋ํํ๋ ํ๋ก์ ํธ๋ฅผ ๋งก๊ฒ ๋๋ฉด์, DBA๊ฐ ๋งค์ผ ๋ค์ฌ๋ค๋ณด๋ ๋ชจ๋ํฐ๋ง ์งํ๋ค์ ์ฒ์๋ถํฐ ์ ๋ฆฌํ๊ณ ์์ต๋๋ค. ์ฒซ ๊ธ์์ MySQL, ๋ ๋ฒ์งธ ๊ธ์์ Oracle์ ๋ค๋ค๋๋ฐ, ์ด๋ฒ PostgreSQL์ด ์๋ฆฌ์ฆ์ ๋ง์ง๋ง์ ๋๋ค. PostgreSQL์ ๊ฐ์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ด๋ฉด์๋ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ์์ด ์์ ๋๊ณผ ๋ ๋ฌ๋ผ์, ์งํ ์ด๋ฆ์๋ ๋ค๋ฅธ DB์๋ ์๋ ๋จ์ด๋ค์ด ๋ณด์์ต๋๋ค. Dead Tuple, VACUUM, Age, autovacuum ๊ฐ์ ๋ง์ด ๊ทธ๋ ์ต๋๋ค. ๊ทธ๋์ ์ด๋ฒ์๋ ํ๋์ฉ ์ ๋ฆฌํด ๋๊ธฐ๋ก ํ์ต๋๋ค.
์ด ๊ธ์์๋ PostgreSQL(๋ฐ PostgreSQL on RDS)์์ ์์ฃผ ๋ณด๋ ์งํ๋ค์ โ ๋ฌด์์ ์๋ฏธํ๋์ง โก ํ์ ์ด๋ ์ ๋ ๊ฐ์ด ์ ์์ธ์ง(์ค์ ๊ด์ธก ๋ฒ์·ํ๊ท ) โข ๊ฐ์ด ํ๋ฉด ๋ฌด์์ ์์ฌํด์ผ ํ๋์ง โฃ ํจ๊ป ๋ณด๋ฉด ์ข์ ์งํ โค ์ง์ ํ์ธํ๋ ์ฟผ๋ฆฌ๋ก ๋ฌถ์ด ์ ๋ฆฌํ์ต๋๋ค. PostgreSQL๋ง์ ๊ฐ๋ (ํ๋ก์ธ์ค ๊ธฐ๋ฐ backend, MVCC, Dead Tuple, VACUUM·autovacuum, ํธ๋์ญ์ ID wraparound์ Age, shared_buffers, WAL)์ ์งํ๋ฅผ ๋ณด๊ธฐ ์ ์ ๋จผ์ ํ ๋ฒ ํ์ด ๋์์ต๋๋ค. ์ด ๊ฐ๋ ๋ค์ด ๊ทธ๋๋ก ๋ค์ ์งํ๋ก ์ด์ด์ง๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ฐ ์งํ๋ง๋ค ๊ทธ๊ฒ์ ์ค์ ๋ก ์์ง์ด๊ฒ ๋ง๋๋ ์ฟผ๋ฆฌ ํจํด์ "๋์ ์ → ๊ณ ์น ์" SQL๋ก ๊ฐ๋ฅํ ํ ํจ๊ป ์ ์๊ณ , ์ค์ ์ฅ์ ๋ก ์ด์ด์ง๋ ์๋๋ฆฌ์ค๋ ๋ถ์์ต๋๋ค.
๋ณธ๋ฌธ์ "๊ด์ธก๊ฐ"์ ์ค์ ์ด์ ์ธ์คํด์ค ํ ๋์์ 1๋ถ ๊ฐ๊ฒฉ์ผ๋ก ํ ๋ฌ๊ฐ ์์งํ ๊ฐ์ ๋๋ค. ์ธ์คํด์ค๋ง๋ค ๋ค๋ฅด๋ฏ๋ก ์ ๋์ ์ธ ๊ธฐ์ค์ ์๋๊ณ , "๋ณดํต ์ด ์ ๋๊ตฌ๋"๋ฅผ ๊ฐ ์ก๋ ์ฉ๋์ ๋๋ค.
PostgreSQL์ ์ด๋ค ๋ฐ์ดํฐ๋ฒ ์ด์ค์ธ๊ฐ
์งํ๋ฅผ ๋ณด๊ธฐ ์ ์, PostgreSQL์ด MySQL·Oracle๊ณผ ์ด๋ป๊ฒ ๋ค๋ฅธ์ง๋ถํฐ ์ง๊ณ ๊ฐ๊ฒ ์ต๋๋ค.
- PostgreSQL: ์คํ์์ค์ด๋ฉด์ ํ์ค ์ค์์ ํ์ฅ์ฑ์ด ๊ฐ์ ์ ๋๋ค. ๋ณต์กํ ์ฟผ๋ฆฌ, ๋ค์ํ ๋ฐ์ดํฐ ํ์ (JSON·๋ฐฐ์ด·์ง๋ฆฌ์ ๋ณด ๋ฑ), ํ๋ถํ ๊ธฐ๋ฅ, ์ฌ์ฉ์ ์ ์ ํ์ฅ(extension)์ด ํ์ํ ๊ณณ์ ์ ๋ง์ต๋๋ค. "๊ธฐ๋ฅ์ด ๋ง๊ณ ์ ์์ ์ถฉ์คํ ์คํ์์ค DB" ๋ผ๋ ํ์ ์ค๋ ๋ฐ์ ์์ต๋๋ค.
- MySQL: ์คํ์์ค์ด๊ณ ๊ฐ๋ณ๊ณ ๋น ๋ฆ ๋๋ค. ์ฝ๊ธฐ๊ฐ ๋ง์ ์น ์๋น์ค์์ ์ค๋ ์ฌ๋๋ฐ์ ์๊ณ , ์คํ ๋ฆฌ์ง ์์ง(InnoDB ๋ฑ)์ ๊ฐ์ ๋ผ์ธ ์ ์๋ ๊ฒ์ด ๊ตฌ์กฐ์ ํน์ง์ ๋๋ค.
- Oracle: ์์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ ๊ฒฉ์ผ๋ก, ๋๊ธฐ์ ์ ํต์ฌ ์ ๋ฌด ์์คํ ์ ๋ง์ด ์๋๋ค. ๊ธฐ๋ฅ์ด ๊ฐ๋ ฅํ๊ณ ์์ ์ ์ธ ๋์ ๋ผ์ด์ ์ค ๋น์ฉ์ด ๋น์๋๋ค.
์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ CPU·๋ฉ๋ชจ๋ฆฌ·์ธ์ ·I/O ๊ฐ์ ๊ณตํต ์งํ๋ฅผ ๋ณด์ง๋ง, ๊ทธ ์์ ๊ฐ์ ๊ณ ์ ํ ์งํ๊ฐ ์นํ๋๋ค. MySQL์ InnoDB์์ ๋์ค๋ ์งํ(๋ฒํผํ ์ ์ค๋ฅ , Row Lock Waits)๊ฐ ๋ง์๊ณ , Oracle์ Redo·Undo·Library Cache·ํ์ฑ์์ ๋์ค๋ ์งํ๊ฐ ๋ง์์ต๋๋ค. PostgreSQL์ MVCC·Dead Tuple·VACUUM·ํธ๋์ญ์ ID(Age) ์์ ๋์ค๋ ์งํ๊ฐ ๊ทธ DB๋ง์ ์๊น์ ๋๋ค. ์ด ๋จ์ด๋ค์ด ์ฒ์์ด๋ฉด ์งํ ์ด๋ฆ์ด ์ธ๊ณ์ด์ฒ๋ผ ๋ณด์ด๋ฏ๋ก, ํต์ฌ ๊ฐ๋ ์ ๋จผ์ ์ฝ๊ฒ ํ์ด ๋๊ฒ ์ต๋๋ค. ์๋ ๊ฐ๋ ๋ค์ด ๊ทธ๋๋ก ๋ค์ ์งํ๋ก ์ด์ด์ง๋๋ค.
PostgreSQL์ ํต์ฌ ๊ฐ๋ ๋จผ์ ํ๊ธฐ
- ํ๋ก์ธ์ค ๊ธฐ๋ฐ backend: PostgreSQL์ ํด๋ผ์ด์ธํธ๊ฐ ์ ์ํ ๋๋ง๋ค ๋ณ๋์ ์ด์์ฒด์ ํ๋ก์ธ์ค(backend process) ๋ฅผ ํ๋์ฉ ๋์๋๋ค. MySQL์ด ์ฐ๊ฒฐ๋ง๋ค "์ค๋ ๋" ๋ฅผ ๋์ฐ๋ ๊ฒ๊ณผ ๋ฌ๋ฆฌ, PostgreSQL์ ์ฐ๊ฒฐ๋ง๋ค "ํ๋ก์ธ์ค" ๋ฅผ ๋์๋๋ค. ๊ทธ๋์ PostgreSQL ์งํ์์ ์ธ์ ์๋ฅผ "Backend(๋ฐฑ์๋)" ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. ์ฐ๊ฒฐ์ด 800๊ฐ๋ฉด backend ํ๋ก์ธ์ค๊ฐ 800๊ฐ ๋ ์๋ ์ ์ ๋๋ค. ํ๋ก์ธ์ค๋ ์ค๋ ๋๋ณด๋ค ๋ง๋๋ ๋น์ฉ์ด ์ปค์, PostgreSQL์์ ์ปค๋ฅ์ ํ(๋๋ PgBouncer ๊ฐ์ ๋ณ๋ ํ๋ฌ)์ด ํนํ ์ค์ํ ์ด์ ๊ฐ ์ฌ๊ธฐ ์์ต๋๋ค.
- MVCC(๋ค์ค ๋ฒ์ ๋์์ฑ ์ ์ด): PostgreSQL์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ฟ ๋ ์๋ ํ์ ๊ทธ ์๋ฆฌ์์ ๋ฎ์ด์ฐ์ง ์์ต๋๋ค. ๋์ ์ ๋ฒ์ ์ ํ์ ๋ฐ๋ก ๋ง๋ค๊ณ , ์ ๋ฒ์ ์ "์ด์ ์ ์ฐ๋ ํ" ์ผ๋ก ํ์๋ง ํด ๋ก๋๋ค. ์ด๋ ๊ฒ ํ ๋ฐ์ดํฐ์ ์ฌ๋ฌ ๋ฒ์ ์ ๋์์ ๋๋ ๋ฐฉ์์ด MVCC์ ๋๋ค. ๋๋ถ์ ๋๊ตฐ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ๋ ์ค์๋ ๋ค๋ฅธ ์ฌ๋์ ๋งํ์ง ์๊ณ ๋ฐ๋๊ธฐ ์ ์ ๊นจ๋ํ ๋ฒ์ ์ ์ฝ์ ์ ์์ต๋๋ค(์ฝ๊ธฐ๊ฐ ์ฐ๊ธฐ๋ฅผ ๋ง์ง ์์). Oracle์ด ๋ณ๊ฒฝ ์ ๊ฐ์ Undo๋ผ๋ ๋ณ๋ ๊ณต๊ฐ์ ๋๋ ๊ฒ๊ณผ ๋ฌ๋ฆฌ, PostgreSQL์ ์ ๋ฒ์ ์ ํ ์ด๋ธ ์์ ๊ทธ๋๋ก ๋จ๊ฒจ ๋๋ค๋ ์ ์ด ๋ค๋ฆ ๋๋ค.
- Dead Tuple(์ฃฝ์ ํ): ์ MVCC ๋๋ฌธ์, UPDATE๋ DELETE๋ฅผ ํ๋ฉด ์ ๋ฒ์ ์ ํ์ด ํ ์ด๋ธ ์์ "์ฃฝ์ ํ(dead tuple)" ์ผ๋ก ๋จ์ต๋๋ค. UPDATE ํ ๋ฒ์ ์ค์ ๋ก๋ "์ ๋ฒ์ ์ถ๊ฐ + ์ ๋ฒ์ ์ ์ฃฝ์ ํ์ผ๋ก ํ์" ์ ๋๋ค. ์ฃฝ์ ํ์ ์๋ฌด๋ ์ ๋ณด์ง๋ง ๋์คํฌ ๊ณต๊ฐ์ ๊ณ์ ์ฐจ์งํฉ๋๋ค. ๊ทธ๋์ UPDATE·DELETE๊ฐ ๋ง์ ํ ์ด๋ธ์ ์๊ฐ์ด ์ง๋๋ฉด ์ฃฝ์ ํ์ด ์์ฌ ์ค์ ๋ฐ์ดํฐ๋ณด๋ค ํจ์ฌ ์ปค์ง๋๋ฐ, ์ด๊ฒ์ "ํ ์ด๋ธ ํฝ์ฐฝ(bloat)" ์ด๋ผ๊ณ ํฉ๋๋ค. ์ฒญ์๋ฅผ ์ ํ ๋ฐฉ์ ๋น ์์๊ฐ ์์ด๋ ๊ฒ๊ณผ ๋น์ทํฉ๋๋ค.
- VACUUM·autovacuum(์ฃฝ์ ํ ์ฒญ์): ์์ธ ์ฃฝ์ ํ์ ์ ๋ฆฌํด ๊ทธ ๊ณต๊ฐ์ ๋ค์ ์ธ ์ ์๊ฒ ํ์ํ๋ ์์
์ด VACUUM ์
๋๋ค. ์ฌ๋์ด ์ง์
VACUUM๋ช ๋ น์ ๋๋ฆด ์๋ ์์ง๋ง, ๋ณดํต์ PostgreSQL์ด ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์์์ ๋๋ฆฌ๋ autovacuum ์ด ์ด ์ผ์ ํฉ๋๋ค. autovacuum์ด ์ฃฝ์ ํ์ ์ ๋ ์น์ ์ฃผ๋ฉด ํ ์ด๋ธ์ด ๊นจ๋ํ๊ฒ ์ ์ง๋๊ณ , ๋ชป ๋ฐ๋ผ๊ฐ๋ฉด ์ฃฝ์ ํ์ด ์์ฌ ํ ์ด๋ธ์ด ํฝ์ฐฝํ๊ณ ์ฟผ๋ฆฌ๊ฐ ๋๋ ค์ง๋๋ค. ์ฒญ์๋ถ๊ฐ ๋ถ์ง๋ฐํ๋ฉด ๋ฐฉ์ด ๊นจ๋ํ๊ณ , ๊ฒ์ผ๋ฅด๋ฉด ๋น ์์๊ฐ ์์ด๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. - ํธ๋์ญ์ ID wraparound์ Age: PostgreSQL์ ๋ชจ๋ ํธ๋์ญ์ ์ ๋ฒํธ(ํธ๋์ญ์ ID, XID)๋ฅผ ๋งค๊น๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด ๋ฒํธ๋ ์ฝ 21์ต(32๋นํธ)์์ ํ ๋ฐํด ๋์ ๋ค์ 0์ผ๋ก ๋์์ค๋ ๊ตฌ์กฐ์ ๋๋ค. ์ด๊ฒ์ wraparound(๋ฉ์ด๋ผ์ด๋) ๋ผ๊ณ ํฉ๋๋ค. ๋ง์ฝ ์์ฃผ ์ค๋๋ ํ์ ์ ์ ํ "freeze(๋๊ฒฐ)" ์ฒ๋ฆฌํ์ง ์์ ์ฑ ๋ฒํธ๊ฐ ํ ๋ฐํด ๋๋ฉด, ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๊ฐ ๋ฏธ๋๋ก ๋ณด์ด๋ ์ฌ๊ฐํ ๋ฌธ์ ๊ฐ ์๊ฒจ DB๊ฐ ์ ์ฐ๊ธฐ๋ฅผ ๊ฑฐ๋ถํ๊ณ ๋ฉ์ถฅ๋๋ค. ๊ทธ๋์ PostgreSQL์ ๊ฐ์ฅ ์ค๋๋ ํธ๋์ญ์ ์ด ์ง๊ธ์ผ๋ก๋ถํฐ ์ผ๋ง๋ ๋จ์ด์ก๋์ง๋ฅผ Age(๋์ด) ๋ก ์ถ์ ํ๊ณ , ์ด ๋์ด๊ฐ ์ํ ์์ค์ ๊ฐ๊น์์ง๋ฉด autovacuum์ด freeze ์์ ์ ํด์ ํ ๋ฐํด ๋๋ ์ฌ๊ณ ๋ฅผ ๋ง์ต๋๋ค. ๋์๊ด ๋์ถ์ฆ ๋ฒํธ๊ฐ ์ธ์ ๊ฐ ๋ค์ ์ฒ์ ๋ฒํธ๋ก ๋์์จ๋ค๋ฉด, ๋๋ฌด ์ค๋๋ ๊ธฐ๋ก์ ๋ฏธ๋ฆฌ ์ ๋ฆฌํด ๋ฌ์ผ ์ ๋ฒํธ์ ํท๊ฐ๋ฆฌ์ง ์๋ ๊ฒ๊ณผ ๋น์ทํฉ๋๋ค. ๋ค์ Age Used Ratio·Current Age ์งํ๊ฐ ๋ฐ๋ก ์ด ๋์ด๋ฅผ ๋ด ๋๋ค.
- shared_buffers(๋ฒํผ ์บ์): PostgreSQL์ด ์์ฃผ ์ฐ๋ ๋ฐ์ดํฐ·์ธ๋ฑ์ค ๋ธ๋ก์ ์บ์ฑํด ๋๋ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๋๋ค. MySQL์ ๋ฒํผํ, Oracle์ ๋ฒํผ ์บ์์ ํด๋นํฉ๋๋ค. ๋์คํฌ์์ ํ ๋ฒ ์ฝ์ด ์จ ๋ธ๋ก์ ์ฌ๊ธฐ ์ฌ๋ ค ๋๊ณ , ๋ค์์ ๊ฐ์ ๋ธ๋ก์ด ํ์ํ๋ฉด ๋์คํฌ๊น์ง ์ ๊ฐ๊ณ ์ฌ๊ธฐ์ ๋ฐ๋ก ๊บผ๋ ๋๋ค. ๋ค์ Cache Hit Ratio·Blks Hit·Blks Read ์งํ๊ฐ ์ด ์บ์์ ์ ์ค์ ๋ด ๋๋ค.
- WAL(๋ณ๊ฒฝ ๋ก๊ทธ): ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ฟ ๋๋ง๋ค "๋ฌด์์ ์ด๋ป๊ฒ ๋ฐ๊ฟจ๋์ง" ๋ฅผ ๋จผ์ ์ ์ด ๋๋ ๊ธฐ๋ก์ ๋๋ค(Write-Ahead Log). ์ฅ์ ๋ก DB๊ฐ ๊ฐ์๊ธฐ ์ฃฝ์ด๋ ์ด ๊ธฐ๋ก์ ๋ค์ ์ ์ฉํด ๋ณต๊ตฌํฉ๋๋ค. Oracle์ Redo์ ํด๋นํฉ๋๋ค. ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ด ๋ง์ผ๋ฉด WAL๋ ๋ง์ด ๋ฐ์ํฉ๋๋ค.
- ๋ธ๋ก(block): PostgreSQL์ด ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ฐ๋ ์ต์ ๋จ์์ ๋๋ค(๋ณดํต 8KB). ํ ํ๋ํ๋๊ฐ ์๋๋ผ ์ฌ๋ฌ ํ์ด ๋ด๊ธด ๋ธ๋ก ๋จ์๋ก ๋์คํฌ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ค๊ฐ๋๋ค. ๋ค์ Blks Read·Blks Hit๊ฐ ์ด ๋ธ๋ก ์๋ฅผ ์ ๋๋ค.
์ด ๊ฐ๋ ๋ค์ ๋จธ๋ฆฌ์ ๋ฃ๊ณ ๋ณด๋ฉด, ๋ค์ ๋์ค๋ 32๊ฐ ์งํ๊ฐ ๋ฐ๋ก ๋ ธ๋ ์ซ์๊ฐ ์๋๋ผ ํ๋์ ๊ทธ๋ฆผ์ผ๋ก ์ด์ด์ง๋๋ค. ํนํ "UPDATE/DELETE → ์ฃฝ์ ํ ๋ฐ์ → VACUUM์ด ์ฒญ์ → ๋ชป ๋ฐ๋ผ๊ฐ๋ฉด ํฝ์ฐฝ·Age ์์น" ์ด๋ผ๋ ํ ์ค๊ธฐ๊ฐ PostgreSQL ์งํ๋ฅผ ๊ดํตํฉ๋๋ค.
๋ค์ด๊ฐ๊ธฐ ์ ์ — ์งํ๋ฅผ ๋ณด๋ ๋ ๊ฐ์ง ๊ด์
์งํ๋ฅผ ๋ณผ ๋๋ ๋ณดํต ๋ ๊ฐ์ง ๊ธฐ์ค์ ๊ฐ์ด ์๋๋ค.
์ฒซ์งธ๋ ์ ๋ ์๊ณ๊ฐ์ ๋๋ค. "CPU ์ฌ์ฉ๋ฅ 90% ์ด์์ด๋ฉด ์ํ" ์ฒ๋ผ ๋ฏธ๋ฆฌ ์ ํ ์ ์ ๋์๋์ง ๋ด ๋๋ค. ๊ธฐ์ค์ด ๋ช ํํ์ง๋ง, DB๋ง๋ค ์ ์ ๋ฒ์๊ฐ ๋ฌ๋ผ ์๊ณ๊ฐ๋ DB๋ณ๋ก ๋ค๋ฅด๊ฒ ์ก์์ผ ํฉ๋๋ค. ์ค์ ๋ก ๊ฐ์ CPU ์ฌ์ฉ๋ฅ ์ด๋ผ๋ PostgreSQL ์ธ์คํด์ค๋ ๊ฒฝ๊ณ 85% / ์ํ 90%๋ก, MySQL·Oracle(๊ฒฝ๊ณ 60% / ์ํ 80%)๋ณด๋ค ๋๊ฒ ์กํ ์์ต๋๋ค. ์ธ์คํด์ค ํน์ฑ์ ๋ฐ๋ผ ํ์ ๋ถํ ์์ค์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋์งธ๋ ํ์ ๋๋น ๋ณํ์ ๋๋ค. ์๊ณ๊ฐ์ ๋์ง ์์๋๋ผ๋ "์ด์ ๊น์ง ํ๊ท 10์ด๋ ๊ฐ์ด ์ค๋ 40์ผ๋ก ๋ฐ์๋ค" ๋ฉด ๋ฌด์ธ๊ฐ ๋ฌ๋ผ์ง ๊ฒ์ ๋๋ค. ๋น์ ํ์๋ฉด ์ ๋ ์๊ณ๊ฐ์ ๊ฑด๊ฐ๊ฒ์ง์ ์ ์ ์์นํ์ด๊ณ , ํ์ ๋๋น ๋ณํ๋ ํ์ ๋ด ์ปจ๋์ ๊ณผ ๋น๊ตํ๋ ๊ฒ์ ๋๋ค. ๋ ๋ค ๋ด์ผ ๋์น๋ ๊ฒ์ด ์์ต๋๋ค. PostgreSQL์๋ Tup Updated·Tup Deleted๋ Temp Bytes์ฒ๋ผ ํ์์ ์๋ค๊ฐ ๋ฐฐ์น ๋ ํฌ๊ฒ ํ๋ ์งํ๊ฐ ๋ง์์, ํนํ "ํ์ ๋๋น ๋ณํ" ๊ฐ ์ค์ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ํ ๊ฐ์ง ๋, ์งํ๋ ๊ฑฐ์ ํผ์ ํ์ง ์์ต๋๋ค. ๊ทธ๋์ ๊ฐ ์งํ๋ง๋ค "ํจ๊ป ํ์ธํ ์งํ" ๋ฅผ ๋ถ์์ต๋๋ค. ์ด๋ค ๊ฐ์ด ํ์์ ๋ ์์ ์งํ๊ฐ ๊ฐ์ด ์ฌ๋๋์ง๋ก ์์ธ์ ๋ฐฉํฅ์ด ๊ฐ๋ฆฌ๊ธฐ ๋๋ฌธ์ ๋๋ค.
1. CPU · ๋ฉ๋ชจ๋ฆฌ
์๋ฒ๊ฐ ์ผ๋ง๋ ๋ฐ์์ง๋ฅผ ๋ณด๋ ๊ธฐ๋ณธ ์์ญ์ ๋๋ค. ์๋น์ ๋น์ ํ๋ฉด CPU๋ ์ฃผ๋ฐฉ์ ๋ฐ์ ์ ๋, ๋ฉ๋ชจ๋ฆฌ๋ ์กฐ๋ฆฌ๋์ ๋์ด์ ๋๋ค. ์ฃผ๋ฌธ์ด ๋ชฐ๋ฆฌ๋ฉด ์ฃผ๋ฐฉ์ด ๋ฐ๋น ์ง๊ณ (CPU↑), ์ฌ๋ฃ๋ฅผ ๋ฏธ๋ฆฌ ๊บผ๋ด๋ ์กฐ๋ฆฌ๋๊ฐ ์ข์ผ๋ฉด ๊ทธ๋๊ทธ๋ ์ฐฝ๊ณ ๋ฅผ ์ค๊ฐ์ผ ํฉ๋๋ค(๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ → ๋์คํฌ ์ ๊ทผ↑).
์ด ์์ญ์ ์ฒ์ ๋ณด๋ฉด ๋งํ๋ ๋จ์ด๋ฅผ ๋จผ์ ์งง๊ฒ ํ์ด ๋๊ฒ ์ต๋๋ค.
- ์ค์(swap): ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ชจ์๋ ๋ ์ด์์ฒด์ ๊ฐ ๋์คํฌ์ ์ผ๋ถ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ฒ๋ผ ๋น๋ ค ์ฐ๋ ๊ฒ์ ๋๋ค. ๋ฉ๋ชจ๋ฆฌ๋ ๋น ๋ฅด๊ณ ๋์คํฌ๋ ํจ์ฌ ๋๋ฆฌ๊ธฐ ๋๋ฌธ์, ์ค์์ด ์์๋๋ฉด ๋ชจ๋ ์์ ์ด ๊ฐ์๊ธฐ ๋๋ ค์ง๋๋ค.
- work_mem(์์
๋ฉ๋ชจ๋ฆฌ): PostgreSQL์ด ์ ๋ ฌ(
ORDER BY)·ํด์ ์กฐ์ธ·๊ทธ๋ฃนํ(GROUP BY) ๊ฐ์ ์์ ์ ํ ๋ ์ฐ๋ backend ํ ๊ฐ๋น ์์ ๊ณต๊ฐ์ ๋๋ค. ์ด ๊ณต๊ฐ ์์์ ๋๋๋ฉด ๋น ๋ฅด์ง๋ง, ์ฒ๋ฆฌํ ์์ด ์ด ํ๋๋ฅผ ๋์ผ๋ฉด ์์ ํ์ผ(temp file)์ ๋์คํฌ์ ๋ง๋ค์ด ์ฒ๋ฆฌํด ๋๋ ค์ง๋๋ค(๋ค์ Temp Bytes·Temp Files๊ฐ ์ด๊ฒ์ ๋ด ๋๋ค).
(OS) Cpu Usage (%)
์๋ฒ์ CPU ์ฌ์ฉ๋ฅ ์ ๋๋ค. ๊ฐ์ฅ ๋จผ์ ๋ณด๋ ์งํ์ด๊ณ ์๋ฏธ๋ ์ง๊ด์ ์ ๋๋ค. CPU๋ ๊ฒฐ๊ตญ ์ฟผ๋ฆฌ๋ฅผ ์ค์ ๋ก ๊ณ์ฐํ๋ ์ผ๊พผ์ด๋ผ, ๋ฌด๊ฑฐ์ด ์ฐ์ฐ(์ ๋ ฌ·์กฐ์ธ·์ง๊ณ·ํ ์ค์บ)์ด ๋ง์์ง์๋ก ์ฌ๋ผ๊ฐ๋๋ค. PostgreSQL์์๋ autovacuum์ด ํฐ ํ ์ด๋ธ์ ์ฒญ์ํ ๋๋ CPU๋ฅผ ์ด๋ ์ ๋ ์๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 18.0%, ๋ฒ์ ์ฝ 8.3 ~ 52.4%. MySQL ์ธ์คํด์ค๋ณด๋ค ๋๊ฒ ๊น๋ ค ์๊ณ , ์๊ฐ์ ์ผ๋ก 50%๋๊น์ง ์ค๋ฅด๊ธฐ๋ ํฉ๋๋ค.
- ์ํ ์ ํธ: ์ด ์ธ์คํด์ค์ ์๊ณ๋ ๊ฒฝ๊ณ 85% / ์ํ 90%๋ก ์กํ ์์ต๋๋ค. 90%๋ฅผ ๋์ด ์ง์๋๋ฉด ์ฟผ๋ฆฌ ์๋ต์ด ๋๋ ค์ง๊ธฐ ์์ํฉ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ๋ฌด๊ฑฐ์ด ์ฟผ๋ฆฌ(ํ ์ค์บ·์ ๋ ฌ·์กฐ์ธ), ๊ฐ์๊ธฐ ๋์ด๋ ํ์ฑ backend, ๋๋ ๋ฐฐ์น, ํฐ ํ ์ด๋ธ์ ๋ํ autovacuum ๋์. CPU๋ง ๋จ๋ ์ผ๋ก ํ๋ ๊ฒฝ์ฐ๋ ๋๋ฌผ๊ณ ๋ณดํต Active Backend๋ ์ฝ๊ธฐ๋(Blks Read·Blks Hit)์ด ๊ฐ์ด ์ฌ๋ผ๊ฐ๋๋ค.
PostgreSQL์์ CPU๋ฅผ ๋์ด์ฌ๋ฆฌ๋ ์ ํ์ ์ธ ์ฟผ๋ฆฌ๋ "ํ ์ผ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋ ์๋" ํํ์ ๋๋ค. ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๋ ์กฐ๊ฑด, ํจ์๋ก ๊ฐ์ผ ์ปฌ๋ผ์ด ๋ํ์ ์ ๋๋ค.
-- ๋์ ์: created_at์ ์ธ๋ฑ์ค๊ฐ ์์ด๋ ํจ์(date)๋ก ๊ฐ์ธ๋ฉด ์ธ๋ฑ์ค๊ฐ ๋ฌด๋ ฅํ๋๋ค
-- ํ ์ค์บ + ํจ์ ์ฐ์ฐ์ด ๊ฒน์ณ CPU๋ฅผ ํฌ๊ฒ ์ด๋ค
SELECT * FROM orders
WHERE date(created_at) = DATE '2026-06-18';
-- ๊ณ ์น ์: ํจ์ ์์ด ๋ฒ์ ์กฐ๊ฑด์ผ๋ก ๋ฐ๊พธ๋ฉด ์ธ๋ฑ์ค๋ฅผ ํ๋ค
SELECT order_id, member_id, total_amount, created_at
FROM orders
WHERE created_at >= TIMESTAMP '2026-06-18 00:00:00'
AND created_at < TIMESTAMP '2026-06-19 00:00:00';
์ง๊ธ ๋ฌด์์ด CPU๋ฅผ ์ฐ๊ณ ์๋์ง๋ ์คํ ์ค์ธ ์ฟผ๋ฆฌ๋ถํฐ ๋ด ๋๋ค.
-- ์ง๊ธ active ์ํ์ธ backend๊ฐ ์ด๋ค ์ฟผ๋ฆฌ๋ฅผ ๋๋ฆฌ๊ณ ์๋์ง (์ค๋ ๊ฑธ๋ฆฐ ์์)
SELECT pid, usename, state,
now() - query_start AS running_for,
query
FROM pg_stat_activity
WHERE state = 'active'
AND backend_type = 'client backend'
ORDER BY running_for DESC;
- ํจ๊ป ํ์ธํ ์งํ: Blks Read·Blks Hit๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๋ ํ ์ค์บ/๋ฌด๊ฑฐ์ด ์ฝ๊ธฐ ์ฟผ๋ฆฌ๊ฐ CPU๋ฅผ ๋จน๋ ๊ฒ์ ๋๋ค. Active Backend๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ์ฟผ๋ฆฌ๊ฐ ๋นจ๋ฆฌ ๋๋์ง ๋ชปํ๊ณ ์์ด๋ ์ค์ ๋๋ค. Tup Updated·Tup Deleted๊ฐ ๊ฐ์ด ๋ฐ๋ฉด → ๋๋ ๋ณ๊ฒฝ ๋ฐฐ์น๊ฐ ๋๋ฉฐ ์ฃฝ์ ํ์ ๋ง๋ค๊ณ autovacuum๊น์ง ์ผ์ ์์ํ ๊ฒ์ผ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ์ ๋ ฌ·์ง๊ณ·๋ฌธ์์ด ๊ฐ๊ณต์ ์ ๋ถ DB ์ฟผ๋ฆฌ์ ๋ชฐ์๋ฃ์ผ๋ฉด ๊ทธ ๊ณ์ฐ ๋ถ๋ด์ด ๊ทธ๋๋ก CPU๋ก ์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฒ๋ฆฌํ ์ ์๋ ๊ฐ๊ณต์ ์ฝ๋ ์ชฝ์ผ๋ก ์ฎ๊ธฐ๊ฑฐ๋, ์์ฃผ ์ฐ๋ ์ง๊ณ๋ ๋ฏธ๋ฆฌ ๊ณ์ฐํ ์ง๊ณ ํ ์ด๋ธ์ ๋๋ฉด ์ํ๋ฉ๋๋ค. ๋ ์ปฌ๋ผ์ ํจ์๋ก ๊ฐ์ธ๋ ์กฐ๊ฑด(
date(col) = ...)์ ์ธ๋ฑ์ค๋ฅผ ๋ฌด๋ ฅํํด ํ ์ค์บ์ ์ ๋ฐํ๋ฏ๋ก, ๋ฒ์ ์กฐ๊ฑด์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ์ด ๊ธฐ๋ณธ์ ๋๋ค.
(OS) Memory Percent (%)
์ด์์ฒด์ ๊ด์ ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ (%)์ ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 79.4%, ๋ฒ์ 78.2 ~ 82.3%๋ก ํํํ๊ฒ ์ ์ง๋์ต๋๋ค. MySQL(์ฝ 54%)·Oracle(์ฝ 56%) ์ธ์คํด์ค๋ณด๋ค ๋๊ฒ ๊น๋ ค ์๋๋ฐ, ์ด๋ ์ธ์คํด์ค ํฌ๊ธฐ·shared_buffers ์ค์ ์ ๋ฐ๋ฅธ ์ฐจ์ด์ ๋๋ค. ๊ทธ๋์ ์ ๋๊ฐ๋ณด๋ค ์ถ์ธ๊ฐ ์ค์ํฉ๋๋ค.
- ์ํ ์ ํธ: ๊ฒฝ๊ณ 90%, ์ํ 95%. ๋ค๋ง ๋จ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊พธ์คํ ์ค์ด๋๋ ์ถ์ธ๊ฐ ๋ ์ํํฉ๋๋ค. ๊ณ ๊ฐ๋๋ฉด OS๊ฐ ์ค์(๋์คํฌ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ฒ๋ผ ์ฐ๋ ๊ฒ)์ ์์ํ๊ณ , ๊ทธ๋๋ถํฐ ์ฑ๋ฅ์ด ๊ธ๊ฒฉํ ๋๋น ์ง๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: backend ํญ์ฆ(์ฐ๊ฒฐ๋ง๋ค ํ๋ก์ธ์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์), ํฐ ์ ๋ ฌ·ํด์ ์กฐ์ธ์ผ๋ก work_mem ์ฌ์ฉ ์ฆ๊ฐ, shared_buffers ์ค์ ๊ณผ๋ค.
PostgreSQL์ ์ฐ๊ฒฐ๋ง๋ค ํ๋ก์ธ์ค๋ฅผ ๋์ฐ๋ฏ๋ก, backend๊ฐ ๋๋ฉด ๋ฉ๋ชจ๋ฆฌ๋ ๊ทธ๋งํผ ๋์ด๋ฉ๋๋ค. ๋ ์ ๋ ฌ·ํด์ ์์ ์ด work_mem์ ๋์ผ๋ฉด ๋์คํฌ temp๋ก ๋์ด๊ฐ๋๋ฐ, ์ด๊ฒ๋ ํจ๊ป ๋ด ๋๋ค.
-- ์์ ํ์ผ(temp) ์ฌ์ฉ๋ — ์ ๋ ฌ/ํด์๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ๋๋์ง ๋ชปํ๊ณ ๋์คํฌ๋ก ๋์ด๊ฐ๋์ง
-- temp_files·temp_bytes๊ฐ ๋น ๋ฅด๊ฒ ๋๋ฉด work_mem์ด ๋ถ์กฑํ๋ค๋ ์ ํธ
SELECT datname, temp_files, temp_bytes
FROM pg_stat_database
WHERE datname = current_database();
- ํจ๊ป ํ์ธํ ์งํ: Numbackends๊ฐ ๊ฐ์ด ์ฐ์ํฅํ๋ฉด → ์ฐ๊ฒฐ(ํ๋ก์ธ์ค) ๋์๋ก ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋ ๊ฒ์ ๋๋ค. Temp Bytes·Temp Files๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ์ ๋ ฌ·ํด์๊ฐ ๋์คํฌ๋ก ๋์ด๊ฐ๋ฉฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋ฐํ๋ ์ค์ ๋๋ค. ๋จ์ ๋ฉ๋ชจ๋ฆฌ(Free Memory)๊ฐ ์ค๋ฉฐ Read IOPS๊ฐ ์ค๋ฅด๋ฉด → ์ค์์ด ์์๋์ ์ ์์ด ์ฆ์ ์ ๊ฒํฉ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — PostgreSQL์ ์ฐ๊ฒฐ๋ง๋ค ํ๋ก์ธ์ค๋ฅผ ๋์ฐ๋ฏ๋ก ์ปค๋ฅ์ ํ์ ๊ณผํ๊ฒ ํฌ๊ฒ ์ก์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์๋ฐ์ด MySQL๋ณด๋ค ์ง์ ์ ์ผ๋ก ์ปค์ง๋๋ค. ํ ํฌ๊ธฐ๋ฅผ ์ ์ ํ๊ฒ ์ก๊ณ , ํ ๋ฒ์ ๊ฑฐ๋ํ ๊ฒฐ๊ณผ์ ์ ์ ๋ ฌ·๊ทธ๋ฃนํํ๋ ์ฟผ๋ฆฌ๋ฅผ ์ค์ด๋ฉฐ, ์ธ๋ฑ์ค๋ก ์ ๋ ฌ์ ๋์ ํ๊ฒ ํ๋ฉด work_mem์ด ๋์คํฌ temp๋ก ๋์ด๊ฐ๋ ๊ฒฝ์ฐ๊ฐ ์ค์ด๋ญ๋๋ค.
Free Memory (Bytes)
์ฌ์ ๋ฉ๋ชจ๋ฆฌ(freeable memory)์ ๋๋ค. ์ธ์คํด์ค์ ๋จ์ ์๋ ์ธ ์ ์๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฐ์ดํธ๋ก ๋ด ๋๋ค. (OS) Memory Percent์ ์ง์ผ๋ก, ํ์ชฝ์ ๋น์จ์, ํ์ชฝ์ ์ ๋ ์ฌ์ ๋์ ๋ด ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 14.2GB, ๋ฒ์ ์ฝ 12.2 ~ 15.0GB๋ก ํํํฉ๋๋ค. ์ฌ์ ๊ฐ ์์ ์ ์ผ๋ก ์ ์ง๋๋ ์ํ์ ๋๋ค.
- ์ํ ์ ํธ: ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ ๋๊ฐ๋ณด๋ค ์ฌ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊พธ์คํ ์ค์ด๋๋ ์ถ์ธ๊ฐ ์ํํฉ๋๋ค. ๊ณ ๊ฐ๋๋ฉด ์ค์์ด ์์๋ฉ๋๋ค.
- ํ๋ฉด(์ค๋ฉด) ์์ฌํ ๊ฒ: backend ๋์(๋ฐ๋ฉ ์ ๋ ์ฐ๊ฒฐ์ด ์์), ํฐ ์ ๋ ฌ·ํด์ ์์ , shared_buffers·์บ์๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ .
- ํจ๊ป ํ์ธํ ์งํ: (OS) Memory Percent์ ๋ฐ๋๋ก ์์ง์ ๋๋ค(์ฌ์ ๊ฐ ์ค๋ฉด ์ฌ์ฉ๋ฅ ์ด ์ค๋ฆ). Numbackends๊ฐ ๊ฐ์ด ์ฐ์ํฅํ๋ฉด → ์ฐ๊ฒฐ ๋์๋ก ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋ ๊ฒ์ ๋๋ค. Read IOPS๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ์ค์ ์์ ์ ํธ์ผ ์ ์์ด ์ฆ์ ์ ๊ฒํฉ๋๋ค.
์ค๋ฌด ์๋๋ฆฌ์ค — ์ฌ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ 14GB ์ํ์ผ๋ก ํํํ๋ฉด ํ๋์ ์ ์์์ ์ ์ ์์ต๋๋ค. ๋ฌธ์ ๋ ์ฒ์ฒํ ์๋ ๊ฒฝ์ฐ์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฐ๊ฒฐ์ ๋ซ์ง ์์ผ๋ฉด backend ํ๋ก์ธ์ค๊ฐ ์์ด๋ฉฐ ์ฌ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๊ฐ๋น ์ผ์ ํ๊ฒ ์ค์ด๋๋ ์ฐํํฅ ๊ทธ๋ํ๊ฐ ๊ทธ๋ ค์ง๋๋ค. ์ด๋ ์๊ฐ ์ค์์ด ์์๋๋ฉด ๋ชจ๋ ์ฟผ๋ฆฌ๊ฐ ๋๋ ค์ง๋ฏ๋ก, ์ถ์ธ๊ฐ ๊บพ์ด๊ธฐ ์ ์ ์ก๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
2. ์ธ์ · ์ฐ๊ฒฐ
์ฒด๊ฐ์ ๊ฐ์ฅ ์์ฃผ ๋ณด๋ ์์ญ์ ๋๋ค. ํต์ฌ์ "์ฐ๊ฒฐ" ๊ณผ "ํ์ฑ" ์ ๊ตฌ๋ถํ๋ ๊ฒ์ ๋๋ค. ์นดํ๋ก ์น๋ฉด ๋งค์ฅ ์ ์๋ ์ ์ฒด๊ฐ ์ฐ๊ฒฐ(Numbackends)์ด๊ณ , ๊ทธ์ค ์ง๊ธ ๊ณ์ฐ๋์์ ์ฃผ๋ฌธ ์ค์ธ ์๋์ด ํ์ฑ(Active Backend)์ ๋๋ค. ๋งค์ฅ์ ์๋์ด ๋ง์๋ ๊ณ์ฐ๋ ์์ ๋ณดํต ํ๋ ๋ช ์ธ ๊ฒ์ด ์ ์์ ๋๋ค.
์ด ์์ญ์ ์ฉ์ด ๋ช ๊ฐ๋ฅผ ๋จผ์ ํ์ด ๋๊ฒ ์ต๋๋ค.
- backend(๋ฐฑ์๋): PostgreSQL์ด ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ํ๋๋ฅผ ์ฒ๋ฆฌํ๋ ค๊ณ ๋์ฐ๋ ํ๋ก์ธ์ค์ ๋๋ค. MySQL์ด ์ฐ๊ฒฐ๋ง๋ค ์ค๋ ๋๋ฅผ ๋์ฐ๋ ๊ฒ๊ณผ ๋ฌ๋ฆฌ PostgreSQL์ ํ๋ก์ธ์ค๋ฅผ ๋์ฐ๊ณ , ๊ทธ๊ฒ์ backend๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. ์ฝ๊ฒ ๋งํด "์ง๊ธ ๋ถ์ด ์๋ DB ์ฐ๊ฒฐ ํ ๊ฐ" ์ ๋๋ค.
- ์ปค๋ฅ์ ํ(Connection Pool): ์ฐ๊ฒฐ์ ๋งค๋ฒ ์๋ก ๋ง๋ค์๋ค ๋๋ ๊ฒ์ ๋น์ฉ์ด ํฝ๋๋ค. ํนํ PostgreSQL์ ์ฐ๊ฒฐ๋ง๋ค ํ๋ก์ธ์ค๋ฅผ ๋์ ๋ ๋น์๋๋ค. ๊ทธ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฐ๊ฒฐ์ ๋ฏธ๋ฆฌ ์ฌ๋ฌ ๊ฐ ๋ง๋ค์ด ๋๊ณ ๋น๋ ค ์ฐ๊ณ ๋ฐ๋ฉํ๊ฑฐ๋, PgBouncer ๊ฐ์ ๋ณ๋ ํ๋ฌ๋ฅผ ์์ ๋ก๋๋ค. ๊ณต๊ตฌ๋ฅผ ์ธ ๋๋ง๋ค ์ฌ ์ค์ง ์๊ณ ๊ณต๊ตฌํจ์์ ๊บผ๋ด ์ฐ๊ณ ๋ค์ ๋ฃ์ด ๋๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. ๋น๋ฆฐ ์ฐ๊ฒฐ์ ๋ฐ๋ฉํ์ง ์์ผ๋ฉด "์ฐ๊ฒฐ ๋์" ๊ฐ ์๊น๋๋ค.
- idle ์ฐ๊ฒฐ: ์ฐ๊ฒฐ์ ๋์ด ์์ง๋ง ์ง๊ธ์ ์๋ฌด ์ฟผ๋ฆฌ๋ ๋๋ฆฌ์ง ์๊ณ ๋ค์ ์ผ์ ๊ธฐ๋ค๋ฆฌ๋ ์ํ(
state = 'idle')์ ๋๋ค. ์ปค๋ฅ์ ํ์ด ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋ ์ฐ๊ฒฐ๋ค์ ๋๋ถ๋ถ ์ด idle ์ํ๋ก ๋๊ธฐํฉ๋๋ค. ๊ทธ๋์ ์ฐ๊ฒฐ ์๊ฐ ์๋ฐฑ ๊ฐ์ฌ๋ ์ค์ ๋ก ์ผํ๋ ๊ฒ์ ๋ช ๊ฐ๋ฟ์ธ ๊ฒฝ์ฐ๊ฐ ์ ์์ ๋๋ค. ํนํ ํธ๋์ญ์ ์ ์ฐ ์ฑ๋ก ๋ ธ๋idle in transaction์ํ๋ ๋ฝ๊ณผ ์ฃฝ์ ํ ์ ๋ฆฌ๋ฅผ ๋ง์ ์ ์์ด ์ฃผ์ํด์ ๋ด ๋๋ค(๋ค์์ ๋ค์ ๋ค๋ฃน๋๋ค).
Active Backend (๊ฐ)
์ง๊ธ ์ค์ ๋ก ์ผํ๊ณ ์๋(active ์ํ์ธ) backend ์์ ๋๋ค. ๋ถํ๋ฅผ ๊ฐ์ฅ ์ ๋ํ๋ ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 0.88, ๋ฒ์ 0 ~ 177. ๋ค์ ๋์ค๋ Numbackends๊ฐ ์ฝ 837์ธ๋ฐ ํ์ฑ์ 1 ์ํ์ ๋๋ค. ์ฆ ๋๋ถ๋ถ์ ์ฐ๊ฒฐ์ ๋๊ณ ์๋ค๋ ๋ป์ด๊ณ , ์ด๊ฒ์ด ์ ์์ ๋๋ค. ๋ค๋ง ์๊ฐ ์ต๋๊ฐ์ด 177๊น์ง ํ ์ ์ด ์๋๋ฐ, ์ด ์๊ฐ์ด ๋ฐ๋ก ํ์ฑ์ด ํ๊บผ๋ฒ์ ๋ชฐ๋ฆฐ ์ํ ์ ํธ์ ๋๋ค.
- ์ํ ์ ํธ: ๊ฒฝ๊ณ 30, ์ํ 40. ํ์ฑ์ด ๊ฐ์๊ธฐ ์์ญ ๊ฐ๋ก ๋ฐ๋ฉด ์ฟผ๋ฆฌ๋ค์ด ๋นจ๋ฆฌ ๋๋์ง ๋ชปํ๊ณ ์์ด๊ณ ์๋ค๋ ์ ํธ์ ๋๋ค. ๊ด์ธก ์ต๋๊ฐ 177์ ์๊ณ๋ฅผ ํฌ๊ฒ ๋๊ธด ๊ฐ์ ๋๋ค.
- ์ฝ๋ ๋ฒ: "์ฐ๊ฒฐ(Numbackends)์ ๊ทธ๋๋ก์ธ๋ฐ ํ์ฑ๋ง ๋ฐ์๋ค" ๋ฉด ์ฟผ๋ฆฌ๊ฐ ๋๋ ค์ง ๊ฒ์ด๊ณ , "์ฐ๊ฒฐ๋ ๊ฐ์ด ๋ฐ์๋ค" ๋ฉด ํธ๋ํฝ์ด ๋ชฐ๋ฆฐ ๊ฒ์ ๋๋ค. ์ด ๊ตฌ๋ถ์ด ์์ธ ์ถ์ ์ ์ถ๋ฐ์ ์ ๋๋ค.
ํ์ฑ backend๊ฐ ๊ฐ์๊ธฐ ์ค๋ฅด๋ ํํ ์์ธ์, ์ด๋ค ๋ฌด๊ฑฐ์ด ์ฟผ๋ฆฌ๊ฐ ๋ฐฐํฌ๋์ด ๊ทธ ์ฟผ๋ฆฌ๋ฅผ ๋๋ฆฌ๋ backend๋ค์ด ๋์์ ์ค๋ ๋จธ๋ฌด๋ ๊ฒฝ์ฐ์ ๋๋ค.
-- ์ง๊ธ active ์ํ์ธ backend๋ฅผ ์ค๋ ๊ฑธ๋ฆฐ ์์๋ก
SELECT pid, usename, state,
now() - query_start AS running_for,
wait_event_type, wait_event, query
FROM pg_stat_activity
WHERE state = 'active'
AND backend_type = 'client backend'
ORDER BY running_for DESC;
- ํจ๊ป ํ์ธํ ์งํ: CPU·Blks Read๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ๋๋ฆฐ(ํ ์ค์บ) ์ฟผ๋ฆฌ๊ฐ ์ ๋๋๊ณ ์์ด๋ ๊ฒ์ ๋๋ค. Locks Waiting์ด ๊ฐ์ด ์ค๋ฅด๋ฉด → ๋ฝ ๋๊ธฐ๋ก ํ์ฑ์ด ๋งํ ์์ธ ๊ฒ(์ฟผ๋ฆฌ ์์ฒด๋ณด๋ค ๋ค๋ฅธ ํธ๋์ญ์ ์ด ์์ธ). Numbackends๊ฐ ๊ฐ์ด ๋ฐ๋ฉด → ํธ๋ํฝ ๊ธ์ฆ์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ํ์ฑ backend๋ ์ฟผ๋ฆฌ ํ๋ํ๋์ ์๋ต ์๋์ ์ง์ ์ข์ฐ๋ฉ๋๋ค. ๋๋ฆฐ ์ฟผ๋ฆฌ ํ ์ข ๋ฅ๊ฐ ๋ฐฐํฌ๋๋ฉด ๊ทธ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ backend๋ค์ด ๋์์ ์ค๋ ๋จธ๋ฌผ๋ฌ ํ์ฑ ์๊ฐ ํ๊บผ๋ฒ์ ์ฌ๋ผ๊ฐ๋๋ค. ์ฟผ๋ฆฌ ์๋ต ์๊ฐ์ ์งง๊ฒ ์ ์งํ๋ ๊ฒ(์ธ๋ฑ์ค·์ ์ ๊ฒฐ๊ณผ ํฌ๊ธฐ)์ด ํ์ฑ ์๋ฅผ ๋ฎ๊ฒ ์ ์งํ๋ ๊ทผ๋ณธ ๋์ฑ ์ ๋๋ค.
์ค๋ฌด ์๋๋ฆฌ์ค — ํ์ ํ์ฑ backend๊ฐ 1~2์๋๋ฐ ์ด๋ ๋ฐฐํฌ ์งํ ๊ฐ์๊ธฐ ์์ญ~177๋ก ์น์์๋ค๊ณ ํด๋ณด๊ฒ ์ต๋๋ค. pg_stat_activity๋ก ์ก์ ๋ณด๋ ๊ฐ์ query๋ฅผ ๊ฐ์ง backend๋ค์ด ์์ญ ๊ฐ์ฉ ๋์์ active๋ก ๋ ์๊ณ , ๊ทธ ์ฟผ๋ฆฌ๊ฐ ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๋ ํ ์ค์บ์ด์์ต๋๋ค. ํ ์์ฒญ์ด ๋๋ ค์ง์ ๋ค๋ฐ๋ผ ๋ค์ด์จ ์์ฒญ๋ค์ด ๋๋์ง ๋ชปํ๊ณ ์์ธ ๊ฒ์ ๋๋ค. ํด๋น ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๋ ํ์ฑ backend๊ฐ ๋ค์ 1~2๋ก ๋์์ต๋๋ค. ๊ด์ธก ์ต๋๊ฐ 177์ ์ด๋ฐ "๋๋ฆฐ ์ฟผ๋ฆฌ๊ฐ ๋์์ ๋ชฐ๋ฆฐ" ์๊ฐ์ ํ์ ์ ๋๋ค.
Numbackends (๊ฐ)
์ง๊ธ ์ฐ๊ฒฐ๋์ด ์๋ ์ ์ฒด backend ์์ ๋๋ค. ์๋ฌด ์ผ๋ ์ ํ๋(idle) backend๋ ํฌํจํฉ๋๋ค. (delta๋ก ํ๊ธฐ๋์ง๋ง ์ค์ง์ ์ผ๋ก ํ์ฌ ์ฐ๊ฒฐ ์๋ฅผ ๋ด ๋๋ค.)
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 837, ๋ฒ์ 726 ~ 1,385. ์ปค๋ฅ์ ํ์ด ํฐ ํ๊ฒฝ์ด๋ผ ์๋ฐฑ ๊ฐ๊ฐ ์ฐ๊ฒฐ๋ ์ฑ ์ ์ง๋ฉ๋๋ค. ์ฐ๊ฒฐ ์ ์์ฒด๋ณด๋ค "ํ์ ์์ค์์ ๋ฒ์ด๋ฌ๋๊ฐ" ๊ฐ ํฌ์ธํธ์ ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ์ฐ๊ฒฐ ๋์(๋ฐ๋ฉ ์ ๋ ์ฐ๊ฒฐ), ํ ์ค์ ๋ณ๊ฒฝ, ํธ๋ํฝ ๊ธ์ฆ.
-- ์ํ๋ณ·์ฌ์ฉ์๋ณ ์ฐ๊ฒฐ ์ (idle๊ฐ ํ์ชฝ์ผ๋ก ์์ด๋ฉด ๋์ ๋จ์)
SELECT usename, state, COUNT(*) AS cnt
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY usename, state
ORDER BY cnt DESC;
- ํจ๊ป ํ์ธํ ์งํ: Active Backend๋ ๊ทธ๋๋ก์ธ๋ฐ Numbackends๋ง ์ฐ์ํฅํ๋ฉด → ์ผ ์ ํ๋ idle ์ฐ๊ฒฐ์ด ์์ด๋ ๋์์ ๋๋ค. Connection Ratio๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → max_connections ํ๋์ ๊ฐ๊น์์ง๋ ๊ฒ์ด๋ผ ์ํํฉ๋๋ค. Free Memory๊ฐ ๊ฐ์ด ์ค๋ฉด → backend ํ๋ก์ธ์ค๋ง๋ค ์ฐ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋์ ๋๋ ์ค์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ์ปค๋ฅ์ ํ ํฌ๊ธฐ๋ฅผ ๋๋ฌด ํฌ๊ฒ ์ก๊ฑฐ๋, ์์ธ ๊ฒฝ๋ก์์ ์ฐ๊ฒฐ์ ๋ฐ๋ฉํ์ง ์์ผ๋ฉด(try-with-resources๋ finally ๋๋ฝ) ์ฐ๊ฒฐ์ด ๊ณ์ ์์ ๋๋ค. PostgreSQL์ ์ฐ๊ฒฐ๋ง๋ค ํ๋ก์ธ์ค๋ฅผ ๋์ ๋น์ฉ์ด ํฌ๋ฏ๋ก, ํ ํฌ๊ธฐ๋ max_connections์ ํจ๊ป ์ ์คํ ์ค๊ณํด์ผ ํ๊ณ , ์ฐ๊ฒฐ์ด ๋ง์ด ํ์ํ๋ฉด PgBouncer ๊ฐ์ ํ๋ฌ๋ฅผ ์๋จ์ ๋๋ ๊ฒ์ ๊ณ ๋ คํฉ๋๋ค.
Connection Ratio (%)
์ฐ๊ฒฐ ์ฌ์ฉ๋ฅ ์
๋๋ค. ์ฐ์์ numbackends / max_connections * 100, ์ฆ "ํ์ฉ๋ ์ต๋ ์ฐ๊ฒฐ ์ค ๋ช %๋ฅผ ์ฐ๋" ์
๋๋ค. ์ฃผ์ฐจ์ฅ ๋ง์ฐจ์จ๊ณผ ๊ฐ์์, 100%๋ฉด ์ ์ฐจ(์ฐ๊ฒฐ)๊ฐ ๋ชป ๋ค์ด์ต๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 16.8%, ๋ฒ์ 14.5 ~ 27.7%. ์ต๋ ์ฐ๊ฒฐ ๋๋น ์ฌ์ ๊ฐ ๋ง์ ์ํ์ ๋๋ค.
- ์ํ ์ ํธ: ๊ฒฝ๊ณ 85%, ์ํ 90%. 100%์ ๋๋ฌํ๋ฉด ์ ์ฐ๊ฒฐ์ด ๊ฑฐ๋ถ๋์ด "too many clients already" ์๋ฌ๊ฐ ๋ฉ๋๋ค. ์๋น์ค ์ฅ์ ๋ก ์ง๊ฒฐ๋ฉ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ์ฐ๊ฒฐ ๋์, ํ ํฌ๊ธฐ ๊ณผ๋ค ์ค์ , max_connections๊ฐ ๋๋ฌด ์๊ฒ ์กํ.
์ฐ๊ฒฐ ๋์๋ ๋๊ฐ ์ฝ๋์์ "๋น๋ฆฐ ์ฐ๊ฒฐ์ ๋ฐ๋ฉํ์ง ์๋" ๊ฒฝ๋ก์์ ์๊น๋๋ค.
-- (๊ฐ๋
์ฉ ์์ฌ์ฝ๋) ๋์ ์: ์์ธ๊ฐ ๋๋ฉด ์ฐ๊ฒฐ์ ๋ซ์ง ๋ชปํ๊ณ ์๋ค
-- conn = pool.getConnection();
-- stmt.executeQuery(...); // ์ฌ๊ธฐ์ ์์ธ๊ฐ ๋๋ฉด
-- conn.close(); // ์ด ์ค์ ๋๋ฌํ์ง ๋ชปํ๋ค → ์ฐ๊ฒฐ ๋์
-- ๊ณ ์น ์: try-with-resources / finally ๋ก ๋ฐ๋์ ๋ฐ๋ฉ
-- try (Connection conn = pool.getConnection()) {
-- ... ์ฟผ๋ฆฌ ...
-- } // ๋ธ๋ก์ ๋ฒ์ด๋๋ฉด ์์ธ๊ฐ ๋๋ conn์ด ์๋ close ๋๋ค
-- ํ์ฌ ์ฌ์ฉ๋ฅ ์ง์ ๊ณ์ฐ
SELECT
(SELECT COUNT(*) FROM pg_stat_activity) AS connected,
setting::int AS max_conn,
ROUND((SELECT COUNT(*) FROM pg_stat_activity)::numeric
/ setting::int * 100, 2) AS usage_pct
FROM pg_settings
WHERE name = 'max_connections';
- ํจ๊ป ํ์ธํ ์งํ: Numbackends๊ฐ ํจ๊ป ์ฐ์ํฅํ๋ฉด → ์ฐ๊ฒฐ ๋์๊ฐ ์ฌ์ฉ๋ฅ ์ ๋ฐ์ด ์ฌ๋ฆฌ๋ ๊ฒ์ ๋๋ค. Active Backend๋ ๋ฎ์๋ฐ ์ฌ์ฉ๋ฅ ๋ง ์ค๋ฅด๋ฉด → idle ์ฐ๊ฒฐ์ด ์์ฌ ํ๋๋ฅผ ์ ์ํ๋ ๊ฒ(๋์ ๊ฐ๋ฅ์ฑ)์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ์ฌ์ฉ๋ฅ ์ ๊ฒฐ๊ตญ
ํ์ฌ ์ฐ๊ฒฐ / max_connections์ด๋ฏ๋ก, ์ฐ๊ฒฐ ๋ฐ๋ฉ ๋๋ฝ์ด ์์ผ๋ฉด ๋ถ์๊ฐ ๊พธ์คํ ์ฐ์ํฅํฉ๋๋ค. ์ฐ๊ฒฐ์ ๋น๋ฆฌ๋ฉด ๋ฐ๋์ ๋ฐ๋ฉ๋๋ ๊ตฌ์กฐ(try-with-resources/finally)๋ก ์ฐ๊ณ , ํ๊ณผ max_connections๋ฅผ ํจ๊ป ์ค๊ณํด ์ฌ์ ๋ฅผ ๋ฌ์ผ ํฉ๋๋ค. ์ฌ์ฉ๋ฅ ์ด ์์ํ ์ฐ์ํฅํ๋ ๊ทธ๋ํ ์์ฒด๊ฐ ๋์ ์ฝ๋์ ์ ํธ์ ๋๋ค.์ค๋ฌด ์๋๋ฆฌ์ค — ๊ฐ์ฅ ํํ ์ฅ์ ํจํด์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฐ๊ฒฐ์ ์ฐ๊ณ ๋ฐ๋ฉํ์ง ์์ผ๋ฉด ์ฐ๊ฒฐ์ด ํ๋์ฉ ์์ด ๋๊ฐ๋๋ค. ๊ทธ๋ํ์ Connection Ratio๊ฐ ์์ํ ์ฐ์ํฅํ๋ค๊ฐ, 100%์ ๋ฟ๋ ์๊ฐ ์ ๊ท ์์ฒญ์ด ์ ๋ถ "too many clients already" ๋ก ์คํจํ๋ฉฐ ์๋น์ค๊ฐ ๋ฉ์ถฅ๋๋ค. ์ฌ๊ธฐ๋ํ๋ฉด ์ผ์ ๋ณต๊ตฌ๋์ง๋ง ๋์ ์ฝ๋๋ฅผ ๋ชป ์ก์ผ๋ฉด ๋ฉฐ์น ๋ค ๊ฐ์ ์์ ์ ๋ ํฐ์ง๋๋ค. ๊ทธ๋์ "์ํ์ ์ ๋์๋" ๋ฟ ์๋๋ผ "๊พธ์คํ ์ฐ์ํฅํ๋๊ฐ" ๋ฅผ ๊ฐ์ด ๋ด ๋๋ค.
Long Active Backend (๊ฐ)
๋จผ์ ์ฉ์ด๋ถํฐ ํ์ด ๋ณด๊ฒ ์ต๋๋ค. backend๋ PostgreSQL์ด ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ํ๋๋ฅผ ์ฒ๋ฆฌํ๋ ค๊ณ ๋์ฐ๋ ํ๋ก์ธ์ค์ ๋๋ค. ๊ทธ backend๊ฐ ์ฟผ๋ฆฌ ํ๋๋ฅผ 5์ด๊ฐ ๋๋๋ก ๋๋ด์ง ๋ชปํ๊ณ ๋ถ์ก๊ณ ์์ ๋, ์ด๊ฒ์ "์ฅ๊ธฐ ์คํ backend" ๋ก ์ ๋๋ค.
๋ณดํต์ ์ฟผ๋ฆฌ๋ ์ ๋ฐ๋ฆฌ์ด๋ฉด ๋๋ฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ํ ์ฟผ๋ฆฌ๊ฐ 5์ด์ฉ ๊ฑธ๋ฆฐ๋ค๋ ๊ฒ์, ๊ทธ๋์ ๊ทธ ์ฐ๊ฒฐ์ด ๊ณ์ ๋ฌถ์ฌ ์๊ณ CPU·๋ฉ๋ชจ๋ฆฌ·๋์คํฌ๋ฅผ ์ก์๋จน์ผ๋ฉฐ, ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฟผ๋ฆฌ๊น์ง ๋ง๊ณ ์๋ค๋ ๋ป์ ๋๋ค. ๊ณ์ฐ๋์์ ํ ์๋์ด 5์ด ๋๊ฒ ์ ๋๋๋ฉด ๋ค์ ์ค์ด ์๊ธฐ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 0.02(๋ฒ์ 0 ~ 2). 0์ด ์ ์์ ๋๋ค.
- ์ํ ์ ํธ: ๊ฒฝ๊ณ 1, ์ํ 2. 1๊ฐ๋ง ๋ํ๋๋ ๋ค์ฌ๋ค๋ณผ ๊ฐ์น๊ฐ ์์ต๋๋ค.
์ด๋ค ์ํฉ์์ ์๊ธฐ๋ — ๊ทธ๋ฆฌ๊ณ ์ด๋ค ์ฟผ๋ฆฌ๊ฐ ๋ฒ์ธ์ธ๊ฐ
๋๋ถ๋ถ์ ์ธ๋ฑ์ค๋ฅผ ์ ๋๋ก ํ์ง ๋ชปํด ํ ์ด๋ธ์ ํต์งธ๋ก ํ๋ ์ฟผ๋ฆฌ์ ๋๋ค. ์ธ๋ฑ์ค๋ ์ฑ ๋ค์ ์์ธ๊ณผ ๊ฐ์ต๋๋ค. ์์ธ์ด ์์ผ๋ฉด ์ํ๋ ํญ๋ชฉ์ ๋ฐ๋ก ํด๊ณ , ์์ผ๋ฉด ์ฒซ ์ฅ๋ถํฐ ๋๊น์ง ๋๊ฒจ์ผ ํฉ๋๋ค. ๋ฐ์ดํฐ๊ฐ ์ ์ ๋ ๋๊น์ง ๋๊ฒจ๋ ๊ธ๋ฐฉ์ด์ง๋ง, ์๋ฐฑ๋ง ํ์ด ๋๋ฉด 5์ด, 10์ด๋ก ๋์ด๋ฉ๋๋ค. ์ค๋ฌด์์ ์์ฃผ ๋์ค๋ ์ ํ์ ์ฝ๋๋ก ๋ณด๊ฒ ์ต๋๋ค.
(1) WHERE ์กฐ๊ฑด ์ปฌ๋ผ์ ์ธ๋ฑ์ค๊ฐ ์๋ ๊ฒฝ์ฐ
-- phone ์ปฌ๋ผ์ ์ธ๋ฑ์ค๊ฐ ์์ผ๋ฉด, ํ์ 500๋ง ๋ช
์ ์ ๋ถ ํ๋๋ค
SELECT * FROM members WHERE phone = '010-1234-5678';
(2) LIKE ์์ ์์ผ๋์นด๋(%)๊ฐ ๋ถ์ ๊ฒฝ์ฐ
-- 'name%' ์ ์ธ๋ฑ์ค๋ฅผ ์ธ ์ ์์ง๋ง, '%...%' ๋ ์ธ๋ฑ์ค๋ฅผ ๋ชป ์ฐ๊ณ ์ ์ฒด๋ฅผ ์ค์บํ๋ค
SELECT * FROM products WHERE name LIKE '%์ผ์ด์ค%';
๋ถ๋ถ ๊ฒ์์ด ๊ผญ ํ์ํ๋ฉด PostgreSQL์ ์ ๋ฌธ ๊ฒ์(tsvector/GIN ์ธ๋ฑ์ค)์ด๋ pg_trgm ํ์ฅ์ผ๋ก ํธ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
(3) ์ปฌ๋ผ์ ํจ์๋ก ๊ฐ์ผ ๊ฒฝ์ฐ
-- created_at์ ์ธ๋ฑ์ค๊ฐ ์์ด๋, ํจ์๋ก ๊ฐ์ธ๋ฉด ์ธ๋ฑ์ค๊ฐ ๋ฌด๋ ฅํ๋๋ค
SELECT * FROM orders WHERE date(created_at) = '2026-06-18';
-- ์ด๋ ๊ฒ ๋ฒ์๋ก ๋ฐ๊พธ๋ฉด ์ธ๋ฑ์ค๋ฅผ ํ๋ค
SELECT * FROM orders
WHERE created_at >= TIMESTAMP '2026-06-18 00:00:00'
AND created_at < TIMESTAMP '2026-06-19 00:00:00';
(4) ๊น์ ํ์ด์ง(OFFSET์ด ํฐ ๊ฒฝ์ฐ)
-- 100๋ง ๊ฑด์ ๊ฑด๋๋ฐ๊ณ 20๊ฑด์ ๊ฐ์ ธ์ค๋ ค๋ฉด, 100๋ง ๊ฑด์ ๋ค ์ฝ์ด์ผ ํ๋ค
SELECT * FROM posts ORDER BY id OFFSET 1000000 LIMIT 20;
-- ๊ณ ์น ์: ๋ง์ง๋ง์ผ๋ก ๋ณธ id ๊ธฐ์ค์ผ๋ก ์๋ผ ์ฝ๋๋ค(keyset ํ์ด์ง)
SELECT * FROM posts WHERE id > 1000000 ORDER BY id LIMIT 20;
(5) ๋๋ UPDATE / DELETE
-- ์กฐ๊ฑด์ ๊ฑธ๋ฆฌ๋ ์๋ฐฑ๋ง ํ์ ํ ๋ฒ์ ์ง์ฐ๋ฉด, ์ค๋ ๋๊ฐ ๋ฌถ์ด๊ณ ๋ฝ๋ ์ค๋ ์ก์ผ๋ฉฐ
-- ์ฃฝ์ ํ(dead tuple)๋ ํ๊บผ๋ฒ์ ์์์ง๋ค
DELETE FROM access_logs WHERE created_at < '2025-01-01';
PostgreSQL์์๋ ๋๋ DELETE/UPDATE๊ฐ ์ฃฝ์ ํ์ ํ๊บผ๋ฒ์ ๋ง๋ค์ด ์ดํ autovacuum ๋ถ๋ด๊น์ง ํค์ฐ๋ฏ๋ก, ๋ช ์ฒ ๊ฑด์ฉ ๋๋ ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ํนํ ์์ ํฉ๋๋ค.
์ด๋ป๊ฒ ํ์ธํ๋
์ฅ๊ธฐ ์คํ backend๊ฐ ๋ณด์ด๋ฉด, ๋จผ์ ์ง๊ธ ๋ฌด์์ด ์ค๋ ๋๊ณ ์๋์ง ์ฐพ์ต๋๋ค.
-- 5์ด ๋๊ฒ ์คํ ์ค์ธ ์ฟผ๋ฆฌ๋ง ๊ณจ๋ผ ๋ณธ๋ค
SELECT pid, usename, now() - query_start AS running_for,
wait_event_type, wait_event, query
FROM pg_stat_activity
WHERE state = 'active'
AND now() - query_start > interval '5 seconds'
ORDER BY running_for DESC;
๋ฒ์ธ ์ฟผ๋ฆฌ๋ฅผ ์ฐพ์์ผ๋ฉด EXPLAIN (ANALYZE, BUFFERS) ๋ก ์คํ ๊ณํ์ ๋ด
๋๋ค. Seq Scan(์์ฐจ ์ค์บ)์ด ํฐ ํ
์ด๋ธ์ ๊ฑธ๋ ค ์๊ฑฐ๋ ์ฝ์ ๋ธ๋ก ์๊ฐ ๋งค์ฐ ํฌ๋ฉด ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๊ณ ์๋ค๋ ๋ป์
๋๋ค.
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM members WHERE phone = '010-1234-5678';
-- ๊ฒฐ๊ณผ์ Seq Scan on members ... rows=5000000 ์ด ๋ณด์ด๋ฉด ํ ์ค์บ, ์ธ๋ฑ์ค ํ์
- ํจ๊ป ํ์ธํ ์งํ: โ ๋จผ์ pg_stat_activity์
running_for๋ก ์ด๋ค ์ฟผ๋ฆฌ๊ฐ ์ค๋ ๊ฑธ๋ฆฌ๋์ง ์ฐพ๊ณ EXPLAIN์ผ๋ก ์์ฐจ ์ค์บ์ ํ์ธํฉ๋๋ค. โก CPU·Blks Read๊ฐ ๋๋ฐ ์์น์ด๋ฉด → ํ ์ค์บ/๋ฌด๊ฑฐ์ด ์ฟผ๋ฆฌ์ ๋๋ค. โข Locks Waiting์ด ๋๋ฐ์ด๋ฉด → ๋ฝ ๋๊ธฐ(์ฟผ๋ฆฌ ์์ฒด๋ณด๋ค ๋ค๋ฅธ ํธ๋์ญ์ ์ด ๋ง์ ๊ฒ)์ ๋๋ค. โฃ Active Backend๊ฐ ๊ฐ์ด ์์ด๋ฉด → ๋๋ฆฐ ์ฟผ๋ฆฌ๊ฐ ๋ค๋ฅผ ๋ง๋ ์ค์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ์ฅ๊ธฐ ์คํ ์ฟผ๋ฆฌ๋ ๋๋ถ๋ถ ORM์ด๋ ์ง์ ์์ฑํ ์ฟผ๋ฆฌ๊ฐ ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๋ ๋ฐ์ ๋์ต๋๋ค. ์กฐํ ์กฐ๊ฑด ์ปฌ๋ผ์ ์ธ๋ฑ์ค๊ฐ ์๊ฑฐ๋, ํจ์๋ก ์ปฌ๋ผ์ ๊ฐ์ธ๊ฑฐ๋, ๊น์ OFFSET ํ์ด์ง์ ์ฐ๋ฉด ๋ฐ์ดํฐ๊ฐ ์์ผ์๋ก ์ด๋ ๋ ๊ฐ์๊ธฐ ๋๋ ค์ง๋๋ค. ์ฝ๋๋ฅผ ์งค ๋ ์กฐํ ์กฐ๊ฑด๊ณผ ์ ๋ ฌ ์ปฌ๋ผ์ ์ธ๋ฑ์ค ์ค๊ณ๋ฅผ ๋จผ์ ์ฑ๊ธฐ๊ณ , ๋๋ ๋ณ๊ฒฝ์ ํ ๋ฒ์ ํ์ง ๋ง๊ณ ๋๋ ์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
์ค๋ฌด ์๋๋ฆฌ์ค — ์ถ์ ์ด๊ธฐ์๋ ๋ชจ๋ ํ๋ฉด์ด ๋นจ๋๋๋ฐ ๋ช ๋ฌ ๋ค ํน์ ๊ฒ์ ํ๋ฉด๋ง ๋๋ ค์ก๋ค๊ณ ๊ฐ์ ํด ๋ด ๋๋ค. ๋ชจ๋ํฐ๋ง์ ๋ณด๋ฉด ๊ทธ ์๊ฐ๋์ Long Active Backend๊ฐ 1~2๋ก ์ฌ๋ผ์ค๊ณ CPU์ Blks Read๋ ๊ฐ์ด ๋๋๋ค. pg_stat_activity๋ก ์ก์ ๋ณด๋, ์ธ๋ฑ์ค ์๋ ์ปฌ๋ผ์ ์กฐ๊ฑด์ผ๋ก ๊ฑด ๊ฒ์ ์ฟผ๋ฆฌ๊ฐ ๋งค๋ฒ ์๋ฐฑ๋ง ํ์ ์์ฐจ ์ค์บํ๊ณ ์์์ต๋๋ค. ๋ฐ์ดํฐ๊ฐ ์ ๋ ์ด๊ธฐ์๋ 0.01์ด์๋ ์ฟผ๋ฆฌ๊ฐ, ๋ฐ์ดํฐ๊ฐ ์์ด๋ฉด์ 5์ด๋ก ๋์ด๋ ๊ฒ์ ๋๋ค. ํด๋น ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ์ Long Active Backend๋ ๋ค์ 0์ผ๋ก ๋์์ต๋๋ค. ์ฅ๊ธฐ ์คํ backend๋ ์ด๋ ๊ฒ "๋๋ ค์ง ์ฟผ๋ฆฌ๊ฐ ์๋ค" ๋ ๊ฐ์ฅ ๋จผ์ ์ผ์ง๋ ๊ฒฝ๊ณ ๋ฑ ์ญํ ์ ํฉ๋๋ค.
Locks Waiting (๊ฐ)
์ง๊ธ ๋ฝ์ ์ป์ผ๋ ค๊ณ ๋๊ธฐ ์ค์ธ ์ ์ฒด backend ์์ ๋๋ค. ๋ฝ ๊ฒฝํฉ์ ์ง์ ๋ณด์ฌ ์ฃผ๋ ์งํ์ ๋๋ค. (๋ฝ ์์ฒด๋ ์๋ 6๋ฒ ๋ฝ ์น์ ์์ ์์ธํ ๋ค๋ฃน๋๋ค.)
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 0.003, ๋ฒ์ 0 ~ 5. 0์ด ์ ์์ด๊ณ , 0์ด ์๋๋ฉด ์ง๊ธ ๋๊ตฐ๊ฐ ๋ค๋ฅธ ํธ๋์ญ์ ๋๋ฌธ์ ๋งํ ์๋ ๊ฒ์ ๋๋ค.
- ์ํ ์ ํธ: ๊ฒฝ๊ณ 1, ์ํ 2. ์์ ๊ฐ์ด๋ผ๋ ๋ฐ๋ณต๋๋ฉด ํน์ ์ฟผ๋ฆฌ·ํธ๋์ญ์ ์ด ์์ฃผ ์ถฉ๋ํ๊ณ ์๋ค๋ ๋ป์ ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ํ ํธ๋์ญ์
์ด ํ์ ์ฅ ์ฑ ์ปค๋ฐ์ ๋ฏธ๋ฃธ(ํนํ
idle in transaction), ๊ฐ์ ํ์ ๋ํ ๋์ ์์ ๊ฒฝํฉ.
-- ์ง๊ธ ๋ฝ์ ๊ธฐ๋ค๋ฆฌ๋ backend์, ๋๊ฐ ๋ง๊ณ ์๋์ง (PostgreSQL 9.6+ ๋ด์ฅ ํจ์)
SELECT pid, pg_blocking_pids(pid) AS blocked_by, state, query
FROM pg_stat_activity
WHERE cardinality(pg_blocking_pids(pid)) > 0;
- ํจ๊ป ํ์ธํ ์งํ: Active Backend๊ฐ ๊ฐ์ด ์์ด๋ฉด → ๋๊ธฐ๊ฐ ๋ถํ๋ก ๋ฒ์ง๋ ์ค์ ๋๋ค. Deadlocks๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ๊ฒฝํฉ์ด ๊ต์ฐฉ์ผ๋ก ๋ฒ์ง ๊ฒ์ ๋๋ค. ์์ธํ ๋ถ์์ 6๋ฒ ๋ฝ ์น์ ์ ์ฐธ๊ณ ํฉ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ๋๊ธฐ backend๊ฐ ์๋ค๋ ๊ฒ์ ๋๊ตฐ๊ฐ ๋ฝ์ ์ค๋ ์ฅ๊ณ ์๋ค๋ ๋ป์ ๋๋ค. ๋ณดํต ๋ฝ์ ์ก์ ํธ๋์ญ์ ์ด ์ปค๋ฐ์ ๋ฏธ๋ฃจ๋ ๊ฒฝ์ฐ(ํนํ ํธ๋์ญ์ ์ ์ฐ ์ฑ ๋ ธ๋
idle in transaction)์ด๋ฏ๋ก, ๋ณ๊ฒฝ ํ ์ฆ์ ์ปค๋ฐํ๋๋ก ํธ๋์ญ์ ๊ฒฝ๊ณ๋ฅผ ์ขํ๋ ๊ฒ์ด ํต์ฌ์ ๋๋ค.
3. ํธ๋์ญ์ · ์ฒ๋ฆฌ๋
์ด ์์ญ์ PostgreSQL์ด ์ผ๋ง๋ ๋ง์ ํธ๋์ญ์ ์ ์ฒ๋ฆฌํ๊ณ , ๊ทธ ๊ณผ์ ์์ ํ์ ์ผ๋ง๋ ์ฝ๊ณ ์ฐ๋์ง๋ฅผ ๋ด ๋๋ค. ๊ฐ๊ฒ์ ํ๋ชฉ๋ณ ํ๋งค ๊ฑด์ ๊ฐ์ ๊ฒ์ด๋ผ, ์ ๋๊ฐ๋ณด๋ค ํ์ ๋๋น ํจํด์ด ์ค์ํฉ๋๋ค.
๋จผ์ ์ฉ์ด๋ฅผ ์ง์ด ๋๊ฒ ์ต๋๋ค.
- ํธ๋์ญ์
(Transaction): ์ฌ๋ฌ DB ์์
์ "์ ๋ถ ์ฑ๊ณต ์๋๋ฉด ์ ๋ถ ์ทจ์" ๋ก ๋ฌถ์ ํ ๋ฌถ์์
๋๋ค. ๋ค ์ ๋์ผ๋ฉด
COMMIT, ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฉดROLLBACKํฉ๋๋ค. - ํํ(tuple): PostgreSQL์์ "ํ(row)" ์ ๋ถ๋ฅด๋ ๋ง์ ๋๋ค. Tup์ผ๋ก ์์ํ๋ ์งํ(Tup Fetched·Returned·Inserted·Updated·Deleted)๋ ๋ชจ๋ "๋ช ๊ฐ์ ํ์ ๋ค๋ค๋" ๋ฅผ ์ ๋๋ค.
- sigma ์งํ: ์ด ์์ญ ๋ค์ ์งํ ์์ ๋ถ์
(sigma)๋ ๋์ ์นด์ดํฐ์ ๊ตฌ๊ฐ ํฉ์ ๋ปํฉ๋๋ค. 1๋ถ ๋์ ๋ฐ์ํ ์์ ๋ํ ๊ฐ์ผ๋ก ๋ณด๋ฉด ๋ฉ๋๋ค.
TPS (๊ฑด/์ด)
์ด๋น ํธ๋์ญ์ ์์ ๋๋ค. ์ปค๋ฐ·๋กค๋ฐฑ์ผ๋ก ๋๋ ํธ๋์ญ์ ์ ์ด๋น ๋จ์๋ก ๋ณธ ๊ฒ์ ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 799, ๋ฒ์ 0 ~ 47,500. ํ์์๋ ๊ฝค ๋๊ณ , ์๊ฐ 4๋ง์ ๋๊ธด ์ ์ด ์์ต๋๋ค. PostgreSQL ์ธ์คํด์ค๊ฐ MySQL·Oracle๋ณด๋ค ํธ๋์ญ์ ์ฒ๋ฆฌ๋์ด ํจ์ฌ ๋์ ํ๊ฒฝ์์ ๋ณด์ฌ ์ค๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ๋๋ ๋ฐฐ์น(์ฆ์ ๋จ๊ฑด ์ปค๋ฐ), ํธ๋ํฝ ๊ธ์ฆ, ํ ์์ ์ ์๊ฒ ์ชผ๊ฐ ์ปค๋ฐํ๋ ์ฝ๋.
์ฐ๊ธฐ ์ชฝ TPS๊ฐ ๋น์ ์์ ์ผ๋ก ๋์ ํํ ์์ธ์ ํ ๊ฑด์ฉ ์ปค๋ฐํ๋ ์ฝ๋์ ๋๋ค.
-- ๋์ ์: ํ ๊ฑด์ฉ INSERT + ๋งค ๊ฑด COMMIT (ํธ๋์ญ์
์๊ฐ ํญ์ฆ)
-- ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ฃจํ๋ฅผ ๋๋ฉฐ ๋งค ๊ฑด ์ปค๋ฐํ๋ฉด TPS์ WAL flush๊ฐ ํจ๊ป ์น์๋๋ค
-- for (row : rows) { insert(row); conn.commit(); }
-- ๊ณ ์น ์: ์ฌ๋ฌ ๊ฑด์ ๋ชจ์ ํ ๋ฒ์ ์ปค๋ฐ (ํธ๋์ญ์
์๊ฐ ํฌ๊ฒ ์ค๋ค)
-- conn.setAutoCommit(false);
-- for (row : rows) { insert(row); }
-- conn.commit(); // ํ ๋ฒ๋ง ์ปค๋ฐ
- ํจ๊ป ํ์ธํ ์งํ: Xact Commit·Xact Rollback์ด ๊ฐ์ด ์ค๋ฅด๋ฉด → ํธ๋์ญ์ ์ ์์ฒด๊ฐ ๋์ด๋ ๊ฒ์ ๋๋ค(์๋). Active Backend·CPU๊ฐ ๋๋ฐ์ด๋ฉด → ์ค์ ๋ถํ ์ฆ๊ฐ์ ๋๋ค. Write IOPS๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ์ปค๋ฐ์ด ๋์คํฌ ์ฐ๊ธฐ(WAL flush)๋ก ๋ด๋ ค๊ฐ๋ ์ค์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — TPS๋ ์ปค๋ฐ·๋กค๋ฐฑ ํ์์ ๋น๋กํฉ๋๋ค. ๋งค ๊ฑด๋ง๋ค ์ปค๋ฐํ๋ ์ฝ๋๋ ํธ๋์ญ์ ์๋ฅผ ์๊ฒ ๋๋ฆฌ๊ณ WAL flush ๋ถ๋ด์ ํค์๋๋ค. ํ ๋ฌถ์ ๋จ์๋ก ์ปค๋ฐํ๋ฉด TPS์ ๋์คํฌ ์ฐ๊ธฐ ๋ถ๋ด์ด ํจ๊ป ์ค์ด๋ญ๋๋ค. ๋จ, ๋๋ฌด ํฌ๊ฒ ๋ฌถ์ผ๋ฉด ๊ทธ ํธ๋์ญ์ ์ด ์ค๋ ์ด์ ์ฃฝ์ ํ ์ ๋ฆฌ(VACUUM)๋ฅผ ๋ง์ผ๋ฏ๋ก, ์ ๋นํ ๋จ์(์์ฒ~์๋ง ๊ฑด)๋ก ๋๋๋ ๊ฒ์ด ๊ท ํ์ ์ ๋๋ค.
Xact Commit (๊ฑด) / Xact Rollback (๊ฑด)
๊ฐ๊ฐ Commit / Rollback์ผ๋ก ๋๋ ํธ๋์ญ์ ์์ ๋๋ค(1๋ถ ๊ตฌ๊ฐ ํฉ).
- ๊ด์ธก๊ฐ: Xact Commit ํ๊ท ์ฝ 3,989 / 904 ~ 237,484, Xact Rollback ํ๊ท ์ฝ 7.1 / 0 ~ 37. ์ปค๋ฐ์ด ์๋์ ์ผ๋ก ๋ง๊ณ ๋กค๋ฐฑ์ ๊ฑฐ์ ์์ต๋๋ค. ์ ์์ ์ธ ๋ชจ์ต์ ๋๋ค.
- ์ฝ๋ ๋ฒ: Rollback์ด ํ์๋ณด๋ค ๋๋ฉด ํธ๋์ญ์ ์ด ์์ฃผ ์คํจํด ๋๋๋ ค์ง๊ณ ์๋ค๋ ๋ป์ ๋๋ค. ๋ฝ ๊ฒฝํฉ·๊ต์ฐฉ(deadlock)·์ ์ฝ์กฐ๊ฑด ์๋ฐ·์ ํ๋ฆฌ์ผ์ด์ ์์ธ ๋ฑ์ ์์ฌํฉ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: Commit ๊ธ์ฆ → ๋๋ ๋ฐฐ์น·์ฆ์ ๋จ๊ฑด ์ปค๋ฐ. Rollback ๊ธ์ฆ → ํธ๋์ญ์ ์คํจ ์ฆ๊ฐ(์๋ฌ·๊ต์ฐฉ).
-- ์ปค๋ฐ/๋กค๋ฐฑ ๋์ ์นด์ดํฐ ํ์ธ (ํ์ฌ DB ๊ธฐ์ค)
SELECT datname, xact_commit, xact_rollback
FROM pg_stat_database
WHERE datname = current_database();
- ํจ๊ป ํ์ธํ ์งํ: Xact Commit·TPS·Write IOPS๊ฐ ํจ๊ป ์ค๋ฅด๋ฉด → ์ ์์ ์ธ ์ฐ๊ธฐ ๋ถํ์ ๋๋ค. Xact Rollback์ด Deadlocks·Locks Waiting๊ณผ ํจ๊ป ์ค๋ฅด๋ฉด → ๊ต์ฐฉ·๋ฝ ๊ฒฝํฉ์ผ๋ก ํธ๋์ญ์ ์ด ๋๋๋ ค์ง๋ ๊ฒ์ผ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ๋กค๋ฐฑ์ด ์ฆ๋ค๋ ๊ฒ์ ๋น์ฆ๋์ค ๋ก์ง์ด ์คํจ๋ฅผ ์์ฃผ ๋ง๋๋ค๋ ๋ป์ ๋๋ค. ๊ต์ฐฉ(deadlock)์ผ๋ก ์ธํ ๋กค๋ฐฑ์ด๋ผ๋ฉด ํธ๋์ญ์ ์์์ ์ฌ๋ฌ ํ ์ด๋ธ·ํ์ ๊ฑด๋๋ฆฌ๋ ์์๋ฅผ ์ฝ๋ ์ ๋ฐ์์ ์ผ์ ํ๊ฒ ๋ง์ถฐ ๊ต์ฐฉ ๊ฐ๋ฅ์ฑ์ ์ค์ ๋๋ค. ์ ์ฝ์กฐ๊ฑด ์๋ฐ์ด ์ฆ๋ค๋ฉด ์ฌ์ ๊ฒ์ฆ์ ๊ฐํํฉ๋๋ค.
Trx Time (์ด)
ํธ๋์ญ์ ๋น๊ต ์๋จธ๋ฆฌ ์งํ๋ก, ํธ๋์ญ์ ์ด ์งํ๋ ์๊ฐ์ ๊ฐ๋ ํ๋ ๊ฐ์ ๋๋ค. ํ ํธ๋์ญ์ ์ด ์ผ๋ง๋ ์ค๋ ์ด์ ์๋์ง๋ฅผ ๋ด ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 0.24์ด, ๋ฒ์ 0 ~ 1,017.48์ด. ํ์์ ๋งค์ฐ ์งง์๋ฐ ์ด๋ค ์๊ฐ 1,000์ด(์ฝ 17๋ถ)๋ฅผ ๋๊ธด ํธ๋์ญ์ ์ด ์์์ต๋๋ค. ์ด ๊ธด ํธ๋์ญ์ ์ด ์ํ ์ ํธ์ ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ํธ๋์ญ์
์ ์ด์ด ๋ ์ฑ ์ค๋ ๋ฐฉ์น(
idle in transaction), ์ธ๋ถ ์์ ์ ํธ๋์ญ์ ์์์ ๊ธฐ๋ค๋ฆผ, ๊ฑฐ๋ํ ๋จ์ผ ํธ๋์ญ์ .
PostgreSQL์์ ๊ธด ํธ๋์ญ์ ์ ํนํ ์กฐ์ฌํด์ผ ํฉ๋๋ค. ํธ๋์ญ์ ์ด ์ค๋ ์ด์ ์์ผ๋ฉด ๊ทธ ์์ ์ดํ์ ์ฃฝ์ ํ์ VACUUM์ด ์ฒญ์ํ์ง ๋ชปํฉ๋๋ค. ๊ทธ ํธ๋์ญ์ ์ด ์ ๋ฒ์ ์ ์์ง ๋ณผ ์๋ ์๋ค๊ณ ๋ณด๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋์ ๊ธด ํธ๋์ญ์ ํ๋๊ฐ ํ ์ด๋ธ ํฝ์ฐฝ๊ณผ Age ์์น์ ์ ๋ฐํ ์ ์์ต๋๋ค.
-- ์ค๋ ์ด์ ์๋ ํธ๋์ญ์
์ฐพ๊ธฐ (idle in transaction ํฌํจ)
SELECT pid, usename, state,
now() - xact_start AS xact_age,
now() - state_change AS in_state_for,
query
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
ORDER BY xact_age DESC;
- ํจ๊ป ํ์ธํ ์งํ: Current Age·Age Used Ratio๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ๊ธด ํธ๋์ญ์ ์ด ์ฃฝ์ ํ ์ ๋ฆฌ๋ฅผ ๋ง์ ๋ ธํ๊ฐ ์งํ๋๋ ์ค์ ๋๋ค. Locks Waiting์ด ๊ฐ์ด ์ค๋ฅด๋ฉด → ๊ทธ ํธ๋์ญ์ ์ด ๋ฝ์ ์ฅ๊ณ ์ ๋๋ ๊ฒ์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ํธ๋์ญ์ ์ ์งง๊ฒ ๊ฐ์ ธ๊ฐ๋ ๊ฒ์ด PostgreSQL์์ ํนํ ์ค์ํฉ๋๋ค. ํธ๋์ญ์ ์์ ์ธ๋ถ API ํธ์ถ·ํ์ผ ์ฒ๋ฆฌ·์ฌ์ฉ์ ์ ๋ ฅ ๋๊ธฐ ๊ฐ์ ๊ธด ์์ ์ ๋ฃ์ผ๋ฉด ๊ทธ ์๊ฐ๋งํผ ํธ๋์ญ์ ์ด ์ด์ ์์ด VACUUM์ ๋ง๊ณ ๋ฝ์ ์ฅก๋๋ค. DB ๋ณ๊ฒฝ ๊ตฌ๊ฐ๋ง ์งง๊ฒ ๋ฌถ์ด ์ฆ์ ์ปค๋ฐํ๊ณ , ๊ธด ์์ ์ ํธ๋์ญ์ ๋ฐ์ผ๋ก ๋นผ์ผ ํฉ๋๋ค.
Tup Fetched (๊ฑด) / Tup Returned (๊ฑด)
- Tup Fetched: ์ฟผ๋ฆฌ๋ก ์ค์ ๋ก ๊ฐ์ ธ์จ(fetched) ํ ์์ ๋๋ค. ์ธ๋ฑ์ค ๋ฑ์ ํตํด ์ค์ ๋ก ํด๋ผ์ด์ธํธ์ ์ ๋ฌ๋ ํ์ ๊ฐ๊น์ต๋๋ค.
- Tup Returned: ์ฟผ๋ฆฌ๊ฐ ์ฒ๋ฆฌ ๊ณผ์ ์์ ์ฝ์ด ํ์(returned/scanned) ํ ์์ ๋๋ค. ์์ฐจ ์ค์บ์ผ๋ก ํ์ ํ๊น์ง ํฌํจํ๋ฏ๋ก, ํ ์ค์บ์ด ๋ง์ผ๋ฉด ์ด ๊ฐ์ด ์ปค์ง๋๋ค.
- ๊ด์ธก๊ฐ: Tup Fetched ํ๊ท ์ฝ 5,723 / 1,203 ~ 43,031, Tup Returned ํ๊ท ์ฝ 63,236 / 10,030 ~ ์ฝ 1.36์ต. Returned์ ์ต๋๊ฐ์ด 1์ต์ ๋๋ ๊ฒ์ด ๋์ ๋๋๋ค. ์๊ฐ์ ์ผ๋ก ์์ฒญ๋ ์์ ํ์ ํ์๋ค๋ ๋ป์ ๋๋ค.
- ์ฝ๋ ๋ฒ: Returned๊ฐ Fetched๋ณด๋ค ํจ์ฌ ํฌ๋ฉด, ๋ง์ด ํ์๋๋ฐ ์ค์ ๋ก ์ด ํ์ ์ ๋ค๋ ๋ป — ์ฆ ๋นํจ์จ์ ์ผ๋ก ํ ์ค์บํ๊ณ ์์ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค. ๋ค์ ์งํ(Rows Hit Ratio)๊ฐ ๋ฐ๋ก ์ด ๋น์จ์ ๋ด ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๋ ํ ์ค์บ, ๋์ ๋ฒ์ ์กฐํ, ๋ํ ์กฐ์ธ.
-- ๊ฐ์ ธ์จ ํ / ํ์ ํ ๋์ ์นด์ดํฐ
SELECT datname, tup_fetched, tup_returned
FROM pg_stat_database
WHERE datname = current_database();
- ํจ๊ป ํ์ธํ ์งํ: Tup Returned๊ฐ Tup Fetched๋ณด๋ค ํจ์ฌ ํฌ๊ณ Blks Read·CPU๊ฐ ๋๋ฐ์ด๋ฉด → ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๋ ํ ์ค์บ์ ๋๋ค. Rows Hit Ratio๊ฐ ๊ฐ์ด ๋จ์ด์ง๋ฉด → ํ์ ๊ฒ ๋๋น ์ด ํ์ด ์ ์ ๋นํจ์จ์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — Returned๊ฐ Fetched๋ณด๋ค ํจ์ฌ ํฌ๋ค๋ ๊ฒ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋ง์ด ์ฝ๊ณ ๋๋ถ๋ถ์ ๋ฒ๋ฆฐ๋ค๋ ๋ป์ ๋๋ค. WHERE ์กฐ๊ฑด์ ๋ง๋ ์ธ๋ฑ์ค๊ฐ ์์ด ์ ๋ถ ํ์ ๋ค ๊ฑฐ๋ฅด๋ ๊ฒฝ์ฐ๊ฐ ๋ํ์ ์ ๋๋ค. ์กฐํ ์กฐ๊ฑด·์กฐ์ธ ํค์ ์ธ๋ฑ์ค๋ฅผ ์ค๊ณํด "ํ์ํ ํ๋ง ๊ณจ๋ผ ์ฝ๋๋ก" ๋ง๋ค๋ฉด ๋ ๊ฐ์ ๊ฒฉ์ฐจ๊ฐ ์ค์ด๋ญ๋๋ค.
Tup Inserted (๊ฑด) / Tup Updated (๊ฑด) / Tup Deleted (๊ฑด)
๊ฐ๊ฐ ์ฟผ๋ฆฌ๋ก ์ฝ์ ·๊ฐฑ์ ·์ญ์ ๋ ํ ์์ ๋๋ค(1๋ถ ๊ตฌ๊ฐ ํฉ). PostgreSQL์์ ์ด ์ธ ์งํ, ํนํ Update์ Delete๋ Dead Tuple๊ณผ ์ง๊ฒฐ๋๋ฏ๋ก ์ค์ํฉ๋๋ค.
- ๊ด์ธก๊ฐ:
- Tup Inserted: ํ๊ท ์ฝ 1,041 / 223 ~ 3,267
- Tup Updated: ํ๊ท ์ฝ 408 / 103 ~ 970
- Tup Deleted: ํ๊ท ์ฝ 93 / 0 ~ 35,123
- ์ฝ๋ ๋ฒ: Insert๋ ์ฃฝ์ ํ์ ๊ฑฐ์ ์ ๋ง๋ค์ง๋ง, Update์ Delete๋ ์ ๋ฒ์ ํ์ ์ฃฝ์ ํ์ผ๋ก ๋จ๊น๋๋ค. Update ํ ๋ฒ์ "์ ๋ฒ์ ์ถ๊ฐ + ์ ๋ฒ์ ์ ์ฃฝ์ ํ์ผ๋ก ํ์" ์ด๊ณ , Delete๋ ๊ทธ ํ์ ์ฃฝ์ ํ์ผ๋ก ํ์ํฉ๋๋ค. ๊ทธ๋์ Tup Updated·Tup Deleted๊ฐ ํฌ๋ฉด ๊ทธ๋งํผ ์ฃฝ์ ํ์ด ์์ฌ ์ดํ autovacuum์ด ์ผํด์ผ ํฉ๋๋ค. Tup Deleted ์ต๋๊ฐ 35,123์ ๋๋ ์ญ์ ๋ฐฐ์น๊ฐ ๋ ์๊ฐ์ผ๋ก ๋ณด์ ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ๋๋ ๋ฐฐ์น(์ ์ฌ·๊ฐฑ์ ·์ญ์ ), ๋ฐ์ดํฐ ๋ง์ด๊ทธ๋ ์ด์ . ํนํ Update/Delete ๊ธ์ฆ ๋ค์๋ ์ฃฝ์ ํ ๋์ ๊ณผ autovacuum ๋์์ด ๋ฐ๋ผ์ต๋๋ค.
๋๋ ๋ณ๊ฒฝ์ ํ ๋ฒ์ ๋ชฐ์ ํ๋ฉด ์ฃฝ์ ํ์ด ํ๊บผ๋ฒ์ ์์์ง๋๋ค. ๋๋ ์ ์ฒ๋ฆฌํ๋ฉด ๋ถ์ฐ๋ฉ๋๋ค.
-- ๋์ ์: ์๋ฐฑ๋ง ํ์ ํ ๋ฒ์ ๊ฐฑ์ → ์ฃฝ์ ํ์ด ํ๊บผ๋ฒ์ ์์์ง๋ค
UPDATE orders SET status = 'ARCHIVED'
WHERE created_at < '2025-01-01';
-- ๊ณ ์น ์: ๋ช ๋ง ๊ฑด์ฉ ๋๋ ์ ๊ฐฑ์ (์ฃฝ์ ํ ๋ฐ์์ ๋ถ์ฐ, VACUUM ๋ถ๋ด ์ํ)
-- ํ ๋ฒ์ 5๋ง ๊ฑด์ฉ ์ฒ๋ฆฌํ๊ณ ๊ทธ๋๊ทธ๋ ์ปค๋ฐํ๋ค
WITH target AS (
SELECT order_id FROM orders
WHERE created_at < '2025-01-01' AND status <> 'ARCHIVED'
LIMIT 50000
)
UPDATE orders o SET status = 'ARCHIVED'
FROM target t WHERE o.order_id = t.order_id;
-- ์ UPDATE๋ฅผ ์ํฅ ํ์ด 0์ด ๋ ๋๊น์ง ๋ฐ๋ณตํ๋ฉฐ ๋ฌถ์๋ง๋ค ์ปค๋ฐ
-- ํ
์ด๋ธ๋ณ ์ฝ์
·๊ฐฑ์ ·์ญ์ ์ ํ์ฌ ์ฃฝ์ ํ ์๋ฅผ ํจ๊ป ๋ณธ๋ค
SELECT relname, n_tup_ins, n_tup_upd, n_tup_del,
n_live_tup, n_dead_tup, last_autovacuum
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;
- ํจ๊ป ํ์ธํ ์งํ: Tup Updated·Tup Deleted ๊ธ์ฆ ๋ค์ pg_stat_user_tables์
n_dead_tup์ด ์ค๋ฅด๋ฉด → ์ฃฝ์ ํ์ด ์์ด๋ ๊ฒ์ ๋๋ค. ์ดํ CPU์ Write IOPS๊ฐ ์ค๋ฅด๋ฉด → autovacuum์ด ์ฒญ์๋ฅผ ์์ํ ๊ฒ์ ๋๋ค. Age Used Ratio๊ฐ ํจ๊ป ์ค๋ฅด๋ฉด → ์ ๋ฆฌ๊ฐ ๋ชป ๋ฐ๋ผ๊ฐ ๋ ธํ๊ฐ ์งํ๋๋ ์ค์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — PostgreSQL์์ UPDATE/DELETE๋ ๋จ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ๋ ๊ฒ ์ด์์ผ๋ก, ์ฃฝ์ ํ์ ๋ง๋ค์ด VACUUM ๋ถ๋ด์ ๋จ๊น๋๋ค. ๋๋ ๋ณ๊ฒฝ์ ํ๋์ ํฐ ํธ๋์ญ์ ์ผ๋ก ๋ชฐ๋ฉด ์ฃฝ์ ํ์ด ํ๊บผ๋ฒ์ ์์ด๊ณ ํ ์ด๋ธ์ด ํฝ์ฐฝํฉ๋๋ค. ๋ฐฐ์น๋ ๋ช ๋ง ๊ฑด ๋จ์๋ก ๋๋ ์ปค๋ฐํ๊ณ , ์์ฃผ ๊ฐฑ์ ๋๋ ํ ์ด๋ธ์ ๋ถํ์ํ UPDATE(๊ฐ์ด ์ ๋ฐ๋๋๋ฐ๋ ๊ฐฑ์ )๋ฅผ ์ค์ด๋ ๊ฒ์ด ์ข์ต๋๋ค. ๊ฐ์ ํ์ ๋ฐ๋ณต ๊ฐฑ์ ํ๋ ํจํด์ด๋ผ๋ฉด
HOT update๊ฐ ์ ์ผ์ด๋๋๋ก ์ธ๋ฑ์ค ์ปฌ๋ผ์ ์์ฃผ ์ ๋ฐ๊พธ๋ ์ค๊ณ๋ ๋์์ด ๋ฉ๋๋ค.์ค๋ฌด ์๋๋ฆฌ์ค — ๋งค์ผ ์๋ฒฝ ๋๋ UPDATE ๋ฐฐ์น๊ฐ ๋๋ ํ ์ด๋ธ์ด ์ ์ ๋๋ ค์ง๋ค๊ณ ํด๋ณด๊ฒ ์ต๋๋ค. ๋งค๋ฒ ์์ญ๋ง ํ์ ํ ํธ๋์ญ์ ์ผ๋ก ๊ฐฑ์ ํ๋ฉด์ ์ฃฝ์ ํ์ด ์์์ง๋๋ฐ, autovacuum์ด ๊ทธ ์๋๋ฅผ ๋ชป ๋ฐ๋ผ๊ฐ
n_dead_tup์ด ๊ณ์ ์์ด๊ณ ํ ์ด๋ธ์ด ์ค์ ๋ฐ์ดํฐ์ ๋ช ๋ฐฐ๋ก ํฝ์ฐฝํฉ๋๋ค. ํฝ์ฐฝํ ํ ์ด๋ธ์ ๊ฐ์ ์ฟผ๋ฆฌ๋ ๋ ๋ง์ ๋ธ๋ก์ ์ฝ์ด ๋๋ ค์ง๋๋ค. ๋ฐฐ์น๋ฅผ 5๋ง ๊ฑด ๋จ์๋ก ๋๋ ์ปค๋ฐํ๊ณ ํด๋น ํ ์ด๋ธ์ autovacuum์ ๋ ์์ฃผ ๋๋๋ก ์กฐ์ ํ๋ฉด, ์ฃฝ์ ํ์ด ์ ๋ ์ ๋ฆฌ๋๋ฉฐ ํฝ์ฐฝ๊ณผ ์๋ ์ ํ๊ฐ ์กํ๋๋ค.
4. ์บ์ · ์ฝ๊ธฐ
PostgreSQL๋ ์์ฃผ ์ฐ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ(shared_buffers, ๋ฒํผ ์บ์)์ ์บ์ฑํด ๋์คํฌ ์ ๊ทผ์ ์ค์ ๋๋ค. ์์ฃผ ๋ณด๋ ์๋ฃ๋ฅผ ์๊ฐ๊น์ง ๊ฐ์ง ์๊ณ ์ฑ ์ ์์ ์ฌ๋ ค๋๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. ์ฑ ์์์ ๋ฐ๋ก ์ฐพ์ผ๋ฉด ๋น ๋ฅด๊ณ (๋ฉ๋ชจ๋ฆฌ), ์๊ฐ๊น์ง ๊ฐ์ผ ํ๋ฉด ๋๋ฆฝ๋๋ค(๋์คํฌ).
์ด ์์ญ์ ์ฉ์ด๋ฅผ ๋จผ์ ํ์ด ๋๊ฒ ์ต๋๋ค.
- ๋ ผ๋ฆฌ ์ฝ๊ธฐ(Blks Hit) / ๋ฌผ๋ฆฌ ์ฝ๊ธฐ(Blks Read): "๋ฐ์ดํฐ๋ฅผ ์ฝ์ด ๋ฌ๋ผ" ๋ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ๋จผ์ ๋ฒํผ ์บ์(๋ฉ๋ชจ๋ฆฌ)๋ถํฐ ์ฐพ์๋ด ๋๋ค. ๋ฉ๋ชจ๋ฆฌ์์ ๋ฐ๋ก ์ฐพ์ ๊ฒ์ด Blks Hit(๋ ผ๋ฆฌ ์ฝ๊ธฐ) ์ด๊ณ , ์บ์์ ์์ด ๋์คํฌ๊น์ง ๋ด๋ ค๊ฐ ์ฝ์ ๊ฒ์ด Blks Read(๋ฌผ๋ฆฌ ์ฝ๊ธฐ) ์ ๋๋ค. Blks Hit๋ ๋น ๋ฅด๊ณ Blks Read๋ ๋๋ฆฝ๋๋ค.
- ์ ์ค๋ฅ (Cache Hit Ratio): ์ ์ฒด ์ฝ๊ธฐ ์ค์์ ๋์คํฌ๊น์ง ๊ฐ์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ์์ ๋ฐ๋ก ์ฐพ์ ๋น์จ์ ๋๋ค. ๋์์๋ก ๋์คํฌ๋ฅผ ๋ ๊ฑด๋๋ ค ๋น ๋ฆ ๋๋ค.
Cache Hit Ratio (%)
๋ฒํผ ์บ์ ์ ์ค๋ฅ ์
๋๋ค. ์ฐ์์ 100 * blksHit / (blksRead + blksHit), "๋์คํฌ๊น์ง ์ ๊ฐ๊ณ ๋ฉ๋ชจ๋ฆฌ์์ ๋ฐ๋ก ์ฐพ์ ๋น์จ" ์
๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 99.13%, ๋ฒ์ 99.02 ~ 99.22%. ๊ฑฐ์ ๋ชจ๋ ์ฝ๊ธฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํด๊ฒฐ๋ฉ๋๋ค. ์ด ์ ๋๊ฐ ์ ์์ ๋๋ค.
- ์ํ ์ ํธ: ๋์ ๋๊ฒ ๋จ์ด์ง๋ฉด(์: 95% ์ดํ) ๋์คํฌ๋ฅผ ์์ฃผ ์ฝ๊ณ ์๋ค๋ ๋ป์ด๊ณ ์ฑ๋ฅ์ด ๋๋น ์ง๋๋ค.
- ํ๋ฉด(๋จ์ด์ง๋ฉด) ์์ฌํ ๊ฒ: shared_buffers ๋ถ์กฑ, ์บ์์ ์๋ ๋๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์๊ธฐ ์กฐํ(๋ํ ํ ์ค์บ), ์ฝ๋ ์คํํธ(์ฌ๊ธฐ๋ ์งํ ์บ์๊ฐ ๋น์ด ์์), ํ ์ด๋ธ ํฝ์ฐฝ์ผ๋ก ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ๋ ๋ง์ ๋ธ๋ก์ ํฉ์ด์ง.
์ ์ค๋ฅ ์ ๋จ์ด๋จ๋ฆฌ๋ ๋ํ ์์ธ์ "ํฐ ํ ์ด๋ธ์ ํ ๋ฒ์ ํ ์ค์บ" ํด์ ์ฑ ์(์บ์)์ ๊ทธ ๋ฐ์ดํฐ๋ก ๊ฐ๋ ์ฑ์ ํ์ ์ฐ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ด๋ด๋ ๊ฒฝ์ฐ์ ๋๋ค.
-- ๋์ ์: ์ธ๋ฑ์ค ์์ด ๊ฑฐ๋ํ ํ
์ด๋ธ ์ ์ฒด๋ฅผ ๋์ด์ ์บ์๋ฅผ ์ค์ผ์ํจ๋ค
SELECT * FROM event_logs ORDER BY created_at;
-- ๊ณ ์น ์: ํ์ํ ๋ฒ์๋ง, ์ธ๋ฑ์ค๋ก ์ขํ์ ์ฝ๋๋ค
SELECT id, type, created_at
FROM event_logs
WHERE created_at >= TIMESTAMP '2026-06-18 00:00:00'
AND created_at < TIMESTAMP '2026-06-19 00:00:00';
-- ํ์ฌ DB์ ์บ์ ์ ์ค๋ฅ ์ง์ ๊ณ์ฐ
SELECT datname,
ROUND(100.0 * blks_hit / NULLIF(blks_hit + blks_read, 0), 2) AS cache_hit_pct
FROM pg_stat_database
WHERE datname = current_database();
- ํจ๊ป ํ์ธํ ์งํ: ์ ์ค๋ฅ ํ๋ฝ๊ณผ ํจ๊ป Blks Read·Read IOPS๊ฐ ์ค๋ฅด๋ฉด → ๋์คํฌ ์ฝ๊ธฐ๊ฐ ์ค์ ๋ก ๋์ด๋ ๊ฒ์ ๋๋ค. Tup Returned๋ ๊ฐ์ด ๋ฐ๋ฉด → ๋ํ ํ ์ค์บ์ด ์บ์๋ฅผ ์ค์ผ์ํค๋ ์ค์ ๋๋ค. ์ฌ๊ธฐ๋ ์งํ ์ผ์์ ์ผ๋ก ๋ฎ์ผ๋ฉด → ์ฝ๋ ์คํํธ๋ก, ๋ฐ์ดํฐ๊ฐ ๋ค์ ์ฑ์์ง๋ฉด ํ๋ณต๋ฉ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ์์ฃผ ์ฐ์ง ์๋ ๋์ฉ๋ ๋ฐ์ดํฐ๋ฅผ ํ๊บผ๋ฒ์ ํ์ผ๋ฉด(์: ์ ์ฒด ํ ์ด๋ธ ์ง๊ณ) ์บ์์ ์๋ ์์ฃผ ์ฐ๋ ๋ฐ์ดํฐ๊ฐ ๋ฐ๋ ค๋ ์ ์ค๋ฅ ์ด ๋จ์ด์ง๋๋ค. ๋๋ ์ฒ๋ฆฌ๋ ์ด์ ํธ๋ํฝ๊ณผ ์๊ฐ๋๋ฅผ ๋ถ๋ฆฌํ๊ณ , ๊ผญ ํ์ํ ๋ฒ์๋ง ์ธ๋ฑ์ค๋ก ์ขํ ์ฝ๋๋ก ์ง๋ ๊ฒ์ด ์ข์ต๋๋ค.
Rows Hit Ratio (%)
์ฟผ๋ฆฌ row ์ ์ค๋ฅ ์
๋๋ค. ์ฐ์์ 100 * tup_fetched / tup_returned, "ํ์ ํ ์ค ์ค์ ๋ก ๊ฐ์ ธ๋ค ์ด ํ์ ๋น์จ" ์
๋๋ค. ์บ์ ์ ์ค๋ฅ (๋ธ๋ก ๋จ์)๊ณผ๋ ๋ค๋ฅธ, ํ ๋จ์์ ํจ์จ ์งํ์
๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 13.2%, ๋ฒ์ 0 ~ 50.9%. ๋ฎ๊ฒ ๊น๋ ค ์์ต๋๋ค. ์ด ๊ฐ์ด ๋ฎ๋ค๋ ๊ฒ์ ํ์ ํ์ ๋นํด ์ค์ ๋ก ์ฐ๋ ํ์ด ์ ๋ค๋ ๋ป์ผ๋ก, ์์ฐจ ์ค์บ ๋น์ค์ด ํฌ๋ค๋ ์ ํธ๋ก ์ฝ์ ์ ์์ต๋๋ค. ๋ค๋ง ์ํฌ๋ก๋ ํน์ฑ์ ํฌ๊ฒ ์ข์ฐ๋๋ฏ๋ก ์ ๋๊ฐ๋ณด๋ค ์ถ์ธ๋ก ๋ด ๋๋ค.
- ํ๋ฉด(๋จ์ด์ง๋ฉด) ์์ฌํ ๊ฒ: ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๊ณ ๋ง์ด ํ์ด ๊ฑฐ๋ฅด๋ ์ฟผ๋ฆฌ๊ฐ ๋์ด๋จ, ๋์ ๋ฒ์๋ฅผ ์ฝ๊ณ ์ผ๋ถ๋ง ์ฐ๋ ํจํด.
- ํจ๊ป ํ์ธํ ์งํ: Rows Hit Ratio๊ฐ ๋จ์ด์ง๋ฉฐ Tup Returned·Blks Read·CPU๊ฐ ์ค๋ฅด๋ฉด → ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๋ ํ ์ค์บ์ด ๋์ด๋ ๊ฒ์ ๋๋ค. ๋ฐ๋๋ก ํํํ๋ฉด ์ํฌ๋ก๋์ ์ ์ ํน์ฑ์ผ๋ก ๋ด ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ์ด ๋น์จ์ด ๋ฎ๋ค๋ ๊ฒ์ "๋ง์ด ์ฝ๊ณ ์ ๊ฒ ์ด๋ค" ๋ ๋ป์ด๋ผ, ์ธ๋ฑ์ค๋ก ํ์ํ ํ๋ง ๊ณจ๋ผ ์ฝ๋๋ก ๋ฐ๊พธ๋ฉด ๊ฐ์ ๋ฉ๋๋ค. ๋ค๋ง ์ํฌ๋ก๋์ ๋ฐ๋ผ ๋ณธ๋ ๋ฎ์ ์ ์์ด, ์ ๋๊ฐ๋ณด๋ค ๊ฐ์๊ธฐ ๋ ๋จ์ด์ก๋์ง๋ฅผ ๋ด ๋๋ค.
Blks Read (blocks) / Blks Hit (๊ฑด)
- Blks Read: ์บ์์ ์์ด ๋์คํฌ์์ ์ง์ ์ฝ์ ๋ธ๋ก ์(๋ฌผ๋ฆฌ ์ฝ๊ธฐ). ๊ด์ธก ํ๊ท ์ฝ 3,551, ๋ฒ์ 208 ~ ์ฝ 1,520๋ง.
- Blks Hit: ์บ์(๋ฉ๋ชจ๋ฆฌ)์์ ๋ฐ๋ก ์ฐพ์ ๋ธ๋ก ์(๋ ผ๋ฆฌ ์ฝ๊ธฐ). ๊ด์ธก ํ๊ท ์ฝ 46,252, ๋ฒ์ 11,977 ~ ์ฝ 611๋ง.
ํ์ Blks Hit๊ฐ Blks Read๋ณด๋ค ํจ์ฌ ํฌ๊ธฐ ๋๋ฌธ์ ์ ์ค๋ฅ ์ด 99%๋๋ก ๋์ต๋๋ค. Blks Read๊ฐ ํ์๋ณด๋ค ํฌ๊ฒ ๋๋ฉด "์บ์์ ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ง์ด ์ฝ๊ณ ์๋ค" ๋ ์ ํธ์ ๋๋ค. Blks Read ์ต๋๊ฐ 1,520๋ง์ ๋ํ ํ ์ค์บ์ด ๋์คํฌ๋ฅผ ํต์งธ๋ก ํ์ ์๊ฐ์ผ๋ก ๋ณด์ ๋๋ค.
-- ๋์คํฌ ์ฝ๊ธฐ(Blks Read)๋ฅผ ๋ง์ด ์ ๋ฐํ๋ ํ
์ด๋ธ ์ฐพ๊ธฐ
SELECT relname, heap_blks_read, heap_blks_hit,
idx_blks_read, idx_blks_hit
FROM pg_statio_user_tables
ORDER BY heap_blks_read DESC
LIMIT 20;
- ํจ๊ป ํ์ธํ ์งํ: Blks Read๊ฐ ์ค๋ฅด๋ฉฐ Cache Hit Ratio๊ฐ ๋จ์ด์ง๋ฉด → ์บ์ ๋ฏธ์ค๊ฐ ์ค์ ๋ก ๋์ด๋ ๊ฒ์ ๋๋ค(๋์ ๊ฐ์ ํ์์ ์๋ท๋ฉด). Read IOPS·Tup Returned๊ฐ ๋๋ฐ์ด๋ฉด → ๋๋ ํ ์ค์บ์ด ๋์คํฌ ์ฝ๊ธฐ๋ฅผ ์ ๋ฐํ๋ ์ค์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — Blks Read(๋์คํฌ ์ฝ๊ธฐ)๊ฐ ๋์๋ค๋ ๊ฒ์ ์ฝ๋๊ฐ ์บ์์ ์๋ ๋ธ๋ก์ ์์ฃผ ์์ฒญํ๋ค๋ ๋ป์ ๋๋ค. ์์ ์งํฉ(์์ฃผ ์ฐ๋ ๋ฐ์ดํฐ)์ด ์บ์์ ๋ค์ด์ฌ ๋งํผ ์กฐํ ๋ฒ์๋ฅผ ์ขํ๊ณ , ํ ๋ฒ ์ฐ๊ณ ๋ง๋ ๋์ฉ๋ ์ค์บ์ ์๊ฐ๋๋ฅผ ๋ถ๋ฆฌํ๋ฉด ๋์คํฌ ์ฝ๊ธฐ๊ฐ ์ค์ด๋ญ๋๋ค. ํ ์ด๋ธ ํฝ์ฐฝ๋ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ ๋ง์ ๋ธ๋ก์ ํฉ์ด ๋์ Blks Read๋ฅผ ๋๋ฆฌ๋ฏ๋ก, VACUUM์ด ์ ๋๋์ง๋ ํจ๊ป ๋ด ๋๋ค.
Read IOPS Max (๊ฑด/์ด) / Write IOPS Max (๊ฑด/์ด)
์ด๋น ๋์คํฌ ์ฝ๊ธฐ/์ฐ๊ธฐ I/O ์ฐ์ฐ ์์ ์ต๋์น์ ๋๋ค. IOPS๋ "์ด๋น ๋ช ๋ฒ ๋์คํฌ์ ์ ๊ทผํ๋" ๋ฅผ ๋ปํฉ๋๋ค.
๋จผ์ ์ฉ์ด๋ฅผ ์งง๊ฒ ํ์ด ๋๊ฒ ์ต๋๋ค.
- IOPS(์ด๋น ์ ์ถ๋ ฅ ํ์): 1์ด์ ๋์คํฌ๋ฅผ ๋ช ๋ฒ ์ฝ๊ฑฐ๋ ์ผ๋์ง, ๊ทธ ํ์์ ๋๋ค. "์๊ฐ๋ฅผ 1์ด์ ๋ช ๋ฒ ๋ค๋ ์๋" ์ ํด๋นํฉ๋๋ค.
- Throughput(์ฒ๋ฆฌ๋): 1์ด์ ์ค์ ๋ก ๋ช ๋ฐ์ดํธ๋ฅผ ์ฃผ๊ณ ๋ฐ์๋์ง, ๊ทธ ์์ ๋๋ค(๋ค์ ๋คํธ์ํฌ ์งํ์์ ๋ค๋ฃน๋๋ค). ํ์๊ฐ ์ ์ด๋ ํ ๋ฒ์ ํฐ ์ง์ ๋๋ฅด๋ฉด ์ฒ๋ฆฌ๋์ ํด ์ ์์ต๋๋ค.
- ๊ด์ธก๊ฐ: Read IOPS Max ํ๊ท ์ฝ 520(๋ฒ์ 55 ~ 54,427), Write IOPS Max ํ๊ท ์ฝ 2,800(๋ฒ์ 612 ~ 102,877). MySQL๊ณผ ๋ฌ๋ฆฌ ์ฐ๊ธฐ IOPS๊ฐ ํ์์๋ ๊ฝค ๋์๋ฐ, TPS๊ฐ ๋์(์ฐ๊ธฐ·์ปค๋ฐ์ด ๋ง์) ์ํฌ๋ก๋๋ผ ๊ทธ๋ ์ต๋๋ค. ์๊ฐ ์ต๋๊ฐ์ด ์ฝ๊ธฐ·์ฐ๊ธฐ ๋ชจ๋ ์๋ง๊น์ง ํ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: Read IOPS๊ฐ ์ค๋ฅด๋ฉด → ์บ์ ๋ฏธ์ค(๋ฌผ๋ฆฌ ์ฝ๊ธฐ ์ฆ๊ฐ, Blks Read ๋๋ฐ). Write IOPS๊ฐ ์ค๋ฅด๋ฉด → ๋๋ ์ฐ๊ธฐ·์ปค๋ฐ·์ฃฝ์ ํ ์ ๋ฆฌ(VACUUM). ํด๋ผ์ฐ๋(RDS)์์๋ IOPS์ ํ๋๊ฐ ์์ด, ํ๋์ ๋ถ๋ชํ๋ฉด ์ ์ฒด๊ฐ ๋๋ ค์ง๋๋ค.
- ํจ๊ป ํ์ธํ ์งํ: Read IOPS๋ Blks Read·Cache Hit Ratio์ ํจ๊ป ๋ด ๋๋ค — ์ ์ค๋ฅ ์ด ๋จ์ด์ง๋ฉฐ Read IOPS๊ฐ ์ค๋ฅด๋ฉด ์บ์ ๋ฏธ์ค์ ๋๋ค. Write IOPS๋ Xact Commit·Tup Inserted/Updated/Deleted์ ํจ๊ป ๋ณด๋ฉด → ์ฐ๊ธฐ์ ์ฃฝ์ ํ ์ ๋ฆฌ๊ฐ ๋์คํฌ๋ก ๋ด๋ ค๊ฐ๋ ์์ ๊ฐ๋ ํ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — Read IOPS๋ ์บ์์์ ๋ชป ์ฐพ์ ์ฝ๊ธฐ๊ฐ, Write IOPS๋ ๋ณ๊ฒฝ·์ปค๋ฐ·VACUUM์ด ๋์คํฌ๋ก ๋ด๋ ค๊ฐ๋ ์์ ๋๋ค. ๋งค ๊ฑด๋ง๋ค ์ปค๋ฐํ๋ ์ฝ๋๋ ๋์คํฌ ์ฐ๊ธฐ(WAL flush)๋ฅผ ์๊ฒ ๋๋ฆฌ๋ฏ๋ก ๋ฌถ์ด์ ์ปค๋ฐํ๋ฉด ๋ถ๋ด์ด ์ค๋๋ค. ํด๋ผ์ฐ๋ DB๋ IOPS์ ํ๋๊ฐ ์์ด, ํ๋๋ฅผ ๋๊ธฐ๋ ํจํด(์ฆ์ ๋จ๊ฑด ์ปค๋ฐ·๋๋ ํ ์ค์บ·๊ณผ๋ํ ์ฃฝ์ ํ ์ ๋ฆฌ)์ ์ฝ๋์ ์ด์ ๋จ๊ณ์์ ์ค์ฌ์ผ ํฉ๋๋ค.
5. Vacuum · MVCC (ํธ๋์ญ์ ID)
์ด ์์ญ์ด PostgreSQL ์งํ ์ค ๊ฐ์ฅ PostgreSQL๋ค์ด ๋ถ๋ถ์ ๋๋ค. ์์์ ํ์ด ๋ MVCC·Dead Tuple·VACUUM·ํธ๋์ญ์ ID wraparound ๊ฐ๋ ์ด ์ฌ๊ธฐ์ ์งํ๋ก ๋ํ๋ฉ๋๋ค.
ํ ์ค๊ธฐ๋ก ์ ๋ฆฌํ๋ฉด ์ด๋ ์ต๋๋ค. UPDATE·DELETE๊ฐ ์ฃฝ์ ํ(dead tuple)์ ๋ง๋ค๊ณ → VACUUM(๋ณดํต autovacuum)์ด ๊ทธ ์ฃฝ์ ํ์ ์ฒญ์ํ๋ฉฐ, ๋์์ ์์ฃผ ์ค๋๋ ํ์ freeze(๋๊ฒฐ)ํด ํธ๋์ญ์ ID๊ฐ ํ ๋ฐํด ๋๋ ์ฌ๊ณ (wraparound)๋ฅผ ๋ง์ต๋๋ค. ๋ง์ฝ ๋ณ๊ฒฝ๋์ด ๋ง์๋ฐ VACUUM์ด ๋ชป ๋ฐ๋ผ๊ฐ๋ฉด, ์ฃฝ์ ํ์ด ์์ฌ ํ ์ด๋ธ์ด ํฝ์ฐฝํ๊ณ , ๊ฐ์ฅ ์ค๋๋ ํธ๋์ญ์ ์ ๋์ด(Age)๊ฐ ์ํ ์์ค์ผ๋ก ์ฌ๋ผ๊ฐ๋๋ค. ์ด ์์ญ์ ๋ ์งํ๊ฐ ๋ฐ๋ก ๊ทธ "๋์ด" ๋ฅผ ๋ด ๋๋ค.
์ฉ์ด๋ฅผ ๋ค์ ํ ๋ฒ ์งง๊ฒ ์ ๋ฆฌํ๋ฉด:
- ํธ๋์ญ์ ID(XID): PostgreSQL์ด ๋ชจ๋ ํธ๋์ญ์ ์ ๋งค๊ธฐ๋ ๋ฒํธ. ์ฝ 21์ต์์ ํ ๋ฐํด ๋์ 0์ผ๋ก ๋์์ค๋ ๊ตฌ์กฐ์ ๋๋ค(wraparound).
- Age(๋์ด): ๊ฐ์ฅ ์ค๋๋(freeze ์ ๋) ํธ๋์ญ์ ์ด ์ง๊ธ์ผ๋ก๋ถํฐ ๋ช ๊ฐ์ ํธ๋์ญ์ ๋งํผ ๋จ์ด์ ธ ์๋์ง์ ๋๋ค. ์ด ๊ฐ์ด wraparound ํ๊ณ(์ฝ 21์ต)์ ๊ฐ๊น์์ง๋ฉด ์ํํฉ๋๋ค.
- autovacuum_freeze_max_age: ์ด ๋์ด์ ๋๋ฌํ๋ฉด PostgreSQL์ด ๊ฐ์ ๋ก freeze ์์ ์ ์์ํ๋ ๊ธฐ์ค์ ์ ๋๋ค. Age Used Ratio๊ฐ ์ด ๊ธฐ์ค ๋๋น ๋น์จ์ ๋ด ๋๋ค.
Age Used Ratio (%)
autovacuum_freeze_max_age ๊ธฐ์ค์ผ๋ก ํ์ฌ ๋์ด๊ฐ ์ผ๋ง๋ ์ฐผ๋์ง์ ๋น์จ์
๋๋ค. ํธ๋์ญ์
ID๊ฐ ํ ๋ฐํด ๋๊ธฐ๊น์ง ์ผ๋ง๋ ์ฌ์ ๊ฐ ์๋์ง๋ฅผ ํ ์ซ์๋ก ๋ณด์ฌ ์ค๋๋ค. ์ฌ์ ๊ธฐ์ค์ 85% ์ดํ๋ฅผ ๊ถ์ฅํฉ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 95.3%, ๋ฒ์ 81.7 ~ 100.0%. ๊ถ์ฅ์ (85%)๋ณด๋ค ๋๊ฒ ๊น๋ ค ์๊ณ , ์๊ฐ 100%๋ฅผ ๋๊ธด ์ ๋ ์์ต๋๋ค. ์ด ์ธ์คํด์ค๋ ๋์ด๊ฐ ๊พธ์คํ ๋๊ฒ ์ ์ง๋๋ ํธ์ด๋ผ, freeze๊ฐ ์๋ฐํ ์ํ๋ฅผ ์์ฃผ ์ง๋๋ค๋ ๋ป์ ๋๋ค. ๋ค๋ง PostgreSQL์ ์ด ๊ธฐ์ค์ ๋๋ฌํ๋ฉด autovacuum์ด ๊ฐ์ ๋ก freeze๋ฅผ ๋๋ฆฌ๋๋ก ์ค๊ณ๋ผ ์์ด, 100%์ ๋ฟ์๋ ๊ณง๋ฐ๋ก ์ฅ์ ๋ ์๋๊ณ "์ง๊ธ freeze๊ฐ ํ์ํ ์ํ" ๋ผ๋ ์ ํธ๋ก ์ฝ์ต๋๋ค.
- ์ํ ์ ํธ: ์ฌ์ ๊ธฐ์ค 85% ์ดํ ๊ถ์ฅ. ์ด๋ฅผ ๋์ด ์ง์์ ์ผ๋ก ๋์ผ๋ฉด autovacuum์ด freeze๋ฅผ ๋ชป ๋ฐ๋ผ๊ฐ๋ ๊ฒ์ผ ์ ์์ด ๋ค์ฌ๋ค๋ด์ผ ํฉ๋๋ค. ์ง์ง ์ํ์ ์ด ๋์ด๊ฐ wraparound ํ๊ณ๊น์ง ๊ณ์ ์ฌ๋ผ๊ฐ PostgreSQL์ด ์ ์ฐ๊ธฐ๋ฅผ ๊ฑฐ๋ถํ๊ณ ๋ฉ์ถ๋ ๊ฒ์ ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ์ค๋ ์ด์ ์๋ ํธ๋์ญ์
(
idle in transaction)์ด freeze๋ฅผ ๋ง์, ๋๋ ๋ณ๊ฒฝ์ ๋นํด autovacuum์ด ๋๋ฌด ๋๋ฆฌ๊ฒ ์ค์ ๋จ, ํน์ ํ ์ด๋ธ์ด ๋งค์ฐ ์ปค์ freeze๊ฐ ์ค๋ ๊ฑธ๋ฆผ.
-- ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ณ ๋์ด — wraparound๊น์ง์ ์ฌ์ ๋ฅผ ๋ณธ๋ค
SELECT datname, age(datfrozenxid) AS xid_age
FROM pg_database
ORDER BY xid_age DESC;
-- ๋์ด๊ฐ ํฐ(freeze๊ฐ ์๊ธํ) ํ
์ด๋ธ ์ฐพ๊ธฐ
SELECT relname, age(relfrozenxid) AS xid_age, last_autovacuum
FROM pg_class c
JOIN pg_stat_user_tables s ON s.relid = c.oid
WHERE c.relkind = 'r'
ORDER BY xid_age DESC
LIMIT 20;
- ํจ๊ป ํ์ธํ ์งํ: Current Age๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ๊ฐ์ ํ์(๋์ด ์์น)์ ๋ค๋ฅธ ๊ฐ๋๋ก ๋ณธ ๊ฒ์ ๋๋ค. Trx Time(๊ธด ํธ๋์ญ์ )์ด ๊ฐ์ด ํฌ๋ฉด → ์ค๋ ์ด์ ์๋ ํธ๋์ญ์ ์ด freeze๋ฅผ ๋ง๋ ์์ธ์ผ ์ ์์ต๋๋ค. Tup Updated·Tup Deleted๊ฐ ๋ง์๋ฐ last_autovacuum์ด ์ค๋๋์ผ๋ฉด → autovacuum์ด ๋ชป ๋ฐ๋ผ๊ฐ๋ ๊ฒ์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — Age๋ ์ง์ ์ฝ๋๋ก ์ค์ด๋ ๊ฐ์ ์๋์ง๋ง, ์ฝ๋๊ฐ ๊ธด ํธ๋์ญ์ ์ ๋ง๋ค๋ฉด freeze๋ฅผ ๋ง์ ๋์ด๋ฅผ ์ฌ๋ฆฝ๋๋ค. ํธ๋์ญ์ ์ ์ฐ ์ฑ ๋ ธ๋
idle in transaction์ ์์ ๊ณ (์์ ๋๋๋ฉด ์ฆ์ ์ปค๋ฐ/๋กค๋ฐฑ), ํธ๋์ญ์ ์ ์งง๊ฒ ๊ฐ์ ธ๊ฐ๋ ๊ฒ์ด ๊ฐ์ฅ ํฐ ๊ธฐ์ฌ์ ๋๋ค. ๋ณ๊ฒฝ์ด ๋ง์ ํ ์ด๋ธ์ autovacuum ์ค์ ์ ๋ ๊ณต๊ฒฉ์ ์ผ๋ก ์ก๋ ์ด์ ์กฐ์ ๋ ํจ๊ป ํ์ํฉ๋๋ค.์ค๋ฌด ์๋๋ฆฌ์ค — ์ด๋ค backend๊ฐ ํธ๋์ญ์ ์ ์ฐ ์ฑ
idle in transaction์ผ๋ก ๋ช ์๊ฐ ๋ฐฉ์น๋๋ค๊ณ ํด๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋์ PostgreSQL์ ๊ทธ ํธ๋์ญ์ ์ด ์ ๋ฒ์ ์ ๋ณผ ์ ์๋ค๊ณ ๋ณด๊ณ freeze์ ์ฃฝ์ ํ ์ ๋ฆฌ๋ฅผ ๋ฏธ๋ฃจ๋ฉฐ, Age Used Ratio๊ฐ ๊ณ์ ์ฌ๋ผ๊ฐ๋๋ค. ๋ฐฉ์น๋ ํธ๋์ญ์ ์ ์ฐพ์ ์ ๋ฆฌํ๋ฉด autovacuum์ด ๋ค์ ์งํ๋๋ฉฐ ๋์ด๊ฐ ๋ด๋ ค๊ฐ๋๋ค. ๊ทธ๋์ ๊ธดidle in transaction์ธ์ ์ PostgreSQL์์ ํนํ ์ํ ์ ํธ๋ก ๋ด ๋๋ค.
Current Age (age)
ํ์ฌ DB์์ ์ฌ์ฉ ์ค์ธ ๊ฐ์ฅ ์ค๋๋ ํธ๋์ญ์ ID์ ๋์ด์ ๋๋ค. Age Used Ratio๊ฐ ๋น์จ(%)์ด๋ผ๋ฉด, ์ด์ชฝ์ ๋์ด์ ์ ๋๊ฐ์ ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 1.91์ต(age), ๋ฒ์ ์ฝ 1.63์ต ~ 2.0์ต. wraparound ํ๊ณ(์ฝ 21์ต)์ ๋นํ๋ฉด ์ฌ์ ๊ฐ ์์ง๋ง, autovacuum_freeze_max_age(๊ธฐ๋ณธ 2์ต) ๊ธฐ์ค์ผ๋ก ๋ณด๋ฉด ๊ฑฐ์ ๊ทธ ๊ทผ์ฒ์์ ์์ง์ด๊ณ ์์ต๋๋ค. ๊ทธ๋์ Age Used Ratio๊ฐ 95%๋๋ก ๋๊ฒ ๋์ค๋ ๊ฒ์ ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: Age Used Ratio์ ๋์ผ — ๊ธด ํธ๋์ญ์ , autovacuum ์ง์ฐ, ๊ฑฐ๋ํ ํ ์ด๋ธ์ freeze ์ง์ฐ.
- ํจ๊ป ํ์ธํ ์งํ: Age Used Ratio์ ๊ฐ์ ๋ฐฉํฅ์ผ๋ก ์์ง์ด๋ ๊ฒ์ด ์ ์์ ๋๋ค(๊ฐ์ ํ์์ ์ ๋๊ฐ/๋น์จ ํํ). ๋ ๋ค ๊พธ์คํ ์ฐ์ํฅํ๋ฉด freeze๊ฐ ๋ชป ๋ฐ๋ผ๊ฐ๋ ๊ฒ์ด๋ฏ๋ก autovacuum ๋์๊ณผ ๊ธด ํธ๋์ญ์ ์ ์ ๊ฒํฉ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — Current Age๊ฐ ๊พธ์คํ ์ฐ์ํฅํ๋ค๋ฉด, ๋ณ๊ฒฝ๋ ๋๋น freeze๊ฐ ๋๋ฆฌ๋ค๋ ๋ป์ ๋๋ค. ์ฝ๋ ์ชฝ์์๋ ๊ธด ํธ๋์ญ์ ์ ์์ ๊ณ , ์ด์ ์ชฝ์์๋ autovacuum์ freeze ๋์์ด ์ ๋ ๋๋๋ก ์ค์ ์ ์กฐ์ ํฉ๋๋ค. ์ด ์งํ๋ PostgreSQL ๊ณ ์ ์ "๋ฐฉ์นํ๋ฉด DB๊ฐ ๋ฉ์ถ ์ ์๋" ํญ๋ชฉ์ด๋ผ, ์ ๋๊ฐ์ด wraparound ํ๊ณ๋ก ํฅํ๋ ์ถ์ธ๋ฅผ ํนํ ์ฃผ์ ๊น๊ฒ ๋ด ๋๋ค.
6. ๋ฝ · ๋์์ฑ
๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋์์ ๋ฐ๊พธ๋ ค ํ ๋ ๋ฝ(Lock) ์ผ๋ก ์์๋ฅผ ์ ํฉ๋๋ค. ํ์ฅ์ค ํ ์นธ์ ํ ์ฌ๋์ฉ ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์์, ํ ์ฌ๋์ด ๋๋ฌด ์ค๋ ์ฐ๋ฉด ๋ค์ ์ค์ด ๊ธธ์ด์ง๋๋ค.
์ด ์์ญ์ ๊ฐ๋ ์ ๋จผ์ ์งง๊ฒ ํ์ด ๋๊ฒ ์ต๋๋ค. (์๋ ์งํ๋ ์ด ๊ฐ๋ ๋ค์ ์ ์ ๋ก ํฉ๋๋ค.)
- ํธ๋์ญ์
(Transaction): ์ฌ๋ฌ DB ์์
์ "์ ๋ถ ์ฑ๊ณต ์๋๋ฉด ์ ๋ถ ์ทจ์" ๋ก ๋ฌถ์ ํ ๋ฌถ์์
๋๋ค. ๋ค ์ ๋์ผ๋ฉด
COMMIT, ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฉดROLLBACKํฉ๋๋ค. - ํ ๋ฝ(Row Lock): PostgreSQL์์ ์ด๋ค ํ์ ๊ณ ์น๊ธฐ ์์ํ๋ฉด, ์ปค๋ฐํ ๋๊น์ง ๊ทธ ํ์ ๋ฝ์ ๊ฑธ์ด ๋ก๋๋ค. ๋ค๋ฅธ ํธ๋์ญ์ ์ด ๊ฐ์ ํ์ ๊ณ ์น๋ ค๋ฉด ๊ทธ ๋ฝ์ด ํ๋ฆด ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. ํ ์ด๋ธ ์ ์ฒด๊ฐ ์๋๋ผ ๊ณ ์น๋ ๊ทธ ํ๋ง ์ ๊ทธ๋ฏ๋ก, ๊ฐ์ ํ ์ด๋ธ์ด๋ผ๋ ๋ค๋ฅธ ํ์ ๋์์ ์์ ํ ์ ์์ต๋๋ค.
- ๊ต์ฐฉ(Deadlock): ๋ ํธ๋์ญ์ ์ด ์๋ก ์๋๊ฐ ์ฅ ๋ฝ์ ๊ธฐ๋ค๋ฆฌ๋ฉฐ ์์ํ ๋ชป ํ๋ฆฌ๋ ์ํ์ ๋๋ค. A๊ฐ 1๋ฒ ํ์ ์ฅ๊ณ 2๋ฒ ํ์ ๊ธฐ๋ค๋ฆฌ๋๋ฐ, B๊ฐ 2๋ฒ ํ์ ์ฅ๊ณ 1๋ฒ ํ์ ๊ธฐ๋ค๋ฆฌ๋ฉด ๋ ๋ค ๋ฉ์ถฅ๋๋ค. PostgreSQL์ ์ด๋ฅผ ๊ฐ์งํ๋ฉด ํ์ชฝ ํธ๋์ญ์ ์ ๊ฐ์ ๋ก ๋กค๋ฐฑ์์ผ ํ๋๋ค.
Locks Waiting (๊ฐ)
์ง๊ธ ๋ฝ์ ์ป์ผ๋ ค๊ณ ๋๊ธฐ ์ค์ธ ์ ์ฒด backend ์์ ๋๋ค. (์์ 2๋ฒ ์ธ์ ์น์ ์๋ ๋์์ง๋ง, ๋ฝ ๊ด์ ์์ ๋ค์ ๋ด ๋๋ค.) ๋ฝ ๊ฒฝํฉ์ ์ง์ ๋ณด์ฌ ์ฃผ๋ ์งํ์ ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 0.003, ๋ฒ์ 0 ~ 5. 0์ด ์ ์์ด๊ณ , 0์ด ์๋๋ฉด ์ง๊ธ ๋๊ตฐ๊ฐ ๋ค๋ฅธ ํธ๋์ญ์ ๋๋ฌธ์ ๋งํ ์๋ ๊ฒ์ ๋๋ค.
- ์ํ ์ ํธ: ๊ฒฝ๊ณ 1, ์ํ 2. ์์ ๊ฐ์ด๋ผ๋ ๋ฐ๋ณต๋๋ฉด ํน์ ์ฟผ๋ฆฌ·ํธ๋์ญ์ ์ด ์์ฃผ ์ถฉ๋ํ๊ณ ์๋ค๋ ๋ป์ ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ํ ํธ๋์ญ์
์ด ํ์ ์ฅ ์ฑ ์ปค๋ฐ์ ๋ฏธ๋ฃธ(ํนํ
idle in transaction), ๊ฐ์ ํ์ ๋ํ ๋์ ์์ ๊ฒฝํฉ.
๋ฝ ๋๊ธฐ๋ ๊ฑฐ์ "ํธ๋์ญ์ ์ ์ด์ด๋๊ณ ์ปค๋ฐ์ ๋ฏธ๋ฃจ๋" ์ฝ๋์์ ์๊น๋๋ค.
-- ๋์ ์: ํ์ ์์ ํ ๋ค ์ธ๋ถ ์์
(API ํธ์ถ·ํ์ผ ์ฒ๋ฆฌ ๋ฑ)์ ํ๋๋ผ ์ปค๋ฐ์ด ๋ฆ์ด์ง๋ค
-- ๊ทธ๋์ ๊ฐ์ ํ(id=1)์ ๊ฑด๋๋ฆฌ๋ ค๋ ๋ค๋ฅธ ํธ๋์ญ์
์ ์ ๋ถ ๋๊ธฐํ๋ค
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- ... ์ฌ๊ธฐ์ ์ธ๋ถ API ํธ์ถ ๋ฑ์ผ๋ก ์ ์ด~์์ญ ์ด ์ง์ฐ ...
COMMIT; -- ๋๋ฌด ๋ฆ๊ฒ ์ปค๋ฐ → ๊ทธ ์ฌ์ด account_id=1์ ๋
ธ๋ฆฌ๋ ์์
๋ค์ด ๋ฝ ๋๊ธฐ
-- ๊ณ ์น ์: DB ๋ณ๊ฒฝ ๊ตฌ๊ฐ๋ง ๋น ๋ฅด๊ฒ ๋ฌถ์ด ๊ณง๋ฐ๋ก ์ปค๋ฐํ๋ค (์ธ๋ถ ์์
์ ํธ๋์ญ์
๋ฐ์์)
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
COMMIT; -- ์ฆ์ ์ปค๋ฐ → ๋ฝ ์ ์ ์๊ฐ์ด ์งง์ ๋๊ธฐ๊ฐ ๊ฑฐ์ ์๋ค
-- ์ง๊ธ ๋ฝ ๊ฒฝํฉ์ด ์๋์ง — ๋ง์ backend์ ๋งํ backend ์ฐพ๊ธฐ
SELECT blocked.pid AS blocked_pid,
blocked.query AS blocked_query,
blocking.pid AS blocking_pid,
blocking.query AS blocking_query
FROM pg_stat_activity blocked
JOIN LATERAL unnest(pg_blocking_pids(blocked.pid)) AS bp(pid) ON true
JOIN pg_stat_activity blocking ON blocking.pid = bp.pid
WHERE cardinality(pg_blocking_pids(blocked.pid)) > 0;
- ํจ๊ป ํ์ธํ ์งํ: Active Backend๊ฐ ๊ฐ์ด ์์ด๋ฉด → ๋๊ธฐ ์ธ์ ์ด ๋ถํ๋ก ๋ฒ์ง๋ ์ค์ ๋๋ค. Deadlocks๊ฐ ๊ฐ์ด ์ค๋ฅด๋ฉด → ๊ฒฝํฉ์ด ๊ต์ฐฉ์ผ๋ก ๋ฒ์ง ๊ฒ์ ๋๋ค. Trx Time(๊ธด ํธ๋์ญ์ )์ด ํฌ๋ฉด → ๊ทธ ๊ธด ํธ๋์ญ์ ์ด ๋ฝ์ ์ฅ๊ณ ์๋ ์์ธ์ผ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ํธ๋์ญ์ ๋ฒ์ ์์ ์ธ๋ถ API ํธ์ถ์ด๋ ๊ธด ๋ก์ง์ ๋ฃ์ผ๋ฉด ๊ทธ๋์ ํ ๋ฝ์ ์ฅ๊ณ ์์ด ๊ฐ์ ํ์ ๊ฑด๋๋ฆฌ๋ ๋ค๋ฅธ ์์ฒญ์ด ๋๊ธฐํฉ๋๋ค. ํธ๋์ญ์ ์ ์งง๊ฒ ๊ฐ์ ธ๊ฐ๊ณ , ์ธ๋ถ ํธ์ถ์ด๋ ๋ฌด๊ฑฐ์ด ์ฒ๋ฆฌ๋ ํธ๋์ญ์ ๋ฐ์ผ๋ก ๋นผ์ผ ํฉ๋๋ค. ์ฌ๋ฌ ํธ๋์ญ์ ์ด ๊ฐ์ ํ์ ์์ฃผ ๊ฐฑ์ ํ๋ ์ค๊ณ ์์ฒด๋ ๊ฒฝํฉ์ ๋๋ฆฌ๋ ์์ธ์ ๋๋ค.
์ค๋ฌด ์๋๋ฆฌ์ค — ํ ํธ๋์ญ์ ์ด ์ด๋ค ํ์ ์์ ํ ๋ค ์ปค๋ฐํ์ง ์๊ณ ์ธ๋ถ ๊ฒฐ์ API ์๋ต์ ๊ธฐ๋ค๋ฆฐ๋ค๊ณ ํด๋ณด๊ฒ ์ต๋๋ค. ๊ทธ ์๋ต์ด ๋ฆ์ด์ง๋ ๋์ ๊ฐ์ ํ(์: ๊ฐ์ ์ํ ์ฌ๊ณ )์ ์์ ํ๋ ค๋ ์์ฒญ๋ค์ด ์ค์ค์ด ๋๊ธฐํ๋ฉด์ Locks Waiting์ด ์ค๋ฅด๊ณ , ๋๊ธฐํ๋ ๋งํผ Active Backend๊ฐ ์์ฌ CPU์ ์๋ต์๊ฐ๊น์ง ๋๋ฐ ์ ํ๋ฉ๋๋ค. ์ pg_blocking_pids ์ฟผ๋ฆฌ๋ก ๋ง์ backend๋ฅผ ์ฐพ์ ์ ๋ฆฌํ๋ฉด ํ๊บผ๋ฒ์ ํ๋ฆฝ๋๋ค. ๊ทผ๋ณธ ํด๊ฒฐ์ ์ธ๋ถ ํธ์ถ์ ํธ๋์ญ์ ๋ฐ์ผ๋ก ๋นผ๊ณ ์ปค๋ฐ์ ๋ฏธ๋ฃจ์ง ์๋ ๊ฒ์ ๋๋ค.
Deadlocks (๊ฑด)
๊ต์ฐฉ(deadlock)์ด ๋ฐ์ํ ๊ฑด์์ ๋๋ค(1๋ถ ๊ตฌ๊ฐ ํฉ). ๋ ํธ๋์ญ์ ์ด ์๋ก์ ๋ฝ์ ๊ธฐ๋ค๋ ค ๋ชป ํ๋ฆฌ๋ ์ํ๊ฐ ๊ฐ์ง๋์ด ํ์ชฝ์ด ๊ฐ์ ๋กค๋ฐฑ๋ ํ์์ ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ๊ฑฐ์ 0(๋ฒ์ 0 ~ 1). ํ ๋ฌ๊ฐ ๊ฑฐ์ ๋ฐ์ํ์ง ์์์ต๋๋ค. 0์ด ์ ์์ ๋๋ค.
- ์ํ ์ ํธ: 1๊ฑด๋ง ๋ํ๋๋ ๋ค์ฌ๋ค๋ณผ ๊ฐ์น๊ฐ ์์ต๋๋ค. ๋ฐ๋ณต๋๋ฉด ํน์ ํธ๋์ญ์ ์กฐํฉ์ด ์์ฃผ ์ถฉ๋ํ๊ณ ์๋ค๋ ๋ป์ ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ์ฌ๋ฌ ํธ๋์ญ์ ์ด ์ฌ๋ฌ ํ·ํ ์ด๋ธ์ ์๋ก ๋ค๋ฅธ ์์๋ก ์ ๊ทธ๋ ์ฝ๋. ๋ฝ ํ๋ ์์๊ฐ ์๊ฐ๋ฆฌ๋ฉด ๊ต์ฐฉ์ด ์๊น๋๋ค.
๊ต์ฐฉ์ ๋ฝ์ ์ก๋ ์์๋ฅผ ์ฝ๋ ์ ๋ฐ์์ ์ผ์ ํ๊ฒ ๋ง์ถ๋ฉด ํฌ๊ฒ ์ค์ด๋ญ๋๋ค.
-- ๋์ ์: ํ ํธ๋์ญ์
์ A→B ์์๋ก, ๋ค๋ฅธ ํธ๋์ญ์
์ B→A ์์๋ก ์ ๊ทผ๋ค → ๊ต์ฐฉ ์ํ
-- ํธ๋์ญ์
1: UPDATE account A; ... UPDATE account B;
-- ํธ๋์ญ์
2: UPDATE account B; ... UPDATE account A;
-- ๊ณ ์น ์: ํญ์ ๊ฐ์ ์์(์: id ์ค๋ฆ์ฐจ์)๋ก ์ ๊ทธ๋๋ก ํต์ผํ๋ค
-- ๋ ํธ๋์ญ์
๋ชจ๋: ์์ id๋ถํฐ ํฐ id ์์๋ก UPDATE
UPDATE accounts SET balance = balance - 100
WHERE account_id IN (1, 2)
ORDER BY account_id; -- ๋ฝ ํ๋ ์์๋ฅผ ํต์ผ
-- ๊ต์ฐฉ ๋์ ๊ฑด์ ํ์ธ
SELECT datname, deadlocks
FROM pg_stat_database
WHERE datname = current_database();
- ํจ๊ป ํ์ธํ ์งํ: Xact Rollback์ด ๊ฐ์ด ์ค๋ฅด๋ฉด → ๊ต์ฐฉ์ผ๋ก ํธ๋์ญ์ ์ด ๊ฐ์ ๋กค๋ฐฑ๋๋ ๊ฒ์ ๋๋ค. Locks Waiting์ด ํจ๊ป ์ค๋ฅด๋ฉด → ๋ฝ ๊ฒฝํฉ์ด ์ฌํด์ง ๋์ ๊ต์ฐฉ๊น์ง ๋ฒ์ง ์ํฉ์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ๊ต์ฐฉ์ ๊ฑฐ์ ํญ์ "๋ฝ ํ๋ ์์๊ฐ ์ฝ๋๋ง๋ค ๋ค๋ฅธ" ๋ฐ์ ์๊น๋๋ค. ์ฌ๋ฌ ํ·์ฌ๋ฌ ํ ์ด๋ธ์ ํ ํธ๋์ญ์ ์์ ๊ฑด๋๋ฆฐ๋ค๋ฉด, ํญ์ ๊ฐ์ ์์(์: ๊ธฐ๋ณธํค ์ค๋ฆ์ฐจ์)๋ก ์ ๊ทผํ๋๋ก ์ฝ๋ ์ ๋ฐ์์ ๊ท์น์ ํต์ผํ๋ฉด ๊ต์ฐฉ ๊ฐ๋ฅ์ฑ์ด ํฌ๊ฒ ์ค๋๋ค. PostgreSQL์ ๊ต์ฐฉ์ ๊ฐ์งํ๋ฉด ํ์ชฝ์ ๋กค๋ฐฑ์์ผ ํ์ด ์ฃผ๋ฏ๋ก, ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ต์ฐฉ ์์ธ๋ฅผ ์ก์ ์ฌ์๋ํ๋ ์ฒ๋ฆฌ๋ฅผ ํจ๊ป ๋๋ ๊ฒ์ด ์ข์ต๋๋ค.
7. ๋คํธ์ํฌ · ์คํ ๋ฆฌ์ง · Temp
DB๊ฐ ๊ฒฐ๊ณผ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๋คํธ์ํฌ ํธ๋ํฝ, ๋ฐ์ดํฐ๋ฅผ ๋ด๋ ํ์ผ ์์คํ ์ฌ์ฉ๋, ๊ทธ๋ฆฌ๊ณ ๋ฉ๋ชจ๋ฆฌ์์ ๋ชป ๋๋ธ ์ ๋ ฌ·ํด์๊ฐ ๋์คํฌ๋ก ํ๋ฌ๊ฐ ์์ ํ์ผ์ ๋ด ๋๋ค. ๋ฒํผ ์บ์๊ฐ ์ฑ ์์ด๋ผ๋ฉด, ์ฌ๊ธฐ๋ ์๋์๊ฒ ๋ค๊ณ ๋๊ฐ ์ง(๋คํธ์ํฌ)์ ์๊ณผ ์ฐฝ๊ณ ์ฌ์ฉ๋(ํ์ผ ์์คํ ), ๊ทธ๋ฆฌ๊ณ ์ฑ ์์ด ๋ชจ์๋ผ ๋ฐ๋ฅ์ ์์๋ก ํผ์น ์์ ๋ฌผ(temp)์ ๋๋ค.
Network Transmit Throughput (Bytes/์ด) / Network Receive Throughput (Bytes/์ด)
DB ์ธ์คํด์ค๊ฐ ์ฃผ๊ณ ๋ฐ๋ ๋คํธ์ํฌ ํธ๋ํฝ์ ๋๋ค. Transmit(์ก์ )์ DB๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ด๋ณด๋ด๋ ์, Receive(์์ )๋ DB๋ก ๋ค์ด์ค๋ ์ฟผ๋ฆฌ·๋ฐ์ดํฐ์ ์์ ๋๋ค.
- ๊ด์ธก๊ฐ: ์ก์ ํ๊ท ์ฝ 967KB/s(๋ฒ์ 227KB ~ ์ฝ 2.4MB/s), ์์ ํ๊ท ์ฝ 795KB/s(๋ฒ์ 235KB ~ ์ฝ 2.2MB/s). ํํํ๊ฒ ์ ์ง๋ฉ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ๋๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ์ฟผ๋ฆฌ(
SELECT *๋ก ํฐ ํ ์ด๋ธ ์ ์ฒด ๋ฐํ ๋ฑ), ๋๋ ์ ์ฌ, ๋ณต์ ํธ๋ํฝ.
-- ๋์ ์: ํ์ด์ง ์์ด ํฐ ํ
์ด๋ธ ์ ์ฒด๋ฅผ ๋ชจ๋ ์ปฌ๋ผ์ผ๋ก ๋ฐํ → ์ก์ ํธ๋ํฝ ํญ์ฆ
SELECT * FROM products;
-- ๊ณ ์น ์: ํ์ํ ์ปฌ๋ผ๋ง, ํ์ด์ง์ผ๋ก ์๋ผ์ ๋ฐํ
SELECT product_id, name, price
FROM products
ORDER BY product_id
LIMIT 100 OFFSET 0;
- ํจ๊ป ํ์ธํ ์งํ: ์ก์ ํธ๋ํฝ ๊ธ์ฆ๊ณผ Tup Returned·Tup Fetched๊ฐ ๋๋ฐ์ด๋ฉด → ํฐ ๊ฒฐ๊ณผ์ ์ ํผ๋ด๋ ์ฟผ๋ฆฌ์ ๋๋ค. ์์ ํธ๋ํฝ๊ณผ Tup Inserted·Write IOPS๊ฐ ๋๋ฐ์ด๋ฉด → ๋๋ ์ ์ฌ๊ฐ ๋ค์ด์ค๋ ์ค์ ๋๋ค. ๋ ๋ค ํํํ๋ฐ ํ์ชฝ๋ง ํ๋ฉด ๋ณต์ ํธ๋ํฝ ๋ฑ ํน์ ๊ฒฝ๋ก๋ฅผ ์์ฌํฉ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ํ์ด์ง ์์ด ํฐ ๊ฒฐ๊ณผ๋ฅผ ํต์งธ๋ก ๋ฐํํ๊ฑฐ๋
SELECT *๋ก ๋ถํ์ํ ์ปฌ๋ผ๊น์ง ํผ๋ด๋ฉด ์ก์ ํธ๋ํฝ์ด ์ปค์ง๋๋ค. ํ์ํ ์ปฌ๋ผ๋ง, ํ์ด์ง ๋จ์๋ก ์๋ผ ๋ฐํํ๋ฉด ์ก์ ๋์ด ์ค๊ณ ์๋ต๋ ๋นจ๋ผ์ง๋๋ค. ๋๋ ์ ์ฌ ์ชฝ์ ํ ๊ฑด์ฉ ๋ฃ๋ ๋์COPY๋ ๋ฌถ์ INSERT๋ก ๋ณด๋ด๋ฉด ์์ ํธ๋ํฝ๊ณผ ์๋ณต ํ์๋ฅผ ํจ๊ป ์ค์ผ ์ ์์ต๋๋ค.
Filesystem Usage (Bytes)
ํ์ผ ์์คํ ์ฌ์ฉ๋์ ๋๋ค. ์ธ์คํด์ค์ ๋์คํฌ๊ฐ ์ค์ ๋ก ์ผ๋ง๋ ์ฐจ ์๋์ง๋ฅผ ๋ฐ์ดํธ๋ก ๋ด ๋๋ค.
- ๊ด์ธก๊ฐ: ํ๊ท ์ฝ 226GB, ๋ฒ์ ์ฝ 209 ~ 245GB. ์๋งํ๊ฒ ์์ง์ ๋๋ค.
- ์ํ ์ ํธ: ์ ๋ ์๊ณ๋ ๋นํ์ฑ์ด์ง๋ง, ๋์คํฌ๊ฐ ๊ฐ๋ ์ฐจ๋ฉด(ํนํ ๋ฐ์ดํฐ·WAL ์์ญ) ์ฐ๊ธฐ ์์ฒด๊ฐ ๋ฉ์ถฐ ์ฅ์ ๋ก ์ง๊ฒฐ๋ฉ๋๋ค. ๊ทธ๋์ ๊พธ์คํ ์ฐ์ํฅํ๋ ์ถ์ธ๋ฅผ ๋ด ๋๋ค.
- ํ๋ฉด(๋๋ฉด) ์์ฌํ ๊ฒ: ๋๋ ์ ์ฌ๋ก ๋ฐ์ดํฐ ์ฆ๊ฐ, ์ ๋ฆฌ๋์ง ์๊ณ ์์ด๋ WAL, ํ ์ด๋ธ ํฝ์ฐฝ(์ฃฝ์ ํ์ด VACUUM์ผ๋ก ํ์๋์ง ์์ ๊ณต๊ฐ์ ๊ณ์ ์ฐจ์ง), temp ์์ญ์ ํฌ๊ฒ ์ฐ๋ ์ ๋ ฌ.
PostgreSQL์์ ํ์ผ ์์คํ ์ด ์์๋ณด๋ค ๋นจ๋ฆฌ ์ฐจ๋ ํํ ์์ธ ํ๋๊ฐ ํ ์ด๋ธ ํฝ์ฐฝ์ ๋๋ค. ์ฃฝ์ ํ์ด ํ์๋์ง ์์ผ๋ฉด ์ค์ ๋ฐ์ดํฐ๋ณด๋ค ํจ์ฌ ํฐ ๊ณต๊ฐ์ ์ฐจ์งํฉ๋๋ค.
-- ํ
์ด๋ธ๋ณ ๋์คํฌ ์ ์ ํฌ๊ธฐ์ ์ฃฝ์ ํ ์๋ฅผ ํจ๊ป ๋ณธ๋ค (ํฝ์ฐฝ ์ ๊ฒ)
SELECT relname,
pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
n_live_tup, n_dead_tup, last_autovacuum
FROM pg_stat_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 20;
- ํจ๊ป ํ์ธํ ์งํ: Tup Updated·Tup Deleted๊ฐ ๋ง์๋ฐ last_autovacuum์ด ์ค๋๋์ผ๋ฉด → ์ฃฝ์ ํ ๋์ ์ผ๋ก ํฝ์ฐฝ์ด ๊ณต๊ฐ์ ๋จน๋ ์ค์ ๋๋ค. Temp Bytes๊ฐ ํฌ๋ฉด → ์ ๋ ฌ ์์ ํ์ผ์ด ๊ณต๊ฐ์ ์ฐ๋ ์ค์ ๋๋ค. WAL์ด ์์ด๋ฉด ๋ณ๋ ๊ฒฝ๋ก๋ก ํจ๊ป ๋ด ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ์คํ ๋ฆฌ์ง๋ ํ ๋ฒ ์ฐจ๋ฉด ์ฐ๊ธฐ๊ฐ ๋ฉ์ถฐ ๊ฐ์ฅ ์น๋ช ์ ์ ๋๋ค. PostgreSQL์์๋ ์ผ๋ฐ์ ์ธ ๋ฐ์ดํฐ ์ฆ๊ฐ ์ธ์ ํ ์ด๋ธ ํฝ์ฐฝ์ด ๊ณต๊ฐ์ ๊ฐ์๋จน์ผ๋ฏ๋ก, ๋ณ๊ฒฝ์ด ๋ง์ ํ ์ด๋ธ์ VACUUM์ด ์ ๋๋์ง ํจ๊ป ๋ด์ผ ํฉ๋๋ค. ์ค๋๋ ๋ฐ์ดํฐ๋ ์ฃผ๊ธฐ์ ์ผ๋ก ์ ๋ฆฌ·์์นด์ด๋ธํ๊ณ , ๋๋ ์ ์ฌ·์ญ์ ๋ ํ ๋ฒ์ ๋ชฐ์ง ๋ง๊ณ ๋๋ ์ ์ฒ๋ฆฌํฉ๋๋ค.
์ค๋ฌด ์๋๋ฆฌ์ค — ํ์ผ ์์คํ ์ฌ์ฉ๋์ด ํ์์ ์๋งํ๋ค๊ฐ ์ด๋ ๋ ๋ถํฐ ๋งค์ผ ์ผ์ ๋์ฉ ๋น ๋ฅด๊ฒ ๋๋ ์ฐํํฅ(์ฌ์ ๊ธฐ์ค) ์ถ์ธ๊ฐ ๊ทธ๋ ค์ง๋ค๋ฉด, ์ ๋ฆฌ๋์ง ์๋ WAL์ด๋ ๋ฉ์ถ์ง ์๋ ์ ์ฌ ๋ฐฐ์น, ํน์ autovacuum์ด ๋ชป ๋ฐ๋ผ๊ฐ๋ ํ ์ด๋ธ ํฝ์ฐฝ์ ์์ฌํฉ๋๋ค. ์ถ์ธ๋๋ก๋ฉด ๋ฉฐ์น ๋ค ๊ณต๊ฐ์ด ๋ฐ๋ฅ๋ ์ฐ๊ธฐ๊ฐ ๋ฉ์ถ๋ฏ๋ก, ์ ๋๊ฐ์ด ์ํ์ ์ ๋ฟ๊ธฐ ์ ์ ์ถ์ธ๋ฅผ ๋ณด๊ณ ๋ฏธ๋ฆฌ ์์ฐ๋ ๊ฒ์ด ํต์ฌ์ ๋๋ค.
Temp Bytes (Bytes) / Temp Files (๊ฑด)
- Temp Bytes: ์์ ํ์ผ(temporary file)์ ์ฐ์ธ ๋ฐ์ดํฐ ์์ ๋๋ค(1๋ถ ๊ตฌ๊ฐ ํฉ).
- Temp Files: ์ฟผ๋ฆฌ๋ก ์์ฑ๋ ์ ์ฒด ์์ ํ์ผ ์์ ๋๋ค(1๋ถ ๊ตฌ๊ฐ ํฉ).
์์ ํ์ผ์ ์ ๋ ฌ·ํด์·๊ทธ๋ฃนํ ์์ ์ด backend์ ์์ ๋ฉ๋ชจ๋ฆฌ(work_mem) ์์์ ๋ชป ๋๋๊ณ ๋์คํฌ๋ก ๋์ณ ๋ฌ์ ๋ ๋ง๋ค์ด์ง๋๋ค. ์ฆ ์ด ์งํ๊ฐ 0์ด ์๋๋ฉด "๋ฉ๋ชจ๋ฆฌ์์ ๋๋์ง ๋ชปํ ๋ฌด๊ฑฐ์ด ์ ๋ ฌ·ํด์๊ฐ ์์๋ค" ๋ ์ ํธ์ ๋๋ค.
- ๊ด์ธก๊ฐ: Temp Bytes ํ๊ท ์ฝ 131KB(๋ฒ์ 0 ~ ์ฝ 1.07GB), Temp Files ํ๊ท ๊ฑฐ์ 0(๋ฒ์ 0 ~ 1). ํ์์ ๊ฑฐ์ 0์ด๋ค๊ฐ ์ด๋ค ์๊ฐ 1GB๊ฐ ๋๋ ์์ ํ์ผ์ด ์๊ธด ์ ์ด ์์ต๋๋ค. ์ด ์๊ฐ์ด ํฐ ์ ๋ ฌ·ํด์๊ฐ ๋์คํฌ๋ก ๋์น ์์ ์ ๋๋ค.
- ํ๋ฉด ์์ฌํ ๊ฒ: ์ธ๋ฑ์ค ์๋ ๋๋
ORDER BY, ํฐ ํด์ ์กฐ์ธ, ๋๋GROUP BY·DISTINCT, work_mem ๋ถ์กฑ.
ํฐ ์ ๋ ฌ์ด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋์ผ๋ฉด ๋์คํฌ ์์ ํ์ผ์ด ์๊น๋๋ค. ์ธ๋ฑ์ค๋ก ์ ๋ ฌ์ ๋์ ํ๊ฒ ํ๊ฑฐ๋ ๊ฒฐ๊ณผ๋ฅผ ์ขํ๋ฉด ์ค์ด๋ญ๋๋ค.
-- ๋์ ์: ์ธ๋ฑ์ค ์๋ ์ปฌ๋ผ์ผ๋ก ๋๋ ์ ๋ ฌ → work_mem์ ๋๊ฒจ ๋์คํฌ temp ๋ฐ์
SELECT * FROM logs ORDER BY message;
-- ๊ณ ์น ์: ์ ๋ ฌ ๊ธฐ์ค ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ๋๊ณ , ํ์ํ ๋ฒ์·์ปฌ๋ผ๋ง ์ขํ ์ฝ๋๋ค
-- (์ธ๋ฑ์ค๊ฐ ์ ๋ ฌ ์์๋ฅผ ์ ๊ณตํ๋ฉด ๋์คํฌ ์ ๋ ฌ์ด ์ฌ๋ผ์ง๋ค)
SELECT id, level, created_at
FROM logs
WHERE created_at >= TIMESTAMP '2026-06-18 00:00:00'
ORDER BY created_at -- created_at ์ธ๋ฑ์ค๊ฐ ์ ๋ ฌ์ ๋์
LIMIT 100;
-- ์ด๋ค ์ฟผ๋ฆฌ๊ฐ ๋์คํฌ ์ ๋ ฌ์ ํ๋์ง — ์คํ๊ณํ์์ ํ์ธ
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM logs ORDER BY message;
-- ๊ฒฐ๊ณผ์ 'Sort Method: external merge Disk: ...kB' ๊ฐ ๋ณด์ด๋ฉด ๋์คํฌ ์ ๋ ฌ(temp ๋ฐ์)
- ํจ๊ป ํ์ธํ ์งํ: Temp Bytes·Temp Files๊ฐ ์ค๋ฅด๋ฉฐ Blks Read·Read IOPS·Write IOPS๊ฐ ๋๋ฐ์ด๋ฉด → ํฐ ์ ๋ ฌ·ํด์๊ฐ ๋์คํฌ๋ฅผ ์ค๊ฐ๋ ์ค์ ๋๋ค. CPU๋ ๊ฐ์ด ์ค๋ฅด๋ฉด ๋ฌด๊ฑฐ์ด ์ ๋ ฌ ์ฐ์ฐ์ด ๋ถํ๋ก ์กํ ๊ฒ์ ๋๋ค. Filesystem Usage๊ฐ ์ผ์์ ์ผ๋ก ์ค๋ฅด๋ฉด → ํฐ ์์ ํ์ผ์ด ๊ณต๊ฐ์ ์ฐจ์งํ ๊ฒ์ ๋๋ค.
๊ฐ๋ฐ์ ๊ด์ — ์์ ํ์ผ์ ์ ๋ ฌ·ํด์·๊ทธ๋ฃนํ์ด work_mem์ ๋์ณ ๋์คํฌ๋ก ํ๋ ๋ค๋ ์ ํธ์ ๋๋ค. ์ธ๋ฑ์ค๋ก ์ ๋ ฌ์ ๋์ ํ๊ฒ ํ๊ณ (
ORDER BY์ปฌ๋ผ์ ์ธ๋ฑ์ค), ๊ฒฐ๊ณผ ํฌ๊ธฐ๋ฅผ ํ์ด์ง ๋จ์๋ก ์ค์ด๋ฉฐ, ํ์ํ ์ปฌ๋ผ๋ง ์ฝ์ผ๋ฉด ๋์คํฌ ์์ ํ์ผ์ด ์ค์ด๋ญ๋๋ค. ๊ฐ์ ๋ฌด๊ฑฐ์ด ์ง๊ณ๊ฐ ๋ฐ๋ณต๋๋ค๋ฉด ๋ฏธ๋ฆฌ ๊ณ์ฐํ ์ง๊ณ ํ ์ด๋ธ์ด๋ ๊ตฌ์ฒดํ ๋ทฐ(materialized view)๋ฅผ ๋๋ ๊ฒ๋ ๋ฐฉ๋ฒ์ ๋๋ค.์ค๋ฌด ์๋๋ฆฌ์ค — ํ์ Temp Files๊ฐ 0์ด๋ ์ธ์คํด์ค์์ ํน์ ์๊ฐ๋์๋ง 1GB๊ฐ ๋๋ Temp Bytes๊ฐ ์ฐํ๋ค๊ณ ํด๋ณด๊ฒ ์ต๋๋ค. ๊ทธ ์๊ฐ์ ๋๋ ๋ฆฌํฌํธ ์ฟผ๋ฆฌ๊ฐ ์ธ๋ฑ์ค ์์ด ํฐ ํ ์ด๋ธ์ ์ ๋ ฌ·์ง๊ณํ๋ฉด์ work_mem์ ๋๊ฒจ ๋์คํฌ ์ ๋ ฌ์ ํ ๊ฒ์ ๋๋ค. EXPLAIN์ผ๋ก ๋ณด๋ฉด
Sort Method: external merge Disk๊ฐ ๋์ต๋๋ค. ์ ๋ ฌ ๊ธฐ์ค ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ฟผ๋ฆฌ๋ฅผ ๋ค์ ์ง์ ๋์คํฌ ์ ๋ ฌ์ ์์ ๋ฉด Temp Bytes๊ฐ 0์ผ๋ก ๋์์ค๊ณ ๊ทธ ์ฟผ๋ฆฌ๋ ๋นจ๋ผ์ง๋๋ค.
8. ๊ธฐํ
(์ฐธ๊ณ ) Postgresql Slow Query Monitor (ms)
PostgreSQL Slow Query๋ฅผ ๋ชจ๋ํฐ๋งํ๋ ์งํ์ธ๋ฐ, ํ๊ฒฝ์ ๋ฐ๋ผ 1๋ถ ๋จ์ ๋ฉํธ๋ฆญ์ผ๋ก ๋ค์ด์ค์ง ์๋ ๊ฒฝ์ฐ๊ฐ ์์ด(์ด ์ธ์คํด์ค์์๋ ๋ฏธ์ ๊ณต) ๋ค์ด์ฌ ๋๋ง ์ฐธ๊ณ ํฉ๋๋ค. ๋๋ฆฐ ์ฟผ๋ฆฌ ์์ฒด๋ ์์์ ๋ณธ Long Active Backend·Active Backend·Blks Read ๊ฐ์ ์งํ์ pg_stat_activity๋ก ์ถฉ๋ถํ ์ถ์ ํ ์ ์๊ณ , ์ด์ ํ๊ฒฝ์์๋ pg_stat_statements ํ์ฅ์ ์ผ ๋๋ฉด ์ด๋ค ์ฟผ๋ฆฌ๊ฐ ๋์ ์ผ๋ก ๊ฐ์ฅ ๋ฌด๊ฑฐ์ด์ง ์ ํํ ๋ณผ ์ ์์ต๋๋ค.
-- (์ด์ ํ๊ฒฝ์์ pg_stat_statements๊ฐ ์ผ์ ธ ์๋ค๋ฉด) ๋์ ์ํ์๊ฐ์ด ํฐ ์ฟผ๋ฆฌ ์ฐพ๊ธฐ
SELECT query,
calls,
ROUND(total_exec_time::numeric, 1) AS total_ms,
ROUND(mean_exec_time::numeric, 2) AS mean_ms
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;
๊ฐ๋ฐ์ ๊ด์ — ๋ณ๋์ slow query ์งํ๊ฐ ์์ด๋, "๋๋ฆฐ ์ฟผ๋ฆฌ" ๋ ๊ฒฐ๊ตญ ์ธ๋ฑ์ค๋ฅผ ๋ชป ํ๊ฑฐ๋ ๊ฒฐ๊ณผ๋ฅผ ๋๋ฌด ๋ง์ด ๋ค๋ฃจ๋ ์ฟผ๋ฆฌ์ ๋๋ค. pg_stat_statements๋ก ํ๊ท ์ํ์๊ฐ์ด ๊ธด ์ฟผ๋ฆฌ๋ฅผ ์ฐพ์
EXPLAIN (ANALYZE, BUFFERS)๋ก ์คํ๊ณํ์ ๋ณด๊ณ ์ธ๋ฑ์ค·๊ฒฐ๊ณผ ํฌ๊ธฐ๋ฅผ ์๋ณด๋ ํ๋ฆ์ ์์ ๋ค๋ฅธ ์งํ๋ค๊ณผ ๊ฐ์ต๋๋ค.
์ํฉ๋ณ๋ก ๋ณด๊ธฐ — ๋ฐฐ์น·๋ฐฑ์ ์ด ๋ ๋ ์ด๋ค ์งํ๊ฐ ์์ง์ด๋
์ง๊ธ๊น์ง๋ ์งํ๋ฅผ ํ๋์ฉ ๋ดค์ง๋ง, ์ค์ ๋ก๋ ํ๋์ ์์ ์ด ์ฌ๋ฌ ์งํ๋ฅผ ๋์์ ์์ง์ ๋๋ค. ํนํ ์ ๊ธฐ ๋ฐฐ์น๋ ๋ฐฑ์ ์ฒ๋ผ ์ ํด์ง ์๊ฐ์ ๋๋ ์์ ์ ๋งค๋ฒ ๋น์ทํ ์งํ ๋ฌถ์์ ๋์ด์ฌ๋ฆฝ๋๋ค. PostgreSQL์ ๋ณ๊ฒฝ ์์ ์ด ์ฃฝ์ ํ๊ณผ VACUUM์ผ๋ก ์ด์ด์ง๋ ํน์ฑ์ด ์์ด์, ๋ฐฐ์น์ ์ข ๋ฅ๋ฅผ ์งํ ํจํด์ผ๋ก ๊ตฌ๋ถํ๊ธฐ ์ข์ต๋๋ค.
๋ฐฐ์น ์ ํ๋ณ ์์ ์งํ ๋ณํ
| ๋ฐฐ์น ์ ํ | ํจ๊ป ์ค๋ฅด๋ ์งํ | ์ด์ |
|---|---|---|
| ๋๋ UPDATE/DELETE ๋ฐฐ์น | Tup Updated·Tup Deleted, (์งํ) n_dead_tup·autovacuum์ผ๋ก CPU·Write IOPS, Locks Waiting, Filesystem Usage | ๋ณ๊ฒฝํ ๋๋ง๋ค ์ฃฝ์ ํ์ด ์์ด๊ณ , ์ดํ autovacuum์ด ์ฒญ์ํ๋ฉฐ, ์ ๋ฆฌ๊ฐ ๋ฆ์ผ๋ฉด ํ ์ด๋ธ์ด ํฝ์ฐฝํจ |
| ๋๋ ์ ์ฌ (INSERT) | Tup Inserted, Xact Commit·TPS, Write IOPS, Network ์์ , Filesystem Usage | ํ์ ๋๋์ผ๋ก ์ฐ๋ฉด ์ปค๋ฐ·WAL flush·๋์คํฌ ์ฐ๊ธฐ๊ฐ ๋๊ณ ๋ฐ์ดํฐ๊ฐ ์ฆ๊ฐํจ |
| ์ง๊ณ·๋ฆฌํฌํธ (๋๋ SELECT) | Tup Returned, Blks Read, Read IOPS, Temp Bytes·Temp Files, CPU / Cache Hit Ratio๋ ํ๋ฝ | ํฐ ํ ์ด๋ธ์ ํ์ด ์ง๊ณ·์ ๋ ฌํ๋ฏ๋ก ์ฝ์ ๋ธ๋ก·๋์คํฌ ์ฝ๊ธฐ·์์ ํ์ผ์ด ๊ธ์ฆํ๊ณ ์บ์๊ฐ ๋ฐ๋ฆผ |
| ๋ฐฑ์ | Read IOPS, Network, CPU(์ฝ๊ฐ) | ๋ฐ์ดํฐ ์ ์ฒด๋ฅผ ์ฝ์ด ๋ด๋ณด๋ด๋ฏ๋ก ๋์คํฌ ์ฝ๊ธฐ·๋คํธ์ํฌ๊ฐ ์ค๋ฆ |
| ๊ธด ํธ๋์ญ์ ๋ฐฉ์น (idle in transaction) | Trx Time, Age Used Ratio·Current Age, Locks Waiting | ํธ๋์ญ์ ์ด ์ค๋ ์ด์ VACUUM·freeze๋ฅผ ๋ง์ ๋์ด๊ฐ ์ค๋ฅด๊ณ , ๋ฝ๋ ์ค๋ ์ฅ |
์๋ฅผ ๋ค๋ฉด
๋งค์ผ ์๋ฒฝ ํต๊ณ ๋ฐฐ์น๊ฐ ํฐ ํ ์ด๋ธ์ ํ ์ค์บํด ์ง๊ณ·์ ๋ ฌํ๋ค๊ณ ํด๋ณด๊ฒ ์ต๋๋ค. ๊ทธ ์๊ฐ์๋ Tup Returned๊ฐ ์์ฒ๋ง~์์ต์ผ๋ก ๋ฐ๊ณ , Blks Read์ Read IOPS๊ฐ ๋ฐ๋ผ ์ค๋ฅด๋ฉฐ, ์ ๋ ฌ์ด work_mem์ ๋๊ฒจ Temp Bytes·Temp Files๊ฐ ์๊ธฐ๊ณ , ๊ทธ ๋ฐ์ดํฐ๊ฐ ์บ์๋ฅผ ๋ฐ์ด๋ด Cache Hit Ratio๊ฐ ์ ๊น ๋จ์ด์ง๋๋ค. CPU๋ ์ง๊ณ·์ ๋ ฌ ์ฐ์ฐ์ผ๋ก ๊ฐ์ด ์ค๋ฆ ๋๋ค. ์ด ๋ฌถ์์ด ๊ฐ์ ์๊ฐ์ ํจ๊ป ์์ง์ด๋ ๊ฒ์ด ์ด ๋ฐฐ์น์ ์ง๋ฌธ ๊ฐ์ ํจํด์ ๋๋ค.
์๋ง ๋๋ UPDATE/DELETE ๋ฐฐ์น๋ผ๋ฉด ๋ฐ๋๋ก Tup Updated·Tup Deleted๊ฐ ๊ฐ์ด ์ค๋ฆ ๋๋ค. ๊ทธ ์งํ ์ฃฝ์ ํ(n_dead_tup)์ด ์์ด๊ณ autovacuum์ด ๋๊ธฐ ์์ํ๋ฉด์ CPU์ Write IOPS๊ฐ ํ ๋ฒ ๋ ์ค๋ฆ ๋๋ค. ๋ง์ฝ ์ด๋ ๋ณ๊ฒฝ์ ํ๋์ ํฐ ํธ๋์ญ์ ์ผ๋ก ๋ฌถ์ด ์ค๋ ๋๋ฉด, ๊ทธ ํธ๋์ญ์ ์ด VACUUM์ ๋ง์ ์ฃฝ์ ํ์ด ์ ๋ฆฌ๋์ง ์๊ณ ํ ์ด๋ธ์ด ํฝ์ฐฝํ๋ฉฐ Age Used Ratio๊น์ง ์ค๋ฅผ ์ ์์ต๋๋ค. ๊ทธ๋์ ๋๋ ์์ ์ ๋๋ฌด ํฌ์ง๋ ๋๋ฌด ์์ง๋ ์์ ๋ฌถ์(์์ฒ~์๋ง ๊ฑด)์ผ๋ก ๋๋ ์ปค๋ฐํ๋ ๊ฒ์ด ๊ท ํ์ ์ ๋๋ค.
ํต์ฌ — "์ธ์ " ์ฌ๋๋์ง๊ฐ ์ค์ํ๋ค
์ฌ๊ธฐ์ ์ค์ํ ์ ์, ์ด ์งํ๋ค์ด ๋ฐฐ์น ์๊ฐ๋์ ํจ๊ป ์ค๋ฅด๋ ๊ฒ์ ์ ์์ด๋ผ๋ ๊ฒ์ ๋๋ค. ์ ํด์ง ์์ ์ด ์ ํด์ง ์๊ฐ์ ์์์ ์ฐ๋ ๊ฒ์ด๋๊น์. ๋ํ์ฌ PostgreSQL์์๋ ๋๋ ๋ณ๊ฒฝ ๋ฐฐ์น ์งํ์ autovacuum์ด ๋ฐ๋ผ ๋๋ ๊ฒ ๋ํ ์ ์์ ์ธ ๋ฆฌ๋ฌ์ ๋๋ค(์ฃฝ์ ํ์ ์น์ ์ฃผ๋ ๊ณ ๋ง์ด ๋์์ ๋๋ค). ๋ฌธ์ ๊ฐ ๋๋ ๊ฒฝ์ฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋ฐฐ์น๊ฐ ์๋ ์๊ฐ๋์ ๊ฐ์ ํจํด์ด ๋ํ๋ ๋ — ๋๊ตฐ๊ฐ ์๋์ผ๋ก ๋ฌด๊ฑฐ์ด ์ฟผ๋ฆฌ๋ฅผ ๋๋ ธ๊ฑฐ๋, ์๋์น ์์ ์์ ์ด ๋๋ค๋ ์ ํธ์ ๋๋ค.
- ๋ฐฐ์น ์๊ฐ๋์ธ๋ฐ ํ์๋ณด๋ค ํจ์ฌ ํฌ๊ฒ, ์ค๋ ํ ๋ — ๋ฐ์ดํฐ๊ฐ ๊ทธ๋งํผ ๋์๊ฑฐ๋, ์ฟผ๋ฆฌ๊ฐ ๋นํจ์จ์ ์ผ๋ก ๋ฐ๋์์ ์ ์์ต๋๋ค.
- ๋ณ๊ฒฝ ๋ฐฐ์น ๋ค์ ์ฃฝ์ ํ์ด ์ค์ง ์๊ณ Age๊ฐ ๊ณ์ ์ค๋ฅผ ๋ — autovacuum์ด ๋ชป ๋ฐ๋ผ๊ฐ๊ฑฐ๋ ๊ธด ํธ๋์ญ์ ์ด ์ ๋ฆฌ๋ฅผ ๋ง๋ ๊ฒ์ ๋๋ค(PostgreSQL ๊ณ ์ ์ ์ ๊ฒ ํฌ์ธํธ).
๊ทธ๋์ ๋ชจ๋ํฐ๋ง์์๋ ์ ๋๊ฐ๋งํผ "ํ์ ์ด ์๊ฐ๋์ ๋น๊ตํด์ ์ด๋ค๊ฐ" ๊ฐ ์ค์ํฉ๋๋ค. ๋งค์ผ ๊ฐ์ ์๊ฐ์ ๊ฐ์ ๋ชจ์์ผ๋ก ์ค๋ฅด๋ด๋ฆฌ๋ ๊ทธ๋ํ๋ผ๋ฉด ๊ทธ๊ฑด ๋ฐฐ์น์ ์ ์ ๋ฆฌ๋ฌ์ด๊ณ , ๊ทธ ๋ฆฌ๋ฌ์์ ๋ฒ์ด๋๋ ์๊ฐ์ด ๋ค์ฌ๋ค๋ณผ ์ง์ ์ ๋๋ค.
์ ๋ฆฌํ๋ฉฐ
PostgreSQL ์งํ๋ MySQL·Oracle๊ณผ ๊ณตํต๋ ๋ถ๋ถ(CPU·๋ฉ๋ชจ๋ฆฌ·์ธ์ ·์ฝ๊ธฐ·๋ฝ)์ด ๋ง์ผ๋ฉด์๋, MVCC·Dead Tuple·VACUUM·ํธ๋์ญ์ ID(Age) ๋ผ๋ ๊ทธ DB๋ง์ ์ค๊ธฐ๊ฐ ๋ถ๋ช ํ์ต๋๋ค. ํต์ฌ ๊ฐ๋ ์ ๋จผ์ ์ก์ ๋๋, ์งํ๋ค์ด ๊ทธ ๊ฐ๋ ๋ค์ ๋์์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ์ด์ด์ก์ต๋๋ค.
PostgreSQL์์ ๊ธฐ์ตํด ๋ ํต์ฌ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- "์ฐ๊ฒฐ(Numbackends)" ๊ณผ "ํ์ฑ(Active Backend)" ์ ๋ค๋ฅด๋ค. ์ ์ธ์คํด์ค๋ ์ฐ๊ฒฐ์ ์ฝ 837์ธ๋ฐ ํ์ฑ์ 1 ์ํ์ด์๋ค. ๋ถํ๋ ํ์ฑ์ผ๋ก ๋ณธ๋ค. PostgreSQL์ ์ฐ๊ฒฐ๋ง๋ค ํ๋ก์ธ์ค๋ฅผ ๋์ฐ๋ฏ๋ก ์ปค๋ฅ์ ํ·PgBouncer๊ฐ ํนํ ์ค์ํ๋ค.
- UPDATE/DELETE๋ ์ฃฝ์ ํ์ ๋จ๊ธด๋ค. Tup Updated·Tup Deleted๊ฐ ํฌ๋ฉด ์ฃฝ์ ํ์ด ์์ด๊ณ , VACUUM(autovacuum)์ด ์ฒญ์ํ๋ค. ๋๋ ๋ณ๊ฒฝ์ ๋๋ ์ ์ปค๋ฐํด ์ฃฝ์ ํ์ด ํ๊บผ๋ฒ์ ์์์ง์ง ์๊ฒ ํ๋ค.
- Age(ํธ๋์ญ์
ID ๋์ด)๋ PostgreSQL ๊ณ ์ ์ ์ํ ์งํ๋ค. Age Used Ratio๊ฐ ๊ถ์ฅ์ (85%) ์๋ก ๊พธ์คํ ๋๊ฑฐ๋ Current Age๊ฐ wraparound ํ๊ณ๋ก ํฅํ๋ฉด freeze๊ฐ ๋ชป ๋ฐ๋ผ๊ฐ๋ ๊ฒ์ด๋ค. ๊ธด
idle in transactionํธ๋์ญ์ ์ด ๊ฐ์ฅ ํํ ์์ธ์ด๋ค. - ์บ์ ์ ์ค๋ฅ (Cache Hit Ratio)์ 99% ํ๋ฐ์ด ์ ์์ด๊ณ , ๋จ์ด์ง๋ฉด ๋์คํฌ๋ฅผ ์ฝ๊ณ ์๋ค๋ ์ ํธ๋ค. Blks Read์ ์๊ฐ ์ต๋๊ฐ์ด ํฌ๋ฉด ํ ์ค์บ์ ์์ฌํ๋ค.
- Temp Bytes·Temp Files๊ฐ 0์ด ์๋๋ฉด ์ ๋ ฌ·ํด์๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋์ด ๋์คํฌ๋ก ํ๋ ๋ค๋ ๋ป์ด๋ค. ์ธ๋ฑ์ค๋ก ์ ๋ ฌ์ ๋์ ํ๊ฒ ํ๋ค.
- ๋๋ถ๋ถ์ ์งํ๋ ํผ์ ํ์ง ์๋๋ค. CPU·Active Backend·Blks Read·Tup·IOPS๊ฐ ๊ฐ์ ์๊ฐ์ ํจ๊ป ์์ง์ด๋์ง๋ฅผ ๋ณด๋ฉด ์์ธ์ ์ค๊ณฝ์ด ์กํ๋ค. ๊ทธ๋์ ๊ฐ ์งํ๋ง๋ค "ํจ๊ป ํ์ธํ ์งํ" ๋ฅผ ๊ฐ์ด ์ ์ด ๋ ๊ฒ์ด๋ค.
์ด๋ก์จ MySQL·Oracle·PostgreSQL ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ฐ์ ํ๋ก ์ ๋ฆฌํด ๋ดค์ต๋๋ค. ์ธ ๊ธ์ ๋๋ํ ๋๊ณ ๋ณด๋ฉด, ๊ฐ์ "๋ฐ์ดํฐ๋ฒ ์ด์ค" ๋ผ๋ ๋ฌด์์ ๊ฐ์ฅ ์ ๊ฒฝ ์จ์ ๋ณด๋์ง๊ฐ ์กฐ๊ธ์ฉ ๋ค๋ฅด๋ค๋ ๊ฒ์ด ๋ถ๋ช ํด์ง๋๋ค.
- MySQL์ ์คํ ๋ฆฌ์ง ์์ง์ธ InnoDB์์ ์๊น์ด ๋์ต๋๋ค. ๋ฒํผํ ์ ์ค๋ฅ , ํ ๋ฝ ๋๊ธฐ, History list length(undo) ๊ฐ์ ์งํ๊ฐ InnoDB์ ๋์์์ ๋น๋กฏ๋ฉ๋๋ค.
- Oracle์ Redo·Undo·Library Cache·ํ์ฑ์ด ์ค์ฌ์ ๋๋ค. ๋ณ๊ฒฝ๋์ Redo·Undo๋ก, ๋์์ฑ·์ฝ๊ธฐ ์ผ๊ด์ฑ์ Undo๋ก, SQL ํจ์จ์ ํ์ฑ(๋ฐ์ธ๋ ๋ณ์)์ผ๋ก ๋๋ฌ๋ฉ๋๋ค.
- PostgreSQL์ MVCC์ ๊ทธ ์ฒญ์(VACUUM) ๊ฐ ์ค์ฌ์ ๋๋ค. ๋ณ๊ฒฝ์ด ์ฃฝ์ ํ์ ๋จ๊ธฐ๊ณ , ๊ทธ๊ฒ์ VACUUM์ด ์น์ฐ๋ฉฐ, ํธ๋์ญ์ ID์ ๋์ด(Age)๋ฅผ ๊ด๋ฆฌํ๋ ์ผ์ด ์ด DB์ ๊ณ ์ ํ ์ ๊ฒ ํฌ์ธํธ์ ๋๋ค.
์ธ DB ๋ชจ๋ ๊ฒฐ๊ตญ์ "๋ณ๊ฒฝ ์ ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๊ด๋ฆฌํ๊ณ ์ ๋ฆฌํ๋๋" ๋ผ๋ ๊ฐ์ ๋ฌธ์ ๋ฅผ ๊ฐ์ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ํ๋๋ค. Oracle์ Undo๋ผ๋ ๋ณ๋ ๊ณต๊ฐ์, PostgreSQL์ ํ ์ด๋ธ ์์ ์ ๋ฒ์ ์ ๋จ๊ฒผ๋ค๊ฐ VACUUM์ผ๋ก ์น์ฐ๊ณ , MySQL์ InnoDB๋ undo ๋ก๊ทธ(History list)๋ก ๊ด๋ฆฌํฉ๋๋ค. ์ด ์ฐจ์ด๋ฅผ ์๊ณ ๋ณด๋ฉด, ๊ฐ์ ๋ชจ๋ํฐ๋ง ํ๋ฉด์ด๋ผ๋ ์ด๋ ์งํ๋ฅผ ๋จผ์ ๋ด์ผ ํ๋์ง๊ฐ DB๋ง๋ค ์์ฐ์ค๋ฝ๊ฒ ๋ฌ๋ผ์ง๋๋ค. ์ธ ํธ์ ๊ฑธ์ณ ์ ๋ฆฌํ ๋ด์ฉ์ด, ์ด๋ค DB์ ์งํ๋ฅผ ๋ณด๋ "๋ฌด์์ ์๋ฏธํ๊ณ / ํ์ ์ด๋ ์ ๋์ด๊ณ / ํ๋ฉด ๋ญ ์์ฌํ๊ณ / ์ด๋ค ์ฟผ๋ฆฌ๋ก ํ์ธํ๋์ง" ๋ผ๋ ๊ฐ์ ํ๋ก ์ ๊ทผํ๋ ๋ฐ ๋์์ด ๋๋ฉด ์ข๊ฒ ์ต๋๋ค.
'ํ๋ก์ ํธ > DB ์๋ํ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| DB ๋ชจ๋ํฐ๋ง ์ด์ ํ์ง์ ์ง๋จ ๋ฆฌํฌํธ ๋ก์ง ๊ตฌ์ฑ (0) | 2026.06.19 |
|---|---|
| MySQL ์ธ๋ฑ์ค ๋์ ์๋ฆฌ์ ์กฐ์ธ ์ต์ ํ (0) | 2026.06.19 |
| ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ํฐ๋ง ์งํ ์ ๋ฆฌ (2) Oracle (0) | 2026.06.19 |
| ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ํฐ๋ง ์งํ ์ ๋ฆฌ (1) - MySQL (0) | 2026.06.18 |
| DBA์ ์ํตํ๊ธฐ ์ํ DB ๋ชจ๋ํฐ๋ง ์งํ ๊ธฐ์ด (0) | 2026.06.16 |