본문으로 건너뛰기

데이터베이스 관리

데이터베이스 구성​

PlantPulse AI는 6개의 데이터베이스를 사용하며, 각각 다른 목적으로 활용됩니다.

데이터베이스용도데이터 유형
PostgreSQL관계형 메타데이터사용자 정보, 채팅 이력, RAG 메타, 피처 스토어
Aster TSDB시계열 저장센서 데이터, 코파일럿 태스크, 추론 히스토리
Neo4j (두 인스턴스)그래프 데이터LightRAG 지식 그래프 · 디지털 스레드의 공장 그래프 거울
Qdrant벡터 저장문서 임베딩, 설비 피처 벡터
Valkey (Redis)캐시세션, 임시 데이터, 검색 캐시
RustFS오브젝트 저장문서 파일, 이미지, 보고서

PostgreSQL​

데이터베이스 목록​

AI 는 자기 PostgreSQL 을 띄우지 않고 플랫폼의 PostgreSQL 안에 네 DB 를 만들어 씁니다 (provision-platform-db.sh 가 없으면 만들고 있으면 넘어갑니다 — 멱등).

데이터베이스사용 서비스
piAI 앱의 DB — 앱마다 스키마 하나: co = AI Chat Web(사용자·채팅 이력·앱·설정), dt = 디지털 스레드(커넥터 등록부)
lightragLightRAG 의 문서 처리 상태(doc_status)
rag_ingest문서 적재 파이프라인(rag-api)의 상태. 도면 · 영상 수집을 켜면 그 표(rag_drawing_* · rag_media_*)도 여기에 기동 때 만들어집니다
litellmLiteLLM 게이트웨이의 키·사용량

접속 계정은 플랫폼 PG 의 계정(PP_PG_USER)입니다 — AI 전용 계정이 따로 있지 않습니다. pi 의 두 스키마도 이 계정으로 붙습니다. 표를 public 에 두지 않습니다.

2026.09 이하에서 올리면 — ch 가 pi.co 로 옮겨집니다​

2026.09 이하는 코파일럿 표가 DB ch 의 public 에 있었습니다. 2026.10 은 기동할 때 bin/migrate-pg-ch-to-pi.sh 가 compose 보다 먼저 돌아 이것을 옮깁니다 — install · up · update · compose-up 이 모두 같은 순서를 밟으므로 따로 부를 일은 없습니다.

  1. 코파일럿·디지털 스레드 컨테이너를 멈춥니다.
  2. ch 에 남은 세션을 정리합니다 — ch 에 붙은 앱 계정(PP_PG_USER) 세션만 끊습니다.
  3. 한 트랜잭션으로 public 의 객체를 새 스키마 co 로 옮깁니다.
  4. ALTER DATABASE ch RENAME TO pi.
상태동작
pi 만 있음 · 둘 다 없음할 일 없음
ch 만 있음위 순서대로 이전
ch 와 pi 가 둘 다 있음거절하고 아무것도 바꾸지 않습니다
ch 의 public 과 co 양쪽에 객체가 있음거절(손으로 반쯤 옮긴 흔적)
cd /opt/kopens/plantpulse-ai-docker
bin/migrate-pg-ch-to-pi.sh --check # 미리 보기 — 아무것도 바꾸지 않습니다
bin/migrate-pg-ch-to-pi.sh --rollback # 되돌리기 — pi.co → ch.public, 이름을 ch 로
이전 스크립트는 덤프를 뜨지 않습니다

업그레이드 전에 ch 를 pg_dump 로 한 번 떠 두십시오. 플랫폼 PG 의 디스크·보존은 플랫폼 소관이라 이 스크립트가 대신하지 않습니다. 되돌린 뒤에는 이전 판의 compose 와 코파일럿 이미지로 띄워야 합니다 — 새 compose 로 띄우면 곧바로 다시 이전합니다.

관리​

# PostgreSQL 접속 — 코파일럿 스키마
psql -h <플랫폼 PG 호스트> -U <PP_PG_USER> -d pi -c 'SET search_path TO co' -c '\dt'

# 디지털 스레드 스키마
psql -h <플랫폼 PG 호스트> -U <PP_PG_USER> -d pi -c '\dt dt.*'

# 데이터베이스 목록 확인
psql -h <플랫폼 PG 호스트> -U <PP_PG_USER> -c '\l'

