본문으로 건너뛰기

Oracle Database 23ai 벡터 백엔드 운영 가이드

GenD 인제스트 파이프라인은 임베딩을 세 번째 벡터 백엔드인 Oracle Database 23ai AI Vector Search 로 적재할 수 있다. 고객/벤더가 제공한 Oracle 인스턴스에 컬렉션 단위로 테이블을 만들고 VECTOR 컬럼 + 벡터 인덱스로 검색한다.

Oracle 23ai 는 단일 컨버지드 DB

Oracle 23ai 에서 "벡터 DB" 는 별도 제품이 아니라 기능이다. 정형 데이터와 벡터가 같은 인스턴스에 공존하며, GenD 는 동일한 SQL/스키마로 양쪽을 다룬다.

아키텍처 요약

  • OracleVectorBackend 가 기존 VectorBackend ABC 를 구현하고 팩토리 get_vector_backend("oracle") 로 해소된다.
  • python-oracledb thin 모드 비동기 커넥션 풀을 사용한다 — Oracle Client 설치가 필요 없어 슬림/ARM64 컨테이너와 호환된다.
  • 컬렉션 1개당 테이블 1개를 만들고 VECTOR(<dim>, FLOAT32) 컬럼 + IVF(기본) 또는 HNSW 벡터 인덱스를 생성한다.
  • Oracle 는 항상 외부(external) 엔드포인트다 — GenD 에 번들되지 않는다. dev 는 외부 23ai Free 컨테이너, prod 는 벤더 SaaS/매니지드.
  • 임베딩은 GenD 측에서 생성한다(GenOS 임베딩 API). 적재 경로는 동기 IngestionService 와 Dagster upsert_vector 자산 모두 팩토리를 통과하므로 오케스트레이션 코드 변경이 없다.

컬렉션별 Oracle 선택

특정 컬렉션을 Oracle 로 적재하려면 IngestionPolicy.vector_backend_type"oracle" 로 설정한다. 벡터 인덱스 종류는 IngestionPolicy.oracle_index_type (ivf | hnsw | none, 기본 ivf) 로 저장·노출된다.

Pipeline Studio 그래프에서는 builtin.vector 노드의 config.backend"oracle" 로 지정하면 해당 노드만 Oracle 로 라우팅된다(미지정 시 런 기본 Weaviate 백엔드 사용).

백엔드 해소 실패는 원인에 따라 동작이 갈린다.

  • 백엔드 미설정 (config.backend 미지정이고 런 기본 백엔드도 없는 환경, 또는 gend_api 팩토리 자체를 적재할 수 없는 CI/code-server) — 적재를 건너뛰고 upserted=0 으로 기록한다(graceful-skip). 이는 환경 조건이며 런을 실패시키지 않는다.
  • 백엔드 설정됨, 그러나 도달 불가 (예: Oracle 엔드포인트 다운) — upsert 시점에 예외가 전파되어 런이 실패한다(fail-loud). 다운된 싱크를 upserted=0 으로 조용히 기록해 누락을 거짓 성공으로 숨기지 않는다.
  • 백엔드 이름 오타/미지원 (config.backend 가 명시됐지만 팩토리가 거부) — 사용자 오설정으로 보고 런을 즉시 실패시킨다(fail-loud).

필수 환경변수 / Secret

운영에서는 GEND_ORACLE_* 를 Secret 으로 주입한다(기본값 없음).

환경변수의미비고
GEND_ORACLE_DSNEasy Connect host:port/service_name 또는 wallet aliasRAC 는 SID 아님, service_name
GEND_ORACLE_USER전용 스키마 계정
GEND_ORACLE_PASSWORD계정 비밀번호vault_enabled 시 Vault 암호화
GEND_ORACLE_WALLET_DIRTLS/mTLS wallet 디렉터리(ADB)비우면 평문 TCP
GEND_ORACLE_INDEX_TYPE기본 벡터 인덱스(ivf/hnsw/none)기본 ivf
GEND_ORACLE_POOL_MIN비동기 풀 최소 연결기본 1
GEND_ORACLE_POOL_MAX비동기 풀 최대 연결기본 4, ADB Always Free 는 보수적으로

임베딩을 GenOS 서빙으로 보내려면:

환경변수의미
GEND_AI_EMBEDDING_PROVIDER=genosOpenAI 호환 GenOS 임베딩 사용
GEND_GENOS_EMBEDDING_URL예: https://genos.example/v1
GEND_GENOS_EMBEDDING_TOKENGenOS 토큰
GEND_EMBEDDING_DIMENSIONSVECTOR(<dim>) 고정 차원(기본 1536)
차원 정합

