Fri, 04 Aug 2023 16:29:05 +0900

pgbouncer 이야기

PostgreSQL 세션 프로세스 연결 시간 관리

PostgreSQL 데이터베이스 서버는 클라이언트가 서버로 접속하면 그에 상응하는 백엔드 프로세스라는 것을 만들어서 그 백엔드 프로세스가 클라이언트의 요청에 응답하는 방식으로 운영됩니다. 흔히 이 백엔드 프로세스를 세션 프로세스라고 합니다.

즉, 클라이언트가 100개가 각각 100개의 연결을 하고 있다면, 100개의 이 백엔드 프로세스가 데이터베이스 서버가 운영되고 있는 OS에 만들어져 돌아가는 샘이죠.

이 백엔드 프로세스는 pg_stat_activity 뷰나, 리눅스 환경이라면, OS ps 명령이나 top 명령으로 살펴보기도 합니다. pg_stat_activity 뷰로는 그 백엔드 프로세스의 각 개별 OS 자원 사용률을 살펴볼 수 없지만, OS에서 각 프로세스별 자원 사용률을 살펴보면 상식적으로는 이해가 되지 않는 현상을 가끔 마주하기도 합니다.

세션이 오랫동안 연결해 있으면, 해당 백엔드 프로세스의 RSS(메모리 점유량) 값이, 이 보다 연결 시간이 적은 백엔드 프로세스보다 많고, 이 값이 접속 시간에 비례해서 계속 커진다는 것이죠.

이는 리눅스 환경에서 이 RSS 값은 그 프로세스가 사용하는 공유 메모리 영역도 함께 포함되어 계산되고 보여지기 때문입니다.

다행이 14버전부터 pg_log_backend_memory_contexts()함수로 이 백엔드 프로세스의 메모리 내부를 볼 수 있어서, 이 값과 RSS 차이가 있는 것을 설명할 수 있어서 다행이지만, 그 이전 버전에서 이 부분을 PostgreSQL을 잘 모르는 사람들에게 설명하기가 쉽지 않았습니다.

이런 긴 이야기 끝에 나온 말이 "PostgreSQL에서는 주기적인 연결 세션의 재접속이 필요하다" 는 것입니다.

어떤 서비스에서는 1년을 계속 연결해 있어도 괜찮은데, 어떤 서비스는 하루만 지나면, OS의 OOM Killer가 백엔드 프로세스를 중지시키버려 수시로 데이터베이스가 재초기화 되는 일이 일어나기도 합니다. 이런 문제를 피할 수 있는 방법은 RSS 값이 큰 백엔드 프로세스 기준으로 그 연결을 끊고 재연결하는 것이 가장 단순한 해결 방법입니다.

이 방법으로 가장 무식한 방법은 DB를 사용할 때만 응용 프로그램이 DB로 접속하고, DB 작업이 끝나면 DB 연결을 끊는 것이겠죠. 하지만, 이 방법은 과도한 연결 비용을 감수해야합니다.

연결 관리자(connection pooler for database)의 필요성

앞부분에서 다뤘듯이 PostgreSQL은 다중 프로세스 기반 서버이며, 각 세션 연결은 그 연결 요청이 받아들여질 때, 그 때 실시간으로 클라이언트와 대응하는 백엔드 프로세스를 만들어 처리합니다. 이 때문에, 갑자기 연결을 원하는 클라이언트들이 많아지면, 데이터베이스 서버는 이 백엔드 프로세스를 만드는 비용이 갑자기 커지게 되고 이것이 데이터베이스 성능을 저하시키는 결정적인 요인으로 작용합니다.

아파치 웹 서버처럼 미리 몇개의 준비된 백엔드 프로세스를 만들어 두고, 클라이언트 요청에 맞춰 백엔드 프로세스를 할당하는 방식이 아닙니다. 아직까지는 이 방식으로 연결 처리하는 것은 고려대상이 아닌 것 같습니다.