Aster TSDB​

키스페이스​

키스페이스용도
piPlantPulse AI 메인 (코파일럿 태스크, 추론 히스토리)

관리​

# Cassandra CQL 접속
cqlsh 127.0.0.1 9042 -u cassandra -p cassandra

# 키스페이스 목록
DESCRIBE KEYSPACES;

# 테이블 목록
USE pi;
DESCRIBE TABLES;
정보

Aster TSDB 키스페이스는 최초 시작 시 db/cassandra/support/keyspace-create.sh 스크립트로 자동 생성됩니다.


Neo4j​

2026.10 부터 Neo4j 가 둘 뜹니다. 같은 이미지이고 계정(PI_NEO4J_USER · PI_NEO4J_PASSWORD)도 같지만, 담는 것과 여는 자리가 다릅니다.

컨테이너담는 것볼륨호스트 포트
plantpulse-neo4jLightRAG 지식 그래프pi-neo4j-data7474 · 7687
plantpulse-digital-thread-neo4j디지털 스레드의 공장 그래프 거울(Dt*) — 참조만, 본문 없음pi-digital-thread-neo4j-data없음

Neo4j Community 는 DB 를 더 만들거나 역할로 권한을 가를 수 없어서, 두 서비스를 확실히 떼어 놓으려고 인스턴스를 나눴습니다. 디지털 스레드 쪽은 디지털 스레드 API 만 compose 네트워크 안에서 붙고, 메모리 상한 (힙 512 MB · 페이지 캐시 256 MB)이 걸려 있습니다.

비밀번호는 bin/passwd.sh 가 두 인스턴스를 함께 바꿉니다

계정이 하나이므로 한쪽만 바꾸지 마십시오 → 비밀번호 · API 키 변경

접속 정보 — plantpulse-neo4j​

항목값
Browser URLhttp://<서버IP>:7474
Bolt URIbolt://127.0.0.1:7687
사용자neo4j
비밀번호neo4j123

관리​

