콘텐츠로 이동






07. SQL Script와 Extension 사용

1. 기능 구분

기능 역할
SQL Script 초기 데이터·테이블·권한 SQL 실행 관리
Extension 설정 DB Pod에 확장 파일 준비
CREATE EXTENSION Database별 확장 활성화

Extension은 파일 준비와 Database 활성화를 구분합니다.

SGCluster에 Extension 추가
          ↓
DB Pod에 확장 파일 준비
          ↓
Database에서 CREATE EXTENSION 실행

06번 문서의 appdb·appuser·app Schema를 사용합니다.

2. 변수 설정

export K8S_CONTEXT="$(kubectl config current-context)"
export DB_NAMESPACE="postgres"
export DB_CLUSTER="demo-db-yaml"
export SQL_SCRIPT="${DB_CLUSTER}-app-init"

UI 클러스터는 DB_CLUSTER를 실제 이름으로 바꿉니다.

kubectl --context "$K8S_CONTEXT" get sgcluster "$DB_CLUSTER" \
  --namespace "$DB_NAMESPACE"

3. SQL Script 등록

3.1. 실행 방식

SGScript는 순서가 있는 SQL 목록이며 SGCluster에서 참조합니다.

항목 실행 기준
사용자 postgres
Database 항목별 지정, 생략 시 postgres
실행 방식 Auto-commit
변경 관리 버전이 있는 스크립트

전체 스크립트가 단일 트랜잭션은 아닙니다. 일부 SQL만 성공할 수 있으므로 재실행 영향을 고려합니다.

3.2. SGScript 작성

테이블·초기 데이터·권한을 설정합니다.

cat > 03-app-script.yaml <<EOF
apiVersion: stackgres.io/v1
kind: SGScript
metadata:
  name: ${SQL_SCRIPT}
  namespace: ${DB_NAMESPACE}
spec:
  scripts:
    - name: initialize-app-settings
      database: appdb
      script: |
        CREATE TABLE IF NOT EXISTS app.settings (
            key text PRIMARY KEY,
            value text NOT NULL
        );

        INSERT INTO app.settings (key, value)
        VALUES ('service_name', 'StackGres demo')
        ON CONFLICT (key) DO NOTHING;

        GRANT SELECT, INSERT, UPDATE, DELETE
        ON TABLE app.settings TO appuser;
EOF

postgres로 실행되므로 appuser 권한을 별도로 부여합니다.

kubectl --context "$K8S_CONTEXT" apply \
  -f 03-app-script.yaml

3.3. 클러스터에 연결

SGCluster YAML의 spec에 추가합니다.

spec:
  managedSql:
    scripts:
      - sgScript: demo-db-yaml-app-init

기존 managedSql.scripts는 유지하고 실제 SGScript 이름을 추가합니다.

자동 생성된 <클러스터 이름>-default 스크립트와 참조는 임의로 삭제하지 않습니다.

kubectl --context "$K8S_CONTEXT" apply \
  -f 02-cluster.yaml

SGScript 생성만으로 실행되지 않습니다. SGCluster 참조까지 확인합니다.

3.4. Web UI 사용

  1. SQL Script 관리 화면을 엽니다.
  2. Namespace·이름을 지정합니다.
  3. Database를 appdb로 지정합니다.
  4. SQL을 등록합니다.
  5. 클러스터의 Managed SQL에 연결합니다.

화면 구성은 버전에 따라 다릅니다. 적용 후 YAML·실행 상태를 확인합니다.

4. SQL 실행 결과 확인

관리 SQL 상태를 조회합니다.

kubectl --context "$K8S_CONTEXT" get sgcluster "$DB_CLUSTER" \
  --namespace "$DB_NAMESPACE" \
  -o jsonpath='{.status.managedSql}{"\n"}'

전체 상태는 YAML로 확인합니다.

kubectl --context "$K8S_CONTEXT" get sgcluster "$DB_CLUSTER" \
  --namespace "$DB_NAMESPACE" \
  -o yaml

애플리케이션 계정으로 접속합니다.

kubectl --context "$K8S_CONTEXT" exec -it \
  --namespace "$DB_NAMESPACE" \
  "${DB_CLUSTER}-0" \
  --container postgres-util \
  -- psql \
     -h "${DB_CLUSTER}.${DB_NAMESPACE}" \
     -U appuser \
     -d appdb \
     -W