그래서, 초창기부터 PostgreSQL은 엔터프라이즈 환경에서 사용한다면, 3rd party 연결 관리 솔루션을 사용하기를 권고하고 있습니다.

이 데이터베이스 연결 관리자는 대부분 응용프로그램을 구현하는 프로그래밍 언어에 종속적입니다. 응용 프로그램이 데이터베이스 연결을 하고 그 연결 객체를 이용해서 쿼리를 보내고 결과를 받아 처리하고 하는 것들이 대부분 프로그래밍 언어에서는 표준화 되어있고, 각 데이터베이스별로 이 표준안을 지켜 각 데이터베이스에 맞는 연결 방법을 구현하기 때문입니다. 단순하게 생각하면, 그냥 내가 쓰는 프로그래밍 언어에서 쓸 수 있는 연결 관리자를 쓰면 문제가 없을 것이다고 생각하고, 별 탈 없이 쓰고 있습니다.

하지만, PostgreSQL은 앞에서 언급했듯이 다중 프로세스 기반 백엔드 처리 기법의 한계로 이 연결 관리자를 쓸 때 꼭 고려해야할 사항이 하나 더 있습니다.

지금 놀고 있는 연결이 일정 시간 이상 연결 되어있었다면, 그 연결을 끊고, 다른 새 연결을 준비할 수 있는가? 입니다.

일반적으로 idle timeout 이라고 합니다. 즉, 개발을 시작하면서 데이터베이스 연결 솔루션을 사용한다면, 제일 먼저 확인해 봐야할 것이 일정 시간이 지난 백엔드 세션이 있는가입니다. 만일 있다면 그 오래된 백엔드 세션이 자동으로 정리 될 수 있도록 그 연결 솔루션 설정을 조정하는 것입니다.

몇몇 연결 솔루션에서는 아에 이런 기능을 제공하지 않는 것도 있으니, 꼭 살펴보아야합니다.

하지만, 놀고 있는 연결을 잘 정리한다고 하더라도 문제가 하나 더 남아 있습니다.

바로 놀고 있지 않고, 너무도 열심히 잘 쓰고 있는 연결을 어떻게 버리고 새 연결을 사용할 수 있는가? 인데. 바로 연결의 최대 수명 주기를 제어하는 것입니다. 어떤 이유로도 이 연결은 1시간을 넘길 수 없다. 이런 식의 설정입니다. 일반적인 용어로는 life timeout 입니다.

대부분의 연결 솔루션은 이런 PostgreSQL 특성을 고려하지 않기 때문에, life timeout에 대해서는 제어할 수 있는 방법을 제공하고 있지 않습니다.

그래서, 결국 pgbouncer가 등장하게 됩니다.

pgbouncer는

pgbouncer는 PostgreSQL 서버가 엄청 많은 (대략 80 이상) 연결 상태를 유지하고 있게 되면 성능이 급격하게 떨어지는 초창기 버전들의 한계를 극복하기 위해서 만들어졌습니다.

요즘 사용하는 최신 PostgreSQL 서버들은 이 문제를 많이 개선했지만, 앞에서 이야기한 엔터프라이즈 환경에서 근본적인 연결 관리 솔루션이 필요하다는 것은 여전히 유효하기 때문에, 요즘은 연결 관리 솔루션 본연의 목적인 미리 연결 확보해 두고 클라이언트가 요청하면 준비된 연결을 제공하고, 다 쓴 연결을 다시 연결 대기 상태로 두고, 각 설정에 맞춰 timeout 작업을 해서 데이터베이스 서버쪽 부담을 줄이는 역할에 보다 충실하도록 계속 개선되고 있습니다.

딱 여기까지입니다. 목적이 분명하고 기타 다른 기능들을 최대한 도입하지 않는 연결 관리자 본연의 일만하는 솔루션입니다. pgbouncer에는 auto failover 기능이 없습니다. load balance 기능도 없습니다. 쿼리 결과 집합 캐싱 기능도 없습니다.

