# pgvector Extension PostgreSQL 설치 가이드

## 개요
벡터 유사도 검색을 위한 pgvector extension이 포함된 PostgreSQL 데이터베이스 설치 가이드입니다.

---

## 1. 사전 요구사항

### 1.1 필수 확인 사항
- [ ] Kubernetes 클러스터 접속 가능 여부 확인
- [ ] Helm 3.x 이상 설치 확인
- [ ] kubectl 명령어 사용 가능 여부 확인
- [ ] 기본 StorageClass 존재 여부 확인

### 1.2 버전 정보
| 구성요소 | 버전 | 비고 |
|---------|------|------|
| PostgreSQL | 16.x | pgvector 0.5.0 이상 지원 |
| pgvector Extension | 0.5.1+ | 최신 안정 버전 권장 |
| Helm Chart | bitnami/postgresql | pgvector 포함 커스텀 이미지 |

---

## 2. 설치 방법

### 2.1 Kubernetes 환경 (Helm Chart)

#### 2.1.1 개발 환경 (dev)

**Step 1: Namespace 생성**
```bash
kubectl create namespace vector-dev
```

**Step 2: Helm Repository 추가**
```bash
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
```

**Step 3: values.yaml 작성**
```yaml
# values-pgvector-dev.yaml
global:
  postgresql:
    auth:
      postgresPassword: "dev_password"
      username: "vector_user"
      password: "dev_vector_password"
      database: "vector_db"

image:
  registry: docker.io
  repository: pgvector/pgvector
  tag: "pg16"
  pullPolicy: IfNotPresent

primary:
  initdb:
    scripts:
      init-pgvector.sql: |
        -- pgvector extension 활성화
        CREATE EXTENSION IF NOT EXISTS vector;

        -- 설치 확인
        SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';

  resources:
    limits:
      memory: 2Gi
      cpu: 1000m
    requests:
      memory: 1Gi
      cpu: 500m

  persistence:
    enabled: true
    size: 10Gi
    storageClass: ""  # 기본 StorageClass 사용

  service:
    type: ClusterIP
    ports:
      postgresql: 5432

metrics:
  enabled: true
  serviceMonitor:
    enabled: false

volumePermissions:
  enabled: true
```

**Step 4: Helm 설치 실행**
```bash
helm install pgvector-dev bitnami/postgresql \
  --namespace vector-dev \
  --values values-pgvector-dev.yaml \
  --wait
```

**Step 5: 설치 확인**
```bash
# Pod 상태 확인
kubectl get pods -n vector-dev

# 서비스 확인
kubectl get svc -n vector-dev

# pgvector 설치 확인
kubectl exec -it pgvector-dev-postgresql-0 -n vector-dev -- \
  psql -U vector_user -d vector_db -c "SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';"
```

**예상 출력:**
```
 extname | extversion
---------+------------
 vector  | 0.5.1
(1 row)
```

#### 2.1.2 운영 환경 (prod)

**Step 1: Namespace 생성**
```bash
kubectl create namespace vector-prod
```

**Step 2: values.yaml 작성 (고가용성 구성)**
```yaml
# values-pgvector-prod.yaml
global:
  postgresql:
    auth:
      postgresPassword: "CHANGE_ME_PROD_PASSWORD"
      username: "vector_user"
      password: "CHANGE_ME_VECTOR_PASSWORD"
      database: "vector_db"

image:
  registry: docker.io
  repository: pgvector/pgvector
  tag: "pg16"
  pullPolicy: IfNotPresent

architecture: replication  # 고가용성 구성

primary:
  initdb:
    scripts:
      init-pgvector.sql: |
        -- pgvector extension 활성화
        CREATE EXTENSION IF NOT EXISTS vector;

        -- 성능 최적화 설정
        ALTER SYSTEM SET shared_buffers = '2GB';
        ALTER SYSTEM SET effective_cache_size = '6GB';
        ALTER SYSTEM SET maintenance_work_mem = '512MB';
        ALTER SYSTEM SET max_wal_size = '2GB';

        -- pgvector 최적화
        ALTER SYSTEM SET max_parallel_workers_per_gather = 4;

  resources:
    limits:
      memory: 8Gi
      cpu: 4000m
    requests:
      memory: 4Gi
      cpu: 2000m

  persistence:
    enabled: true
    size: 100Gi
    storageClass: ""  # 기본 StorageClass 사용

  podAntiAffinity:
    preset: hard  # Primary와 Replica 분리 배치

readReplicas:
  replicaCount: 2

  resources:
    limits:
      memory: 8Gi
      cpu: 4000m
    requests:
      memory: 4Gi
      cpu: 2000m

  persistence:
    enabled: true
    size: 100Gi

backup:
  enabled: true
  cronjob:
    schedule: "0 2 * * *"  # 매일 새벽 2시 백업
    storage:
      size: 50Gi

metrics:
  enabled: true
  serviceMonitor:
    enabled: true

networkPolicy:
  enabled: true
  allowExternal: false
```