SELECT * FROM app.settings;

예상 결과입니다.

     key      |     value
--------------+----------------
 service_name | StackGres demo
\q

변경 시 버전·재실행 대상을 확인합니다. 실행 완료된 SQL을 단순 덮어쓰지 않습니다.

5. Extension 추가

5.1. 호환성 확인

계층 경로를 다루는 ltree를 사용합니다. 설치 전 다음을 확인합니다.

  • PostgreSQL 버전에 맞는 패키지
  • StackGres 버전의 지원 여부
  • 추가 설정·사전 로딩 필요 여부
  • 패키지 다운로드 가능 여부

확장별 요구사항을 확인하고 이름만으로 사용 가능하다고 가정하지 않습니다.

5.2. SGCluster 설정

기존 postgres 설정에 확장을 추가합니다.

spec:
  postgres:
    version: "<기존 PostgreSQL 버전>"
    extensions:
      - name: ltree

기존 PostgreSQL 버전·Extension 목록은 유지합니다.

kubectl --context "$K8S_CONTEXT" apply \
  -f 02-cluster.yaml

Web UI에서는 클러스터 편집 화면의 Extension 항목에 추가합니다.

변경 후 Pod 상태를 확인합니다.

kubectl --context "$K8S_CONTEXT" get pods \
  --namespace "$DB_NAMESPACE"

6. Database에서 Extension 활성화

6.1. 관리자 접속

postgres로 appdb에 접속합니다.

kubectl --context "$K8S_CONTEXT" exec -it \
  --namespace "$DB_NAMESPACE" \
  "${DB_CLUSTER}-0" \
  --container postgres-util \
  -- psql \
     -h "${DB_CLUSTER}.${DB_NAMESPACE}" \
     -U postgres \
     -d appdb \
     -W

확장 파일 준비 여부를 확인합니다.

SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE name = 'ltree';

목록에 있으면 활성화합니다.

CREATE EXTENSION IF NOT EXISTS ltree WITH SCHEMA public;

설치 버전·Schema를 확인합니다.

SELECT e.extname, e.extversion, n.nspname
FROM pg_extension e
JOIN pg_namespace n ON n.oid = e.extnamespace
WHERE e.extname = 'ltree';

6.2. 동작 확인

SELECT 'company.platform.database'::public.ltree;

SELECT
    'company.platform.database'::public.ltree
    OPERATOR(public.<@)
    'company.platform'::public.ltree
    AS is_descendant;

is_descendant가 true인지 확인합니다.

public에 설치했으므로 타입·연산자에 Schema를 명시합니다.

\q

활성화는 Database별 작업입니다. 다른 Database에서도 별도로 실행합니다.

7. SGScript로 Extension 활성화

수동 검증 후 기존 SGScript에 추가할 수 있습니다.

spec:
  scripts:
    # 기존 SQL 항목 유지
    - name: enable-ltree
      database: appdb
      script: |
        CREATE EXTENSION IF NOT EXISTS ltree WITH SCHEMA public;

진행 순서입니다.

  1. SGCluster에 Extension 선언
  2. 확장 파일 준비 확인
  3. SGScript로 CREATE EXTENSION 실행
  4. Database에서 결과 확인

SGScript는 확장 파일을 다운로드·설치하지 않습니다.

8. 오류 확인

증상 확인 항목
SQL 미실행 SGCluster 참조·Namespace·실행 상태
Database 없음 실행 Database·생성 여부
SQL 일부만 반영 Auto-commit·실패 지점
appuser 권한 오류 테이블 소유자·GRANT
Extension 목록에 없음 지원 패키지·파일 준비
CREATE EXTENSION 실패 권한·의존성·추가 설정
Extension 변경 후 Pod 오류 패키지 다운로드·컨테이너 로그

Event를 확인합니다.

kubectl --context "$K8S_CONTEXT" get events \
  --namespace "$DB_NAMESPACE" \
  --sort-by=.metadata.creationTimestamp
  • *재실행을 위해 테이블·기본 스크립트를 임의로 삭제하면 안됩니다