pgbouncer의 최대 장점은 응용프로그램의 기존 DB 연결 설정을 하나도 바꾸지 않아도 된다는 점입니다.

최대 단점은 또 새로운 pgbouncer 서버(디비 운영자 관점에서 보면, 또 하나의 DB 서버가 운영 되는 식이거든요)를 운영해야한다는 점이겠죠.

또 새로운 솔루션을 운영해야하는 부담감

서비스 운영에서 문제가 생겼을 때, 살펴보아야 할 부분이 하나 더 늘었다는 것은 꽤 부담입니다.

특히나 그것이 오픈소스라면, 그 소프트웨어의 사용권과 사용할 버전과 문제 상황에서 기대 커뮤니티도 살펴야합니다.

pgbouncer는 단일 버전 새 기능과 버그 픽스로 버전 관리를 하기 때문에, 무조건 가장 마지막 정식 배포된 버전을 사용하는 것이 무난합니다.

하지만, pgbouncer도 하나의 서비스를 제공하는 서버이며, 그 서버 동작이 이상해지면, 그 클라이언트 전체에 영향을 끼치기에, 서비스 장애 상황이나, 품질이 떨어지는 상황일 때 반드시 pgbouncer가 잘 동작하고 있는지를 확인해야합니다.

즉, 관리자는 결국 또 하나의 서버 관리 능력을 키워야 함을 의미합니다.

앞에서 다뤘듯이 pgbouncer는 pooler 기능에 집중한 서버입니다. 그래서, 초기 도입 안정화 작업만 잘 했다면,

1. 클라이언트들이 잘 접속하는지와,

2. 자기가 클라이언트가 되는 디비 서버 쪽으로 잘 접속하는지,

3. 현재 상태가 어떤지

이것만 잘 살펴보고 문제 상황을 잘 해결 할 수 있다면 운영 부담은 다른 서버군 소프트웨어보다 관리 비용이 적을 수 있습니다.

새로운 솔루션이 도입되어 응용프로그램을 바꿔야하는 부담감

앞에서 이야기한 대로 pgbouncer 도입의 최대 장점은 응용프로그램 쪽에서 바꾸어야 할 부분이 전혀 없다는 것입니다.

물론 클라이언트와 pgbouncer 간 연결은 끊기지 않았지만, pgbouncer 내부 설정에 따라 pgbouncer와 db 인스턴스간 연결이 재 초기화 되는 설정이 있는데, 응용 프로그램이 그것을 고려하지 않은 db 기능을 사용하는 경우는 당연히 문제가 생기겠죠.

대표적인 예가, prepare 구문을 사용하는 서버측 준비된 구문과, declare 구문을 사용하는 서버측 커서 같은 것들이겠죠.

이런 것을 사용한다면, pgbouncer 설정에서 응용 프로그램 - pgbouncer - db server 연결을 항상 보장하는 방식으로 운영해야할 것입니다.

이런 응용프로그램이 db 인스턴스를 어떻게 쓰는지 모른다면, 도입 검증용 환경에서 충분히 검증을 해야할 것입니다. 이 때는 pgbouncer 로그와 db 인스턴스의 클라이언트 접속 로그를 부지런히 비교해 보아야합니다. 그리고 문제 상황들을 차근히 푼뒤 운영 환경에 적용해야할 것 같네요. (당연한 이야기지만)

pgbouncer 설명

만들기 & 설치

소스 구하고, https://pgbouncer.org

configure

make && make install

여느 오픈소스 빌드 작업과 크게 다르지는 않습니다.

pgbouncer는 네트워크 패킷 처리를 위해 event 라이브러리를 사용합니다.

그래서, libevent 패키지 관련 개발 패키지 (header 파일이 포함되어 있는 패키지)가 설치 되어 있어야 컴파일이 됩니다.