**Step 3: Helm 설치 실행**
```bash
helm install pgvector-prod bitnami/postgresql \
  --namespace vector-prod \
  --values values-pgvector-prod.yaml \
  --wait
```

**Step 4: 설치 확인**
```bash
# 모든 Pod 상태 확인 (Primary + Replicas)
kubectl get pods -n vector-prod

# Replication 상태 확인
kubectl exec -it pgvector-prod-postgresql-0 -n vector-prod -- \
  psql -U postgres -c "SELECT * FROM pg_stat_replication;"
```

---

### 2.2 Docker Compose 환경 (로컬 개발)

**docker-compose.yml**
```yaml
version: '3.8'

services:
  pgvector:
    image: pgvector/pgvector:pg16
    container_name: pgvector-local
    environment:
      POSTGRES_DB: vector_db
      POSTGRES_USER: vector_user
      POSTGRES_PASSWORD: local_password
      POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
    ports:
      - "5432:5432"
    volumes:
      - pgvector_data:/var/lib/postgresql/data
      - ./init-scripts:/docker-entrypoint-initdb.d
    command:
      - "postgres"
      - "-c"
      - "shared_buffers=256MB"
      - "-c"
      - "max_connections=200"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U vector_user -d vector_db"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  pgvector_data:
    driver: local
```

**init-scripts/01-init-pgvector.sql**
```sql
-- pgvector extension 활성화
CREATE EXTENSION IF NOT EXISTS vector;

-- 테스트 테이블 생성 (선택사항)
CREATE TABLE IF NOT EXISTS vector_test (
    id SERIAL PRIMARY KEY,
    content TEXT,
    embedding vector(384)  -- 384차원 벡터 (예시)
);

-- 인덱스 생성 (HNSW - 고성능)
CREATE INDEX ON vector_test
USING hnsw (embedding vector_cosine_ops);

-- 확인 쿼리
SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';
```

**실행 명령**
```bash
# 시작
docker-compose up -d

# 로그 확인
docker-compose logs -f pgvector

# 접속 테스트
docker exec -it pgvector-local psql -U vector_user -d vector_db

# 종료
docker-compose down
```

---

## 3. 설치 검증

### 3.1 Extension 설치 확인
```sql
-- Extension 버전 확인
SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';

-- 지원 연산자 확인
SELECT oprname, oprleft::regtype, oprright::regtype
FROM pg_operator
WHERE oprname IN ('<=>', '<->', '<#>');
```

**예상 결과:**
```
 oprname | oprleft | oprright
---------+---------+----------
 <=>     | vector  | vector
 <->     | vector  | vector
 <#>     | vector  | vector
```

### 3.2 벡터 연산 테스트
```sql
-- 테스트 데이터 삽입
CREATE TABLE test_vectors (
    id SERIAL PRIMARY KEY,
    embedding vector(3)
);

INSERT INTO test_vectors (embedding) VALUES
('[1,2,3]'),
('[4,5,6]'),
('[1,1,1]');

-- 코사인 거리 계산 테스트
SELECT id, embedding, embedding <=> '[1,2,3]' AS cosine_distance
FROM test_vectors
ORDER BY cosine_distance
LIMIT 3;
```

### 3.3 인덱스 성능 테스트
```sql
-- HNSW 인덱스 생성
CREATE INDEX ON test_vectors USING hnsw (embedding vector_cosine_ops);

-- 인덱스 사용 여부 확인
EXPLAIN ANALYZE
SELECT id FROM test_vectors
ORDER BY embedding <=> '[1,2,3]'
LIMIT 10;
```

---

## 4. 연결 정보

### 4.1 Kubernetes 환경

**개발 환경 (cluster 내부)**
```
Host: pgvector-dev-postgresql.vector-dev.svc.cluster.local
Port: 5432
Database: vector_db
Username: vector_user
Password: dev_vector_password
```

**운영 환경 (cluster 내부)**
```
Host: pgvector-prod-postgresql.vector-prod.svc.cluster.local
Port: 5432
Database: vector_db
Username: vector_user
Password: CHANGE_ME_VECTOR_PASSWORD
```

**외부 접속 (Port-Forward)**
```bash
# 개발 환경
kubectl port-forward -n vector-dev svc/pgvector-dev-postgresql 5432:5432

# 운영 환경
kubectl port-forward -n vector-prod svc/pgvector-prod-postgresql 5433:5432
```

### 4.2 Docker Compose 환경
```
Host: localhost
Port: 5432
Database: vector_db
Username: vector_user
Password: local_password
```