GEND_EMBEDDING_DIMENSIONS 는 Oracle VECTOR(<dim>) 컬럼 폭을 결정한다. 임베딩 모델 차원과 다르면 업서트가 차원 불일치로 스킵된다 — 모델 차원과 반드시 일치시킬 것.

벡터 인덱스 종류 (D5)

  • IVF (기본) — 모든 RU 에서 동작하고 DML 친화적이며 자동 재구성된다. 컬렉션 생성 시 ORGANIZATION NEIGHBOR PARTITIONS ... DISTANCE COSINE.
  • HNSWORGANIZATION INMEMORY NEIGHBOR GRAPH. 트랜잭션 일관 DML 은 RU ≥ 23.6 에 의존하며 SGA VECTOR_MEMORY_SIZE 풀(DBA 설정)이 필요하다. 현재 단계에서는 옵션화/Deferred.
  • none — 인덱스를 만들지 않는다(소규모/실험).

헬스 모니터링

GET /api/v1/ingestion/stores/health 는 구성된 각 벡터 백엔드의 도달 가능성을 반환한다. Oracle 의 reachable 은 외부 엔드포인트에 대한 실시간 SELECT 1 FROM dual 결과다. 한 백엔드가 불통이어도 나머지를 가리지 않는다.

{
"weaviate": {"reachable": true},
"milvus": {"reachable": false},
"oracle": {"reachable": true}
}

벤더 산출물 체크리스트 (staging/prod)

"VDB 접속 계정" 만으로는 부족하다. 아래를 벤더에게 요청한다:

  1. 23ai 인스턴스COMPATIBLE ≥ 23.4, RU 버전 명시(IVF 는 23.4+, 추후 HNSW 면 23.6+), 캐릭터셋 AL32UTF8(한글).
  2. 전용 스키마 계정 + 권한: CREATE SESSION, CREATE TABLE, CREATE INDEX(+CREATE VECTOR INDEX), 테이블스페이스 quota.
  3. (HNSW 사용 시) SGA VECTOR_MEMORY_SIZE 풀 설정 — DBA 만 가능.
  4. 접속: host / port / service_name(RAC 면 SID 아님) (+TLS 면 wallet zip 과 비밀번호).
  5. 네트워크 allowlist: GenD AKS egress → Oracle listener 포트.
  6. dev/test 인스턴스 분리 (또는 23ai Free 로 대체).
  7. 예상 벡터 건수 기준 테이블스페이스 용량 협의.
  8. (GenOS 측) 임베딩 모델 차원값VECTOR(<dim>) 고정용.
  9. 벡터 적재 대상이 정형 데이터와 같은 인스턴스인지 벡터 전용 인스턴스인지 — DSN/용량/네트워크 결정용(코드 불변).

dev/prod 패리티

항목devprod
인스턴스외부 23ai Free 컨테이너벤더 SaaS/매니지드(ADB / Database@Azure / Base DB)
접속평문 TCP user/passTLS/mTLS(wallet)
코드동일 OracleVectorBackend/스키마/벡터 SQL동일

게이트된 통합 테스트 실행

apps/api/tests/test_oracle_backend_integration.py 는 실제 23ai 인스턴스 대상 종단 라운드트립 테스트다. GEND_ORACLE_DSN 이 없으면 자동 스킵되며, 일반 CI 에서는 실행되지 않는다.

외부 23ai Free 컨테이너를 띄운다:

docker run -d --name oracle-free -p 1521:1521 \
-e ORACLE_PASSWORD=GendTest123 \
gvenzl/oracle-free:23-slim

전용 앱 계정(CREATE SESSION/TABLE/INDEX + quota)을 만든 뒤 실행한다:

cd apps/api
GEND_ORACLE_DSN=localhost:1521/FREEPDB1 \
GEND_ORACLE_USER=gend GEND_ORACLE_PASSWORD=GendTest123 \
PYTHONPATH=src .venv/bin/python -m pytest \
tests/test_oracle_backend_integration.py -v

테스트는 ensure_collection → 멱등 MERGE 업서트(차원=embedding_dimensions) → JSON_VALUE(metadata, '$.dept') 라운드트립 → VECTOR_DISTANCE 최근접이 결정적 object_id 인지 확인 → delete_by_document_id → health_check → 테이블 DROP 정리까지 검증한다.

식별자 대문자화

컬렉션 이름은 _safe_identifier 가 대문자로 변환한다. 컬렉션 zz_gend_it_xxxx 는 테이블 ZZ_GEND_IT_XXXX 가 되므로 원시 SQL 은 대문자 이름으로 조회한다.