Neo4j Browser(http://<서버IP>:7474)에서 Cypher 쿼리로 그래프를 관리합니다:

// 노드 타입별 카운트
MATCH (n) RETURN labels(n), count(n) ORDER BY count(n) DESC;

// 관계 타입별 카운트
MATCH ()-[r]->() RETURN type(r), count(r) ORDER BY count(r) DESC;

디지털 스레드 쪽 — plantpulse-digital-thread-neo4j​

포트가 열려 있지 않으므로 Browser 로는 못 들어갑니다. 상태는 관리 콘솔의 디지털 스레드 → 그래프 거울 화면(Neo4j 탐침 · 라벨별 노드 수)에서 봅니다. 거울은 원천(플랫폼 원장 · 사건)에서 다시 만들 수 있는 사본입니다 → 디지털 스레드


Qdrant​

접속 정보​

항목값
REST APIhttp://127.0.0.1:6333
Dashboardhttp://127.0.0.1:6333/dashboard
API Keyqdrant-key-123

컬렉션​

컬렉션용도
(LightRAG 자동 생성)RAG 문서 벡터 (LightRAG가 관리)

RustFS​

접속 정보​

항목값
APIhttp://127.0.0.1:9000
Consolehttp://127.0.0.1:9001
Access Keyminio
Secret Keyminio123!

버킷​

버킷용도
plantpulse-ragrag-api 의 객체 저장소 하나. 접두사로 가릅니다 — manual/ 관리 콘솔에서 손으로 올린 문서 원본, drawings/ 도면 구조와 쪽 미리보기(도면 수집을 켰을 때), media/ 영상·음성 재생본과 녹취(영상 수집을 켰을 때), migration/ 옛 버킷 이전 완료 표식. 버킷 이름은 compose 기본값이고, 같은 플랫폼을 AI 설치 둘이 함께 쓸 때만 두 번째 설치에 호스트 env RAG_S3_BUCKET 으로 다른 이름을 줍니다 → 환경 변수 설정
2026.10 이전의 rag-manual-docs 는 저절로 옮겨집니다

예전 판은 손으로 올린 원본을 rag-manual-docs 버킷에 두었습니다. 2026.10 의 rag-api 는 기동할 때 뒤에서 그 객체를 plantpulse-rag 의 manual/ 아래로 복사합니다. 새 자리에 이미 있으면 덮지 않고, 옛 버킷은 읽기만 하므로 옛 이미지로 되돌려도 그대로 읽힙니다. 진행 상태는 rag-api /api/v1/config 의 object_store_migration 항목에서 봅니다.


데이터 저장 경로​

AI 스택의 로컬 상태는 호스트 디렉토리가 아니라 이름 붙은 도커 볼륨에 있습니다. 호스트에서 경로로 찾으려 하지 마십시오 — docker volume inspect 로 봅니다.

볼륨내용잃으면
pi-lightrag-inputs업로드된 원본 문서색인을 재생성할 방법이 없다
pi-lightrag-storageLightRAG KV 캐시(로컬 JSON)재생성 가능
pi-qdrant-data문서 임베딩 벡터원본에서 재생성 가능
pi-neo4j-dataLightRAG 지식 그래프원본에서 재생성 가능
pi-digital-thread-neo4j-data디지털 스레드의 공장 그래프 거울원천에서 재구축 가능 — 다만 플랫폼 사건을 다시 읽어야 하므로 복원이 훨씬 빠르다
pi-ttm-tuned-models현장 데이터로 설치별로 학습한 시계열 모델그 현장 데이터 없이는 다시 만들 수 없다
pi-pp-proxy-certs프록시의 TLS 인증서고객이 넣은 실제 인증서라면 다시 받아야 한다
pi-phoenix-dataLLM 호출 트레이스지난 트레이스가 사라진다
pi-registry-data로컬 이미지 레지스트리 (registry 프로필을 켠 노드만)이미지를 다시 넣어야 한다
pi-asr-audio녹취 서빙이 읽는 오디오 라이브러리 (영상 · 음성을 켠 설치만)잃을 것이 없다 — plantpulse-asr-audio 가 기동할 때마다 다시 쓴다

bin/backup.sh 가 받는 것​

compose 파일에 선언된 볼륨 전부를 받습니다 — 목록을 따로 적지 않습니다. 빼는 것은 다시 만들 수 있는 로그와 캐시(copliot-web-logs · insight-api-logs · llm-cache · emb-cache · rerank-cache · asr-cache)와, 기동할 때마다 다시 만들어지는 녹취 오디오 라이브러리(asr-audio)뿐입니다. registry-data 는 그 프로필을 켠 노드에만 있으므로, 있으면 받고 없으면 건너뜁니다.

cd /opt/kopens/plantpulse-ai-docker/bin
./backup.sh --list # 볼륨마다 backup · optional · exclude 판정만 찍는다
./backup.sh # 전부 → /data1/pp-backup/YYYYMMDD/<볼륨>.tar.gz
COMPONENT=neo4j-data ./backup.sh # 하나만
손잡이기본값뜻
BACKUP_ROOT/data1/pp-backup백업을 둘 곳
BACKUP_RETENTION_DAYS30그보다 오래된 날짜 디렉터리를 지운다 — 그 회차가 전부 성공했을 때만
예전에는 넷만 받았습니다

2026.09 이전의 backup.sh 는 손으로 적은 네 볼륨(neo4j-data · qdrant-data · lightrag-storage · lightrag-inputs)만 받았고, TLS 인증서 볼륨이 빠져 있었습니다. 지금은 compose 에서 목록을 뽑으므로 볼륨이 새로 생기면 기본으로 백업됩니다.

돌고 있는 채로 뜬 백업은 완전히 일관되지 않을 수 있습니다

쓰는 도중의 사본이 될 수 있습니다. 업그레이드 직전처럼 일관된 백업이 필요하면 bin/compose-down.sh 로 내린 뒤 돌리십시오. 복원도 compose 를 내린 상태에서 합니다(예시는 bin/backup.sh 머리말에 있습니다).

PostgreSQL · Aster TSDB · Redis · RustFS 는 플랫폼 것이므로 이 스크립트가 받지 않습니다 — 플랫폼의 백업 절차를 따릅니다.


백업 권장사항​

대상방법주기
PostgreSQLpg_dump일 1회
Neo4jneo4j-admin dump일 1회
RustFSrc mirror일 1회
QdrantSnapshot API주 1회
/etc/kopens/plantpulse-ai.env파일 복사 — 🔴 PI_LITELLM_SALT_KEY 가 여기 있습니다변경 시
AI 로컬 볼륨bin/backup.sh (위)일 1회