---

## 5. Python 연결 예제

### 5.1 필수 라이브러리
```bash
pip install psycopg2-binary pgvector
```

### 5.2 연결 코드
```python
import psycopg2
from pgvector.psycopg2 import register_vector

# 연결
conn = psycopg2.connect(
    host="localhost",
    port=5432,
    database="vector_db",
    user="vector_user",
    password="local_password"
)

# pgvector 타입 등록
register_vector(conn)

# 벡터 검색 예제
cur = conn.cursor()
cur.execute("""
    SELECT id, embedding <=> %s::vector AS distance
    FROM test_vectors
    ORDER BY distance
    LIMIT 5
""", ([1, 2, 3],))

results = cur.fetchall()
for row in results:
    print(f"ID: {row[0]}, Distance: {row[1]}")

cur.close()
conn.close()
```

---

## 6. 트러블슈팅

### 6.1 Extension 설치 실패
```sql
-- 에러: extension "vector" is not available
-- 해결: pgvector 이미지 사용 확인
```
**확인 명령:**
```bash
# Pod의 이미지 확인
kubectl describe pod pgvector-dev-postgresql-0 -n vector-dev | grep Image
```

### 6.2 인덱스 생성 실패
```sql
-- 에러: operator class "vector_cosine_ops" does not exist
-- 해결: Extension 재생성
DROP EXTENSION vector CASCADE;
CREATE EXTENSION vector;
```

### 6.3 성능 이슈
```sql
-- 인덱스 통계 업데이트
ANALYZE test_vectors;

-- HNSW 파라미터 조정 (m=16, ef_construction=64)
CREATE INDEX ON test_vectors
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
```

---

## 7. 보안 권장사항

### 7.1 비밀번호 관리
```bash
# Kubernetes Secret 생성
kubectl create secret generic pgvector-credentials \
  --from-literal=postgres-password='STRONG_PASSWORD' \
  --from-literal=password='STRONG_VECTOR_PASSWORD' \
  -n vector-prod

# values.yaml에서 참조
global:
  postgresql:
    auth:
      existingSecret: "pgvector-credentials"
```

### 7.2 네트워크 정책
```yaml
# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: pgvector-policy
  namespace: vector-prod
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: postgresql
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: vector-prod
    - podSelector:
        matchLabels:
          app: vector-service
    ports:
    - protocol: TCP
      port: 5432
```

---

## 8. 모니터링

### 8.1 Prometheus Metrics (운영 환경)
```yaml
# ServiceMonitor가 활성화된 경우 자동 수집
metrics:
  enabled: true
  serviceMonitor:
    enabled: true
    namespace: monitoring
    interval: 30s
```

### 8.2 주요 메트릭
- `pg_up`: PostgreSQL 가용성
- `pg_database_size_bytes`: 데이터베이스 크기
- `pg_stat_database_tup_fetched`: 조회된 행 수
- `pg_stat_database_conflicts`: 복제 충돌 수

---

## 9. 백업 및 복구

### 9.1 수동 백업
```bash
# Kubernetes 환경
kubectl exec -n vector-prod pgvector-prod-postgresql-0 -- \
  pg_dump -U vector_user vector_db > backup_$(date +%Y%m%d).sql

# Docker Compose 환경
docker exec pgvector-local pg_dump -U vector_user vector_db > backup.sql
```

### 9.2 복구
```bash
# Kubernetes 환경
cat backup.sql | kubectl exec -i pgvector-prod-postgresql-0 -n vector-prod -- \
  psql -U vector_user -d vector_db

# Docker Compose 환경
cat backup.sql | docker exec -i pgvector-local psql -U vector_user -d vector_db
```

---

## 10. 참고 자료

- [pgvector GitHub](https://github.com/pgvector/pgvector)
- [PostgreSQL Documentation](https://www.postgresql.org/docs/16/)
- [Bitnami PostgreSQL Helm Chart](https://github.com/bitnami/charts/tree/main/bitnami/postgresql)
- [pgvector Performance Tips](https://github.com/pgvector/pgvector#performance)

---

## 부록: 차원별 인덱스 권장사항

| 벡터 차원 | 인덱스 타입 | 파라미터 | 비고 |
|----------|-----------|---------|------|
| < 768 | HNSW | m=16, ef_construction=64 | 일반적인 임베딩 |
| 768-1536 | HNSW | m=24, ef_construction=100 | OpenAI ada-002 |
| > 1536 | IVFFlat | lists=100 | 매우 높은 차원 |

**인덱스 선택 가이드:**
- **HNSW**: 검색 속도 우선 (메모리 사용량 높음)
- **IVFFlat**: 메모리 절약 우선 (검색 속도 느림)