환경 설정

make install 작업으로 만들어진 share/doc/pgbouncer 폴더 안에 샘플 환경 설정 파일이 있습니다.

이것을 적당한 곳으로 옮기고 적당하게 편집합니다.

su - postgres

cd $PGDATA

cp /usr/local/share/doc/pgbouncer/pgbouncer.ini .

vim pgbouncer.ini

환경설정은 크게 다음과 같습니다.

1. 응용프로그램이 pgbouncer로 접속하는 데이터베이스 정의 [databases]
곧 사용할 데이터베이스 정의가 되겠죠. 이 데이터베이스로 응용프로그램이 접속하면 pgbouncer는 내부적으로 db 인스턴스 어느 데이터베이스를 사용할 것인지를 맵핑하는 설정입니다.

2. 사용자별 개별 설정 [users]
응용프로그램이 pgbouncer로 접속하는 사용자별 개별 설정인데, 일반적으로 비워둡니다. (대부분 설정은 아래 pgbouncer 서버 전역 설정을 사용하기에 딱히 따로 지정할 상황을 고려하지 않아도 될 것 같습니다.)

3. pgbouncer 설정 [pgbouncer]
connection pooler 의 일반 설정이 이 부분에서 합니다. 일반적으로 다음 몇가지를 빼고는 기본값을 그대로 사용해도 무난합니다.

1. auth_type, auth_file : 클라이언트 인증 관련 정보
auth_type = md5
auth_file = 패스워드파일 (scram-sha-256 비밀번호라면, PostgreSQL 서버의 pg_authid.rolpassword 값을 가져와서 사용하면 된다.)

2. admin_users : pgbouncer 서버 각종 정보를 보거나 기능을 SQL로 제어하려고 할 때 접속하는 pgbouncer 데이터베이스로 접속 할 수 있는 사용자 이름

3. stats_users : pgbouncer 사용 통계 정보를 볼 수 있는 사용자 이름

4. pool_mode : 서비스 성격에 따라 잘 지정해야 합니다.
session: 한 번 접속하면 클라이언트가 끊기기 전까지 연결 유지, 기본값
transaction: 연결을 트랜잭션 단위로
statement: SQL 한 구문 단위로
일반적인 웹 서비스라면, transaction 단위도 무난합니다.

5. 클라이언트 접속 제한을 위한 각종 설정 max_client_conn, min_pool_size, reserve_pool_size, max_db_connections
각 설정을 도움말을 보면서 적당하게 조정해서 사용해서 쓰면 됩니다. 기억해야할 것은 윗 네가지 설정을 기본값이 실운영환경에는 적합하지 않습니다. 서비스 성격에 맞게 조정하는 것이 바람직합니다.
예를 들어, DB 인스턴스가 실행되고 있는 호스트의 CPU 코어가 8개라면, max_db_connections 값을 그 값의 8배 이상을 잡지 않는 것이 좋습니다. 물론 이 가정은 pool_mode 가 transaction 이고, idle in transaction 상태가 거의 없는 작업만 있다는 가정 아래일 뿐입니다. 무조건 'max_db_connections 값은 cpu 코어수의 8배다' 이런 생각은 아주 위험합니다. 나머지 설정도 마찬가지입니다.

6. 다음 pgbouncer의 로그 관련 설정이 있는데, 기본 로그 설정이 많은 정보를 남깁니다. 그래서, 메인 DB 인스턴스 운영과 달리 pgbouncer는 대부분 운영 담당자에게는 방치형 서버가 될 가능성이 큽니다. 안정화 작업을 충분히 거쳤 더 이상 안봐도 되는 로그는 남기지 않겠다고 설정해야, 로그 분석시 편할 것입니다. 도입 초기는 기본값으로 쓰고 안정화 되었다면, 이 로그 관련 설정을 바꾸어 운영할 필요가 있습니다. 안그러면, pgbouncer 서버 로그 관리도 해야하는 상황이 발생할 수도 있습니다.

