08000 connection exception ๋?
PostgreSQL ์๋ฌ ์ฝ๋ 08000์ Connection Exception ์ผ๋ก, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ์ ๋คํธ์ํฌ ์ฐ๊ฒฐ ๊ณผ์ ์์ ์๊ธฐ์น ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ๋ํ๋๋ ์๋ฌ์
๋๋ค. ์ด ์๋ฌ๋ ๋จ์ํ ์ฟผ๋ฆฌ ์ค๋ฅ๊ฐ ์๋๋ผ ๋ฌผ๋ฆฌ์ ยท๋
ผ๋ฆฌ์ ์ฐ๊ฒฐ ๋ ์ด์ด์์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์, ์ ํ๋ฆฌ์ผ์ด์
์ด DB์ ์ ๊ทผ ์์ฒด๋ฅผ ๋ชปํ๊ฒ ๋๋ ์น๋ช
์ ์ธ ์ํฉ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก 08000 ๊ณ์ด์ ์๋ฌ๋ 08001(์ฐ๊ฒฐ ์คํจ), 08006(์ฐ๊ฒฐ ๋จ์ ) ๋ฑ ๋ ๊ตฌ์ฒด์ ์ธ ํ์ ์๋ฌ์ ํจ๊ป ๋ฑ์ฅํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฉฐ, ์๋ฌ ๋ก๊ทธ๋ฅผ ํตํด ์ ํํ ์์ธ์ ํ์
ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ฃผ์ ๋ฐ์ ์์ธ
1. PostgreSQL ์๋ฒ์ pg_hba.conf ์ธ์ฆ ์ค์ ์ค๋ฅ
pg_hba.conf๋ ์ด๋ค ํธ์คํธ, ์ด๋ค ์ฌ์ฉ์, ์ด๋ค ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ ์ ์์ ํ์ฉํ ์ง ์ ์ํ๋ ํต์ฌ ์ค์ ํ์ผ์
๋๋ค. ํด๋ผ์ด์ธํธ IP๊ฐ ํ์ฉ ๋ชฉ๋ก์ ์๊ฑฐ๋, ์ธ์ฆ ๋ฐฉ์(md5, scram-sha-256 ๋ฑ)์ด ํด๋ผ์ด์ธํธ ์ค์ ๊ณผ ๋ง์ง ์์ผ๋ฉด ์ฐ๊ฒฐ ์์ฒด๊ฐ ๊ฑฐ๋ถ๋๋ฉฐ 08000 ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค. ํนํ ์ด์ ์๋ฒ ๋ง์ด๊ทธ๋ ์ด์
์ด๋ IP ๋ณ๊ฒฝ ํ ์ด ์ค์ ์ ์
๋ฐ์ดํธํ์ง ์์ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๊ฐ ์ค๋ฌด์์ ๋งค์ฐ ๋น๋ฒํฉ๋๋ค.
2. ๋คํธ์ํฌ ๋ฐฉํ๋ฒฝ ๋๋ ํฌํธ ์ฐจ๋จ ๋ฌธ์
PostgreSQL ๊ธฐ๋ณธ ํฌํธ์ธ 5432๊ฐ ๋ฐฉํ๋ฒฝ ๋๋ ๋ณด์ ๊ทธ๋ฃน(AWS Security Group, iptables ๋ฑ)์ ์ํด ์ฐจ๋จ๋์ด ์์ผ๋ฉด, ํด๋ผ์ด์ธํธ๋ ์๋ฒ์ TCP ์ฐ๊ฒฐ ์์ฒด๋ฅผ ๋งบ์ ์ ์์ต๋๋ค. ํด๋ผ์ฐ๋ ํ๊ฒฝ(AWS RDS, GCP Cloud SQL ๋ฑ)์์ ์ธ๋ฐ์ด๋ ๊ท์น์ ์๋ชป ์ค์ ํ๊ฑฐ๋, ์จํ๋ ๋ฏธ์ค ํ๊ฒฝ์์ OS ๋ฐฉํ๋ฒฝ ์ค์ ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ์ด ๋ฌธ์ ๊ฐ ๋ํ๋ฉ๋๋ค. ์ฐ๊ฒฐ ํ์์์์ด ๋ฐ์ํ๊ฑฐ๋ "Connection refused" ๋ฉ์์ง๊ฐ ํจ๊ป ์ถ๋ ฅ๋๋ค๋ฉด ์ด ์์ธ์ ๊ฐ์ฅ ๋จผ์ ์์ฌํด์ผ ํฉ๋๋ค.
3. postgresql.conf์ listen_addresses ๋ฐ max_connections ์ค์ ๋ฌธ์
listen_addresses๊ฐ localhost๋ก๋ง ์ค์ ๋์ด ์์ผ๋ฉด, ์ธ๋ถ IP์์์ ๋ชจ๋ ์ฐ๊ฒฐ ์๋๋ ๊ฑฐ๋ถ๋ฉ๋๋ค. ๋ํ max_connections ํ๋์ ๋๋ฌํ์ ๊ฒฝ์ฐ, ์๋ก์ด ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ์ด ์๋ฆฝ๋์ง ๋ชปํ๊ณ ์ฐ๊ฒฐ ์์ธ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ํนํ ์ปค๋ฅ์
ํ ์์ด ์ด์ํ๋ ์ ํ๋ฆฌ์ผ์ด์
์์ ํธ๋ํฝ์ด ๊ธ์ฆํ ๋ ์ด ์ํฉ์ด ์์ฃผ ๋ฐ์ํ๋ฉฐ, ์ด์ ์ค ๊ฐ์์ค๋ฌ์ด ์ฐ๊ฒฐ ์คํจ์ ์ฃผ์ ์์ธ ์ค ํ๋์
๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ
์์ธ 1: pg_hba.conf ์ค์ ์์
ํ์ฌ pg_hba.conf ํ์ผ์ ๋ด์ฉ์ ํ์ธํ๊ณ , ์ ์์ ํ์ฉํ ํด๋ผ์ด์ธํธ IP์ ์ธ์ฆ ๋ฐฉ์์ ์ถ๊ฐํฉ๋๋ค.
-- pg_hba.conf ํ์ฌ ์ค์ ๋ด์ฉ ํ์ธ (PostgreSQL 10 ์ด์)
SELECT * FROM pg_hba_file_rules;
-- pg_hba.conf ํ์ผ ๊ฒฝ๋ก ํ์ธ
SHOW hba_file;
pg_hba.conf ํ์ผ์ ์ง์ ํธ์งํฉ๋๋ค (OS ๋ ๋ฒจ):
# /etc/postgresql/15/main/pg_hba.conf ์์
# ํน์ IP์์ ํน์ DB/์ ์ ์ ์ ํ์ฉ (scram-sha-256 ์ธ์ฆ)
host mydb myuser 192.168.1.100/32 scram-sha-256
# ํน์ ์๋ธ๋ท ์ ์ฒด ํ์ฉ
host all all 10.0.0.0/8 scram-sha-256
# ๋ก์ปฌ ์์ผ ์ ์ ํ์ฉ
local all all peer
์ค์ ๋ณ๊ฒฝ ํ PostgreSQL์ ์ฌ๋ก๋ํฉ๋๋ค (์ฌ์์ ์์ด ์ ์ฉ ๊ฐ๋ฅ):
-- PostgreSQL ๋ด๋ถ์์ ์ค์ ๋ฆฌ๋ก๋
SELECT pg_reload_conf();
# OS ๋ ๋ฒจ์์ ๋ฆฌ๋ก๋
sudo systemctl reload postgresql
# ๋๋
sudo pg_ctlcluster 15 main reload
์์ธ 2: ๋ฐฉํ๋ฒฝ ๋ฐ ํฌํธ ์ค์ ํ์ธ
# PostgreSQL ํฌํธ ๋ฆฌ์ค๋ ์ฌ๋ถ ํ์ธ
ss -tlnp | grep 5432
# ๋๋
netstat -tlnp | grep 5432
# iptables ๋ฐฉํ๋ฒฝ 5432 ํฌํธ ํ์ฉ (Linux)
sudo iptables -A INPUT -p tcp --dport 5432 -s 192.168.1.0/24 -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4
PostgreSQL์์ ํ์ฌ ํ์ฑ ์ฐ๊ฒฐ ๋ฐ ์ ์ ํํฉ์ ํ์ธํ๋ ์ฟผ๋ฆฌ:
-- ํ์ฌ ์ ์ ์ค์ธ ํด๋ผ์ด์ธํธ IP ๋ฐ ์ํ ํ์ธ
SELECT
pid,
usename,
application_name,
client_addr,
client_port,
state,
backend_start
FROM pg_stat_activity
WHERE state IS NOT NULL
ORDER BY backend_start DESC;
-- ํด๋ผ์ด์ธํธ IP๋ณ ์ฐ๊ฒฐ ์ ์ง๊ณ
SELECT
client_addr,
count(*) AS connection_count
FROM pg_stat_activity
WHERE client_addr IS NOT NULL
GROUP BY client_addr
ORDER BY connection_count DESC;
์์ธ 3: postgresql.conf ์ค์ ๊ฒํ ๋ฐ ์์
-- ํ์ฌ listen_addresses ๋ฐ max_connections ์ค์ ํ์ธ
SHOW listen_addresses;
SHOW max_connections;
-- ํ์ฌ ์ฌ์ฉ ์ค์ธ ์ฐ๊ฒฐ ์ vs ์ต๋ ์ฐ๊ฒฐ ์ ๋น๊ต
SELECT
count(*) AS current_connections,
(SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS max_connections,
(SELECT setting::int FROM pg_settings WHERE name = 'max_connections') - count(*) AS available_connections
FROM pg_stat_activity;
postgresql.conf ํ์ผ ์์ (OS ๋ ๋ฒจ):
# /etc/postgresql/15/main/postgresql.conf
# ๋ชจ๋ IP์์ ์ ์ ํ์ฉ (๋ณด์ ๊ทธ๋ฃน/๋ฐฉํ๋ฒฝ์ผ๋ก ๋ณ๋ ์ ์ด)
listen_addresses = '*'
# ์ต๋ ์ฐ๊ฒฐ ์ ์กฐ์ (์๋ฒ ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ๋ผ ์กฐ์ ํ์)
max_connections = 200
# ์ํผ์ ์ ์ ์ฉ ์์ฝ ์ฐ๊ฒฐ (๊ธด๊ธ ์ ์์ฉ)
superuser_reserved_connections = 3
์ค์ ๋ณ๊ฒฝ ํ ๋ฐ๋์ ์ฌ์์์ด ํ์ํ ํญ๋ชฉ ํ์ธ:
-- ์ฌ์์ ์์ด ์ ์ฉ ๊ฐ๋ฅํ ํญ๋ชฉ vs ์ฌ์์ ํ์ ํญ๋ชฉ ํ์ธ
SELECT
name,
setting,
context
FROM pg_settings
WHERE name IN ('listen_addresses', 'max_connections', 'superuser_reserved_connections');
-- context = 'postmaster' ์ด๋ฉด ์ฌ์์ ํ์
-- context = 'sighup' ์ด๋ฉด reload๋ง์ผ๋ก ์ ์ฉ ๊ฐ๋ฅ
-- ์ ํด ์ํ ์ฐ๊ฒฐ ๊ฐ์ ์ข
๋ฃ (๊ธด๊ธ ์ ์ฌ์ฉ)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND state_change < now() - interval '10 minutes'
AND usename != 'postgres';
์๋ฐฉ ๋ฐฉ๋ฒ
1. ์ปค๋ฅ์ ํ๋ฌ ๋์ ์ผ๋ก ์ฐ๊ฒฐ ์ ์์ ํ
PgBouncer ๋๋ Pgpool-II ๊ฐ์ ์ปค๋ฅ์
ํ๋ฌ๋ฅผ ์ ํ๋ฆฌ์ผ์ด์
๊ณผ PostgreSQL ์ฌ์ด์ ๋ฐฐ์นํ๋ฉด, ์ค์ DB์ ๋งบ์ด์ง๋ ์ฐ๊ฒฐ ์๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ ์ดํ ์ ์์ต๋๋ค. PgBouncer์ transaction ๋ชจ๋๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์์ฒ ๊ฐ์ ํด๋ผ์ด์ธํธ ์์ฒญ๋ ์์ญ ๊ฐ์ ์ค์ DB ์ฐ๊ฒฐ๋ก ์ฒ๋ฆฌํ ์ ์์ด max_connections ์ด๊ณผ๋ก ์ธํ 08000 ์๋ฌ๋ฅผ ๊ทผ๋ณธ์ ์ผ๋ก ์๋ฐฉํ ์ ์์ต๋๋ค. ์๋๋ PgBouncer ๊ธฐ๋ณธ ์ค์ ์์์
๋๋ค.
# /etc/pgbouncer/pgbouncer.ini ํต์ฌ ์ค์
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb
[pgbouncer]
listen_port = 6432
listen_addr = *
auth_type = scram-sha-256
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20
-- ๋ชจ๋ํฐ๋ง: ํ์ฌ ์ฐ๊ฒฐ ์ ์๊ณ์น ์๋ฆผ์ฉ ์ฟผ๋ฆฌ (๋ชจ๋ํฐ๋ง ์์คํ
์ ๋ฑ๋ก)
SELECT
CASE
WHEN count(*) > (SELECT setting::int * 0.8 FROM pg_settings WHERE name = 'max_connections')
THEN 'WARNING: ์ฐ๊ฒฐ ์ 80% ์ด๊ณผ'
ELSE 'NORMAL'
END AS connection_status,
count(*) AS current_conn
FROM pg_stat_activity;
2. ์ค์ ๋ณ๊ฒฝ ์ ์ฒดํฌ๋ฆฌ์คํธ ๋ฐ ํ ์คํธ ์ ์ฐจ ์๋ฆฝ
pg_hba.conf, postgresql.conf ๋ฑ ์ฐ๊ฒฐ ๊ด๋ จ ์ค์ ํ์ผ์ ๋ณ๊ฒฝํ ๋๋ ๋ฐ๋์ ์คํ
์ด์ง ํ๊ฒฝ์์ ๋จผ์ ๊ฒ์ฆํ๊ณ , ๋ณ๊ฒฝ ์ ๋ฐฑ์
์ ๋จ๊ธฐ๋ ์ต๊ด์ ๋ค์ฌ์ผ ํฉ๋๋ค. ํนํ pg_hba.conf ์์ ํ์๋ pg_reload_conf() ์ ์ฉ ์ ์ pg_hba_file_rules ๋ทฐ๋ฅผ ํตํด ํ์ฑ ์ค๋ฅ ์ฌ๋ถ๋ฅผ ํ์ธํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
-- ์ค์ ๋ฆฌ๋ก๋ ์ pg_hba.conf ํ์ฑ ์ค๋ฅ ํ์ธ
SELECT * FROM pg_hba_file_rules
WHERE error IS NOT NULL;
-- ์ค์ ํ์ผ ๋ณ๊ฒฝ ์ด๋ ฅ ๊ด๋ฆฌ (๋ณ๊ฒฝ ์ ์ฝ๋ฉํธ ์ถ๊ฐ ๊ถ์ฅ)
-- ์: # 2024-01-15 ํ๊ธธ๋ - ์ ๊ท ์ฑ์๋ฒ IP ์ถ๊ฐ (192.168.10.50)
๊ด๋ จ ์๋ฌ
| ์๋ฌ ์ฝ๋ | ์๋ฌ๋ช | ์ค๋ช |
|---|---|---|
08001 |
SQLSTATE 08001 - sqlclient_unable_to_establish_sqlconnection |
ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์ฐ๊ฒฐ์ ๋งบ์ ์ ์์ ๋ ๋ฐ์. ๋ฐฉํ๋ฒฝ/ํฌํธ ์ฐจ๋จ ์ ์ฃผ๋ก ๋ํ๋จ |
08003 |
connection_does_not_exist | ์ด๋ฏธ ๋ซํ ์ฐ๊ฒฐ์ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋ผ ๋ ๋ฐ์. ์ปค๋ฅ์ ํ์์ stale connection ๋ฐํ ์ ์์ฃผ ๋ฑ์ฅ |
08006 |
connection_failure | ํต์ ์ค ์ฐ๊ฒฐ์ด ๋์ด์ง ๋ ๋ฐ์. ๋คํธ์ํฌ ๋ถ์์ ๋๋ ์๋ฒ ๋น์ ์ ์ข ๋ฃ ์ ๋ํ๋จ |
08P01 |
protocol_violation | ํด๋ผ์ด์ธํธ-์๋ฒ ๊ฐ ํ๋กํ ์ฝ ๋ฒ์ ๋ถ์ผ์น ๋๋ ๋๋ผ์ด๋ฒ ๋ฒ๊ทธ๋ก ์ธํด ๋ฐ์ |
57P03 |
cannot_connect_now | ์๋ฒ๊ฐ ์์ ์ค์ด๊ฑฐ๋ ๋ณต๊ตฌ ์ค์ผ ๋ ์ฐ๊ฒฐ์ ๊ฑฐ๋ถํ๋ ์๋ฌ |
08000 ๊ณ์ด ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด PostgreSQL ์๋ฒ ๋ก๊ทธ($PGDATA/log/)์ ํจ๊ป ํด๋ผ์ด์ธํธ ์ธก ์๋ฌ ๋ฉ์์ง๋ฅผ ๋์์ ํ์ธํ๋ ๊ฒ์ด ๋น ๋ฅธ ์์ธ ํ์
์ ํต์ฌ์
๋๋ค. ์ค๋ฌด์์๋ Prometheus + postgres_exporter๋ฅผ ํ์ฉํ์ฌ ์ฐ๊ฒฐ ์, ๊ฑฐ๋ถ๋ ์ฐ๊ฒฐ ์๋ฅผ ์ค์๊ฐ์ผ๋ก ๋ชจ๋ํฐ๋งํ๊ณ , ์๊ณ์น ์ด๊ณผ ์ ์ฆ์ ์๋์ด ์ค๋๋ก ๊ตฌ์ฑํ๋ ๊ฒ์ ๊ฐ๋ ฅํ ๊ถ์ฅํฉ๋๋ค.









