명령어/DB
[PostgreSQL] SET·current_setting으로 "지금 로그인한 유저"를 세션에 심는다
jykim23
2026. 8. 2. 19:46
반응형
설치·접속: PostgreSQL 설치와 접속
부제: 애플리케이션이 로그인 직후 "현재 사용자 id"를 DB 세션에 넣어두고, 이후 쿼리·정책·감사 로그에서 그 값을 꺼내 쓸 때
-- 앱 네임스페이스(점 포함)의 커스텀 변수는 자유롭게 세팅 가능
SET app.current_user_id = '42';
SELECT current_setting('app.current_user_id');
-- 없는 변수를 그냥 읽으면 에러, 두 번째 인자 true면 NULL로 안전하게
SELECT current_setting('app.missing', true) IS NULL AS missing_ok;
current_setting
-----------------
42
missing_ok
------------
tapp.current_user_id처럼 점이 들어간 커스텀 GUC 변수는 세션 안에서 자유롭게 넣고 뺄 수 있다. SET으로 심고 current_setting으로 읽는데, 이 값은 그 연결(세션)에만 존재하고 다른 연결에는 안 보인다. 활용의 핵심은 애플리케이션의 요청 컨텍스트를 DB 안으로 전달하는 것이다 — 로그인 유저 id, 테넌트, 요청 추적 id 같은 걸 세션 변수로 넣어두면, RLS 정책이나 트리거, 감사 로그에서 파라미터를 매번 넘기지 않고도 그 값을 꺼내 쓸 수 있다. current_setting의 두 번째 인자 true는 "변수가 없으면 에러 대신 NULL"이라, 미설정 상황을 안전하게 처리하게 해준다.
이렇게도 쓴다
트랜잭션 안에서만 살아있는 값으로 심는다. 커밋되면 사라져 커넥션 풀 오염을 막는다. (조합: set_config, is_local=true)
BEGIN;
SELECT set_config('app.tenant', 'acme', true);
SELECT current_setting('app.tenant'); -- acme
COMMIT;
SELECT current_setting('app.tenant', true); -- (빈 값, 트랜잭션 끝나 소멸)
RLS 정책의 조건으로 세션 변수를 그대로 쓴다. (조합: RLS USING)
CREATE POLICY p ON docs USING (tenant = current_setting('app.tenant', true));
내장 세션 정보로 지금 롤·DB·클라이언트 IP를 확인한다. (조합: 내장 함수)
SELECT current_user, current_database(), inet_client_addr();
세션 시작마다 자동 적용되게 롤에 기본값을 박는다. (조합: ALTER ROLE SET)
ALTER ROLE m9_app SET statement_timeout = '5s';
이 쿼리 하나만 타임아웃을 로컬로 조정한다. (조합: SET LOCAL)
BEGIN; SET LOCAL work_mem = '128MB'; -- 무거운 정렬 쿼리 ... COMMIT;
세션에서 만진 커스텀 변수를 되돌린다. (조합: RESET)
RESET app.current_user_id;반응형