7. 각종 timeout 관련 설정, server_lifetime, server_idle_timeout 이 두 설정은 신경을 써야합니다. 앞에서 다룬 오래된 연결 세션 프로세스들이 많아서 발생하는 out of memory killer 작동으로 인한 데이터베이스 재초기화 문제를 피하는 결정적인 설정입니다.
client_idle_timeout, idle_transaction_timeout, query_timeout 같은 설정은 서비스의 성격에 따라 너무도 다양해서 이 글에서는 언급하지 않겠습니다.

8. 그외 나머지 저수준 tcp/ip 연결에 대한 각종 설정들인데, 이 부분은 대부분 OS 기본값을 사용하는것이 무난합니다. 물론 pgbouncer와, PostgreSQL 사이가 원거리 네트워크 환경이라면, 상황이 또 달라지겠지만, 일반적인 구성상으로는 이 두 소프트웨어 연결은 대부분 근거리 네트워크 환경이거나 같은 호스트내에서 운영 되기 때문에 신경을 안쓰는 것으로.

정리하면,
[databases] 영역에서 사용할 DB 설정하고,

[pgbouncer] 영역에서 admin , 사용자 인증, pooler 개수, 연결 최대수, timeout 설정해서

쓰면 됩니다.

실행

pgbouncer 실행에 앞서, pgbouncer.ini에서 언급한 userlist.txt 파일을 준비해야합니다.

이 글에서는 auth_query 를 이용한 PostgreSQL 서버에서 사용자 정보를 가져와 인증하는 방식을 사용하지 않고, 그냥 일반 텍스트 파일에

"사용자이름" "비밀번호"

양식의 사용자 목록 파일(userlist.txt)을 사용자 인증용으로 사용하려고 합니다. 그래서,

이 파일을 하나 만들어야합니다.

"postgres" "SCRAM-SHA-256$......"

뒤부분의 비밀번호 문자열은

DB 서버에서

ALTER ROLE postgres PASSWORD 'mysecret'
SQL을 실행하고, 그 결과가 저장된, pg_authid.rolpassword 값을 그대로 사용하면 됩니다.

다음 pgbouncer 실행

nohup ./pgbouncer pgbouncer.ini > pgbouncer.log 2>&1 &

일반적인 서버 실행방법과 다르지 않지만, pgbouncer.ini 파일 지정은 꼭 해야합니다.

로그 파일 관리 부분이 고려되지 않았는데,

윗 방식으로 실행하게 되면, 자꾸만 커져가는 로그파일 정리가 힘들어집니다.

OS 기본 패키지인 logrotate 같은 도구로 로그파일 돌려쓰기를 하려면, pgbouncer.ini에서 로그파일 설정을 하고, pgbouncer는 데몬모드로 실행하고, pgbouncer 프로세스에 HUP 신호를 보내서 환경설정을 다시 반영하는 방식으로 풀어야할 것 같습니다. postrotate 로 kill -HUP `cat pgbouncer.pid` 같은 명령을 등록해 주면 될 것 같네요.

pgbouncer 데몬모드(-d 옵션 추가)가 충분히 안정적인가?에 대한 대답은 피합니다.
소프트웨어 안정성에 대한 검증은 쓰는 사람 몫이니까요.
(데몬 모드의 신뢰성을 의심한다면, OS 서비스 등록으로 푸는 방법도 있습니다.)

나름대로 고민해본 최적의 도입 방안

pgbouncer를 운영 할 때 기억해야할 것은

그 프로세스

pgbouncer 프로세스가 어느 호스트에서 실행될 것인가입니다.

응용프로그램 서버 쪽에 두어 pgbouncer를 병렬화 하는 방법

DB 인스턴스가 있는 쪽에 두어 전통적인 DB 인스턴스의 연결관리자 역할만 하는 방법

pgbouncer 인스턴스가 실행되는 전용 호스트를 두는 방법

