환경
Hypervisor : VMware Workstation
Guest: RHEL 8(Minimal Install
DBMS: PostgreSQL 15.8
리소스: 4GB RAM, 2 Core CPU, 20GB 외장 SSD 할당
작업순서
1. 리눅스 OS 사전 설정
2. PostgreSQL 전용 계정 및 디렉터리 구성
3. 소스 코드 다운로드 및 컴파일(Make)
4. 환경변수 등록 및 DB 클러스터 초기화(initdb)
5. DB 서버 기동 및 외부 접속 환경 구성
6. 원격 접속 테스트
7. 장애 분석 및 인덱스 실습
8. 정기 리포트용 시스템 모니터링 모듈 설정 (pg_stat_statements)
리눅스 OS 사전 설정
- 패키지 최신화
- dnf update -y
- 시스템 시간대 서울로 변경
- timedatectl set-timezone Asia/Seoul
- 소스 컴파일을 위한 필수 의존성 패키지 설치
- dnf install -y gcc make readline-devel zlib-devel tar wget vim
- 방화벽 설정
- firewall-cmd --permanent --add-port=5432/tcp
- firewall-cmd -reload
PostgreSQL 전용 계정 및 디렉터리 구성
- postgres 유저 생성 및 비밀번호 설정
- useradd postgres
- passwd postgres -- 입력할 때 화면에 비밀번호 안나옴
- 데이터베이스 저장용 디렉터리 생성 및 소유권 변경
- mkdir -p /pgdata/15/data
- chown -R postgres:postgres /pgdata
소스 코드 다운로드 및 컴파일(Make)
- 소스 코드 다운로드 및 압축 해제
- cd /usr/local/src
- wget https://ftp.postgresql.org/pub/source/v15.8/postgresql-15.8.tar.gz
- tar -zxvf postgresql-15.8.tar.gz
- configure
- cd postgresql-15.8
- ./configure --prefix=/usr/local/pgsql
- make
- make
- make install
환경변수 등록 및 DB 클러스터 초기화 (initdb)
- 계정 전환
- su - postgres
- 환경변수 등록
- echo 'export PATH=/usr/local/pgsql/bin:$PATH' >> ~/.bash_profile
- echo 'export PGDATA=/pgdata/15/data' >> ~/.bash_profile
- source ~/.bash_profile
- 데이터베이스 클러스터 초기화
- initdb -D /pgdata/15/data
DB 서버 기동 및 외부 접속 환경 구성
- DB 서버 기동
- pg_ctl start -l /pgdata/15/data/pg.log
- postgresql.conf 수정 (IP 접근 허용)
- vi /pgdata/15/data/postgresql.conf
# listen_addresses = 'localhost' 부분을 찾아 허용 IP로 변경 * 로하면 모두 허용
- pg_hba.conf 수정 (클라이언트 인증 규칙 추가)
- vi /pgdata/15/data/pg_hba.conf
# host all all 0.0.0.0/0 scram-sha-256
- 외부 접속용 비밀번호 설정 및 재기동
- psql
- postgres=# 프롬프트 진입
- SET password_encryption = 'scram-sha-256';
- ALTER USER postgres WITH PASSWORD '비밀번호';
- \q
원격 접속 테스트
- 리눅스 터미널에서 ip a 명령어를 통해 가상머신의 ip를 확인 후 호스트 pc로 접속 테스트
- host : 가상머신 IP 주소
- Port : 5432
- database / username : postgres
- password : 설정한 비밀번호
장애 분석 및 인덱스 실습
CREATE TABLE perf_test (
id SERIAL PRIMARY KEY,
user_name VARCHAR(50),
reg_date TIMESTAMP DEFAULT now()
);
INSERT INTO perf\_test (user\_name, reg\_date)
SELECT 'user\_' || seq, now() - (seq || ' seconds')::interval
FROM generate\_series(1, 1000000) seq;
-- [튜닝 전] 인덱스가 없을 때 (Seq Scan 발생)
EXPLAIN ANALYZE
SELECT * FROM perf_test WHERE user_name = 'user_777777';
-- 결과: 테이블 전체를 풀 스캔하며 수십~수백 ms 소요
-- [인덱스 생성]
CREATE INDEX idx_perf_test_username ON perf_test(user_name);
-- [튜닝 후] 인덱스 적용 확인 (Index Scan 발생)
EXPLAIN ANALYZE
SELECT * FROM perf_test WHERE user_name = 'user_777777';
-- 결과: 인덱스를 타면서 실행 시간(Execution Time)이 0.1ms 수준으로 단축
정기 리포트용 시스템 모니터링 모듈 설정 (pg_stat_statements)
- 리눅스 root 계정에서 확장 모듈 컴파일 및 설치
su - root
cd /usr/local/src/postgresql-15.8/contrib/pg_stat_statements
make
make install
- postgres 계정으로 돌아와 환경 설정 파일에 모듈 사전 적재 등록
su - postgres
vi /pgdata/15/data/postgresql.conf
# 주석 해제 및 추가: shared_preload_libraries = 'pg_stat_statements'
- DB 재시작
pg_ctl restart
- 재기동 후 악성 쿼리 조회
-- 확장 활성화
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- 슬로우 쿼리 리포트 추출
SELECT query, calls, total_exec_time, rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 5;
댓글