데이터베이스 관리
데이터베이스 구성
PlantPulse AI는 6개의 데이터베이스를 사용하며, 각각 다른 목적으로 활용됩니다.
| 데이터베이스 | 용도 | 데이터 유형 |
|---|---|---|
| PostgreSQL | 관계형 메타데이터 | 사용자 정보, 채팅 이력, RAG 메타, 피처 스토어 |
| Aster TSDB | 시계열 저장 | 센서 데이터, 코파일럿 태스크, 추론 히스토리 |
| Neo4j (두 인스턴스) | 그래프 데이터 | LightRAG 지식 그래프 · 디지털 스레드의 공장 그래프 거울 |
| Qdrant | 벡터 저장 | 문서 임베딩, 설비 피처 벡터 |
| Valkey (Redis) | 캐시 | 세션, 임시 데이터, 검색 캐시 |
| RustFS | 오브젝트 저장 | 문서 파일, 이미지, 보고서 |
PostgreSQL
데이터베이스 목록
AI 는 자기 PostgreSQL 을 띄우지 않고 플랫폼의 PostgreSQL 안에 네 DB 를 만들어 씁니다
(provision-platform-db.sh 가 없으면 만들고 있으면 넘어갑니다 — 멱등).
| 데이터베이스 | 사용 서비스 |
|---|---|
pi | AI 앱의 DB — 앱마다 스키마 하나: co = AI Chat Web(사용자·채팅 이력·앱·설정), dt = 디지털 스레드(커넥터 등록부) |
lightrag | LightRAG 의 문서 처리 상태(doc_status) |
rag_ingest | 문서 적재 파이프라인(rag-api)의 상태. 도면 · 영상 수집을 켜면 그 표(rag_drawing_* · rag_media_*)도 여기에 기동 때 만들어집니다 |
litellm | LiteLLM 게이트웨이의 키·사용량 |
접속 계정은 플랫폼 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 이 모두 같은 순서를 밟으므로 따로 부를 일은 없습니다.
- 코파일럿·디지털 스레드 컨테이너를 멈춥니다.
ch에 남은 세션을 정리합니다 —ch에 붙은 앱 계정(PP_PG_USER) 세션만 끊습니다.- 한 트랜잭션으로
public의 객체를 새 스키마co로 옮깁니다. 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
키스페이스
| 키스페이스 | 용도 |
|---|---|
pi | PlantPulse 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-neo4j | LightRAG 지식 그래프 | pi-neo4j-data | 7474 · 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 URL | http://<서버IP>:7474 |
| Bolt URI | bolt://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 API | http://127.0.0.1:6333 |
| Dashboard | http://127.0.0.1:6333/dashboard |
| API Key | qdrant-key-123 |
컬렉션
| 컬렉션 | 용도 |
|---|---|
| (LightRAG 자동 생성) | RAG 문서 벡터 (LightRAG가 관리) |
RustFS
접속 정보
| 항목 | 값 |
|---|---|
| API | http://127.0.0.1:9000 |
| Console | http://127.0.0.1:9001 |
| Access Key | minio |
| Secret Key | minio123! |
버킷
| 버킷 | 용도 |
|---|---|
plantpulse-rag | rag-api 의 객체 저장소 하나. 접두사로 가릅니다 — manual/ 관리 콘솔에서 손으로 올린 문서 원본, drawings/ 도면 구조와 쪽 미리보기(도면 수집을 켰을 때), media/ 영상·음성 재생본과 녹취(영상 수집을 켰을 때), migration/ 옛 버킷 이전 완료 표식. 버킷 이름은 compose 기본값이고, 같은 플랫폼을 AI 설치 둘이 함께 쓸 때만 두 번째 설치에 호스트 env RAG_S3_BUCKET 으로 다른 이름을 줍니다 → 환경 변수 설정 |
예전 판은 손으로 올린 원본을 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-storage | LightRAG KV 캐시(로컬 JSON) | 재생성 가능 |
pi-qdrant-data | 문서 임베딩 벡터 | 원본에서 재생성 가능 |
pi-neo4j-data | LightRAG 지식 그래프 | 원본에서 재생성 가능 |
pi-digital-thread-neo4j-data | 디지털 스레드의 공장 그래프 거울 | 원천에서 재구축 가능 — 다만 플랫폼 사건을 다시 읽어야 하므로 복원이 훨씬 빠르다 |
pi-ttm-tuned-models | 현장 데이터로 설치별로 학습한 시계열 모델 | 그 현장 데이터 없이는 다시 만들 수 없다 |
pi-pp-proxy-certs | 프록시의 TLS 인증서 | 고객이 넣은 실제 인증서라면 다시 받아야 한다 |
pi-phoenix-data | LLM 호출 트레이스 | 지난 트레이스가 사라진다 |
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_DAYS | 30 | 그보다 오래된 날짜 디렉터리를 지운다 — 그 회차가 전부 성공했을 때만 |
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 는 플랫폼 것이므로 이 스크립트가 받지 않습니다 — 플랫폼의 백업 절차를 따릅니다.
백업 권장사항
| 대상 | 방법 | 주기 |
|---|---|---|
| PostgreSQL | pg_dump | 일 1회 |
| Neo4j | neo4j-admin dump | 일 1회 |
| RustFS | rc mirror | 일 1회 |
| Qdrant | Snapshot API | 주 1회 |
/etc/kopens/plantpulse-ai.env | 파일 복사 — 🔴 PI_LITELLM_SALT_KEY 가 여기 있습니다 | 변경 시 |
| AI 로컬 볼륨 | bin/backup.sh (위) | 일 1회 |