각 구성 방법에는 각각 장단점이 있습니다.

이 글에서는 두번째 구성 방법을 소개합니다.

이유는 다음과 같습니다.

pgbouncer 운영 주체가 DB 인스턴스 운영 주체와 같은 경우가 많습니다.

pgbouncer의 고가용성은 auto failover 정도만으로 충분하다고 판단 되었습니다.

보안성을 높이는 측면에서 봐도 응용프로그램 서버 쪽에 있는 것보다 안전할 것입니다.

이렇게 되면 응용프로그램 환경 변경 최소화를 목표로 하고 있을 때, PostgreSQL 리슨 포트와 pgbouncer의 리슨 포트가 충돌하게 됩니다.

피하는 방법

PostgreSQL 인스턴스는 unix domain socket 접속만 허용해서, tcp listen 포트는 아에 쓰지 않는 설정을 합니다.
postgresql.conf 에서 listen_addresses = ''

pgbouncer 에서는 반대로 tcp listen 포트만 열고, unix domain socket을 사용하지 않는 설정을 합니다.

이렇게 하면,

psql 명령만 실행하면, PostgreSQL 인스턴스로 접속하고,

psql -h 127.0.0.1 로 실행하면, pgbouncer 인스턴스로 접속하는 전략입니다.

모든 포트는 기본값 5432 입니다.

pgbouncer 프로세스 소유주와, postgres 프로세스 소유주에 대한 OS 계정 문제도 있습니다. 이 부분에 대한 견해도 각각인데, OS 계정을 분리할지, 같은 계정으로 할 것인지에 대한 견해도 각각이지만, 일단은 관리자가 같다면, OS 계정도 같은 것이 편할 것 같습니다.

환경 설정

아래 설정은 웹 서비스용 - 서버측 prepare 구문도 없고, 커서도 없고, 2PC도 쓰지 않는 아주 일반적인 DB 인스턴스를 대상으로 작성되었습니다.

[databases]
mydb = host=/tmp user=ioseph

[users]
[pgbouncer]
logfile = /data/pg16/pgbouncer.log
pidfile = /data/pg16/pgbouncer.pid
listen_addr = *
listen_port = 5432
unix_socket_dir =
auth_type = md5
auth_file = /data/pg16/userlist.txt
admin_users = pgbouncer
stats_users = pgbouncer
pool_mode = transaction

ignore_startup_parameters = extra_float_digits

min_pool_size = 5
reserve_pool_size = 3
log_stats = 0

윗 userlist.txt 파일에는

"webuser" "비밀번호"

"pgbouncer" "pgbouncer관리자비밀번호"

이 두줄이 있습니다. webuser는 기존 응용프로그램이 사용하는 계정이름입니다.

응용 프로그램이 pgbouncer를 사용할 때는 달라지는 것은 pool_mode를 transaction으로 했기 때문에, 앞에서 다뤘듯이 연결이 보장된 상태에서 사용했던 기능들을 사용하지 않기 때문에, jdbc driver를 사용한다면, jdbc connection url에 prepareThreshold=0 옵션을 추가로 지정해야할 필요도 있습니다. 기본값이 5입니다.

관리 방법

pgbouncer 관리자와, PostgreSQL 관리자가 같다면, 위와 같은 환경에서 꼭 기억해야하는 것은 pgbouncer를 통해서 db로 접속했는지, 직접 db로 접속했는지를 헷갈리지 말아야합니다. 이 헷갈림을 피하기 위해, pgbouncer 서버 관리자 이름은 postgres을 사용하지 않는 것도 좋은 방법입니다.

psql -U postgres mydb # PostgreSQL 서버로 접속

psql -h 127.0.0.1 -U pgbouncer pgbouncer # pgbouncer 관리DB로 접속

위 환경이라면, pgbouncer로 접속할 때는 어떤 방법으로 db 슈퍼유저 권한으로 접속할 방법이 없습니다.

데이터베이스 관리자 권한으로 작업이 필요할 때는 반드시 db 인스턴스가 실행된 호스트로 쉘 접속을 해서, unix domain socket으로 해당 데이터베이스에 접속해야한다는 것입니다.

pgbouncer를 통해서 슈퍼유저 권한 접속이 필요하다면,

윗 설정 기준이라면,

mydb 처럼 mydbdba 같은 새로운 데이터베이스 하나를 더 등록하고, 그 접속 정보에 슈퍼유저 정보를 지정하는 것입니다.

mydbdba = host=/tmp user=postgres

물론 윗 설정이 localhost의 unix domain socket 접속에 대한 인증이 trust 이기 때문에, pgbouncer를 통한 슈퍼유저 접속은 보안상 많이 위험합니다. 이 부분은 hba 설정으로 어느정도는 보완할 수는 있지만 아에 접속자체를 막는것이 더 안전할 것입니다.

$ psql -h 127.0.0.1 -U pgbouncer pgbouncer
pgbouncer 사용자의 암호:
psql(16beta2, 1.20.0/bouncer 서버)
경고: psql 메이저 버전 16, 서버 메이저 버전 1.20.
일부 psql 기능이 작동하지 않을 수도 있습니다.
도움말을 보려면 "help"를 입력하십시오.

pgbouncer=# show help;
NOTICE: Console usage
상세정보:
SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|USERS|VERSION
SHOW PEERS|PEER_POOLS
SHOW FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM|STATE
SHOW DNS_HOSTS|DNS_ZONES
SHOW STATS|STATS_TOTALS|STATS_AVERAGES|TOTALS
SET key = arg
RELOAD
PAUSE []
RESUME []
DISABLE
ENABLE
RECONNECT []
KILL
SUSPEND
SHUTDOWN
WAIT_CLOSE []
SHOW

pgbouncer 데이터베이스에 접속하고, 각종 pgbouncer 관련 SQL 작업을 할 수 있습니다. 시작은 show help;

주로 쓰는 SQL 구문은 첫줄에 있는

SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|USERS|VERSION

명령과,

SHOW STATS|STATS_TOTALS|STATS_AVERAGES|TOTALS

정도입니다.

각 명령의 자세한 설명은 pgbouncer 홈페이지를 참조하세요.

이 글에서 못다한 이야기

도입을 고민하고 있다면, pgbouncer의 성능보다 안정성을 먼저 고민해야할 것 같습니다. 왜냐하면, 데이터베이스 관리자로 데이터베이스 인스턴스 보기도 바쁜데, pgbouncer 때문에 끙끙거리는 일이 최대한 없어야 하니까요.

안정성 테스트는

아주 잦은 클라이언트와 pgbouncer 간 연결에서 잘 버티는지,

아주 오랫 동안 클라이언트가 연결 되어 있음에도 db 인스턴스의 세션 관리를 잘 하는지

전체적으로 오랫동안 운영되어도 메모리 누수가 없는지

이정도 일 것 같네요.

pgbouncer를 포기해야하는 상황에서 클라이언트가 직접 DB로 접속하는 원래 상태로 돌리는 작업을 어떻게 깔끔하게 할지에 대한 계획도 잘 마련해 두어야합니다.

pgbouncer 소프트웨어의 패치 작업에 대한 계획도 필요합니다.

데이터베이스 관리자가 모니터링 도구를 통해서 데이터베이스 인스턴스를 모니터링 하듯, pgbouncer 모니터링 도구도 마련해야할 것 같습니다.

pgbouncer용 grafana 대시보드가 있긴하던데, 안 써봐서 모르겠습니다.

PostgreSQL 데이터베이스 접속 관련 문제로 고민 하고 분이 pgbouncer 도입을 고려할 때 이 글이 조금이나마 도움이 되었으면 하는 마음으로 이 글을 마칩니다.