2026/07/29

, , ,

Teldrive, 1.6.x에서 1.8.x 업데이트 삽질기(Oracle PostgreSQL)

Teldrive, 1.6.x에서 1.8.x 업데이트 삽질기(Oracle PostgreSQL)

하루 종일 Teldrive 1.8.3 업데이트에 매달렸다. DB 마이그레이션 오류로 고생했지만, AI 도움으로 SQL 수동 패치 후 해결! VPS까지 업데이트하니 검색 속도가 수십 초→수초로 확 줄고 Everything 색인도 빨라짐. 삽질 끝에 성능 업데이트 성공! 😎

AI 믿고 업데이트 강행!

Teldrive를 무제한 클라우드로 활용한 지도 어느덧 2년이 훌쩍 지났다. 그러던 차에, 얼마 전 윈도우 만능 검색 도구인 에브리씽(Everything)에 뭔가 문제가 생겼는지, Rclone으로 마운트한 Teldrive 전체를 다시 색인할 일이 생겼다. 그런데 그 어마어마한 데이터양도 문제지만, 색인 속도가 너무 처참했다. 이때 문득 떠오른 생각!

‘teldrive를 업데이트하면 색인 속도가 빨라질까?’

최신 버전이 1.8.3임을 고려하면, 내가 사용 중인 1.6.3 버전은 유통 기한이 만료된 구버전이나 다름없다. 하지만, IT 쪽은 ‘잘 작동하면, 굳이 건드리지 않는다’라는 다소 보수적인 관리 원칙이 존재한다. 내가 윈도우 업데이트를 하지 않는 것처럼 말이다. DB 역시 괜히 잘못 건드렸다가 꼬이기 시작하면 엄청 골치 아파진다는 것을 예전 teldrive 업데이트 때 한 번 경험한 적이 있었기 때문에 망설여졌지만, 이젠 AI라는 든든한 조수가 있고, AI의 분석에 의하면, 1.8.3 버전으로 업데이트하면 색인/검색 속도 향상이 있다고 하니, 큰맘 먹고 시도해 봤다.

잠깐! 업데이트 전에 DB 백업은 필수!!!

첫 번째 난관, users 테이블에 Primary Key가 없다

마음의 준비는 했지만, 역시나 DB 마이그레이션과 관련해서 문제가 생겼다.

2026-07-28 13:19:34 ✗ ERROR [APP] failed to migrate database error=ERROR 20251007120000_kv.sql: failed to run SQL migration: failed to execute SQL query "CREATE TEMP TABLE bots_temp AS\nSELECT DISTINCT ON (user_id, token)\n user_id,\n token,\n bot_id\nFROM\n teldrive.bots\nORDER BY\n user_id, token, bot_id;\nDROP TABLE teldrive.bots;\nCREATE TABLE teldrive.bots (\n\tuser_id int8 NOT NULL,\n\ttoken text NOT NULL,\n\tbot_id int8 NOT NULL,\n\tCONSTRAINT bots_pkey PRIMARY KEY (user_id, token),\n\tCONSTRAINT bots_user_id_fkey FOREIGN KEY (user_id) REFERENCES teldrive.users(user_id)\n);\nINSERT INTO teldrive.bots (user_id, token, bot_id)\nSELECT user_id, token, bot_id FROM bots_temp;\nCREATE TABLE IF NOT EXISTS teldrive.kv (\n key text PRIMARY KEY,\n value BYTEA NOT NULL,\n created_at TIMESTAMP DEFAULT timezone('utc'::text, now()) NOT NULL\n);": ERROR: there is no unique constraint matching given keys for referenced table "users" (SQLSTATE 42830)

1.6.19 버전까진 문제없이 실행되었고, 1.7.0 버전 실행에서도 같은 문제가 생겼다.

AI에 의하면, 이 오류는 업데이트를 포기해야 할 정도로 치명적인 문제는 아니지만, 데이터베이스 구조의 미묘한 차이 때문에 발생한 것이라고 한다. 에러 메시지를 해석해 보면, Teldrive 1.8.3이 bots 테이블을 새로 만들면서 users 테이블의 user_id 칼럼을 참조(Foreign Key)하려고 하는데, 현재 DB의 users 테이블에는 user_id 칼럼에 대한 고유(Unique) 제약 조건이 없어서 참조를 걸 수 없다는 뜻이다.

내가 보기에, 이건 순전히 teldrive 버그다. 왜냐하면 구버전 DB를 새버전 DB로 마이그레이션을 해줘야 하는데, 그걸 사용자가 직접 하게 만들었으니 말이다.

해결 방법은 pgAdmin이나 DBeaver 같은 SQL DB 관리 도구에서 아래의 SQL 쿼리를 순서대로 실행해 주면 된다(제미나이 3.1 프로).

DELETE FROM teldrive.users a USING teldrive.users b

WHERE a.ctid < b.ctid AND a.user_id = b.user_id;
ALTER TABLE teldrive.users ADD PRIMARY KEY (user_id);

두 번째 난관, 업로드 실패

이후 root 폴더가 사라지는 등 몇 가지 우여곡절이 있었으면, 아무튼 이 조치로 1.8.3 업데이트는 순조롭게 마무리되는 것 같았다. 하지만, 다운로드나 동영상 재생은 되는데, 파일 업로드가 안 되었다. 오류 코드 중 핵심 문구는 다음과 같다.

error=ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification (SQLSTATE 42P10)

ERROR [API] request.failed error=ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification (SQLSTATE 42P10)

AI에 의하면, 이 오류는 데이터베이스에 필요한 고유 제약 조건(Unique Constraint)이 없어서 발생한 것이라고 한다. 아마도 1.7.0 이후 버전은 파일 업로드 시 ON CONFLICT 구문을 사용해 같은 이름의 파일이 있으면 업데이트하고, 없으면 새로 추가하는 방식으로 동작하는 듯하다. 이 구문이 정상 작동하려면 files 테이블에 (name, parent_id, user_id) 세 가지 칼럼을 묶은 고유 제약 조건(Unique Constraint)이 반드시 정의되어 있어야 하는데, 1.6.x 버전 데이터베이스에는 이 제약 조건이 빠져 있어, 업로드 시 오류가 발생했다. 이 문제는 아래 SQL 쿼리를 순서대로 실행하면 해결된다(딥시크).

SELECT
name,
COALESCE(parent_id, '00000000-0000-0000-0000-000000000000'::uuid) as parent_id,
user_id,
COUNT(*)
FROM teldrive.files
GROUP BY name, COALESCE(parent_id, '00000000-0000-0000-0000-000000000000'::uuid), user_id
HAVING COUNT(*) > 1;

CREATE UNIQUE INDEX CONCURRENTLY unique_file_active
ON teldrive.files (name, COALESCE(parent_id, '00000000-0000-0000-0000-000000000000'::uuid), user_id)
WHERE status = 'active';

ALTER INDEX unique_file_active RENAME TO unique_file;

세 번째 난관, 완전히 해결되지 않은 업로드 문제

이후 업로드는 되었지만, 로그에 아래와 같은 오류가 여전히 나타났다.

error=ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification (SQLSTATE 42P10)

files 테이블은 해결되었지만, kv 테이블에도 동일한 제약 조건(KET에 대한 고유성)이 누락되어 있었다. kv 테이블은 Teldrive가 세션 정보, 임시 설정, 기타 Key-Value 데이터를 저장하는 데 사용하는 중요한 테이블이다. 지금은 이 오류를 무시하고 업로드가 가능하지만, 앞으로 로그인 유지, 봇 세션 갱신, 설정 저장 등에서 문제가 생길 수 있으므로 해결해야만 하는 오류다.

이 오류는 다음 쿼리를 순서대로 실행하면 해결할 수 있다(딥시크).

key 값이 중복된 데이터가 있는지 확인. 제대로 된 DB라면 아무 값도 출력되지 않는다

SELECT key, COUNT(*) FROM teldrive.kv GROUP BY key HAVING COUNT(*) > 1;

ALTER TABLE teldrive.kv ADD PRIMARY KEY (key);

네 번째 난관, 채널 변경 오류

업로드 문제 해결 이후, 잘 쓰다가 채널 변경이 안 된다. 아마 이것이 이번 대장정의 마지막 난관이지 않을까 싶다.

참고로 1.6.3에서 1.8.3까지 업데이트 로그 중 반드시 확인해야 할 사항은 특정 채널이 가득 차면 자동으로 다음 채널로 넘어가는 기능(v1.7.0)이다. Telegram 공식 제한이 약 채널당 파일 수 제한은 100만 개라고는 하지만, 실제로 70~80만 개만 넘어가도 Teldrive가 파일 목록을 불러오거나 동기화할 때 눈에 띄게 느려지기 시작한다고 한다. 고로 채널당 파일 수는 30만 개 이하로 유지할 것을 추천.

채널 변경 오류와 한 줄 해결법은 아래 참고(딥시크).

2026-07-30 11:44:39 ✗ ERROR [DB] db.query_failed duration_ms=12 rows_affected=0 sql=INSERT INTO "teldrive"."channels" ("channel_name","user_id","selected","created_at","channel_id") VALUES ('My_Cloud',1387486203,true,'
2026-07-30 02:44:39.278',2236746563) ON CONFLICT ("channel_id") DO UPDATE SET "selected"=true RETURNING "channel_id" error=ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification (SQLSTATE 42P10)
026-07-30 11:44:39 ✗ ERROR [API] request.failed error=failed to update channel

ALTER TABLE teldrive.channels ADD CONSTRAINT channels_channel_id_unique UNIQUE (channel_id);

오늘 일등 공신, 딥시크!

업데이트 완료 후, 검색 속도는 수십 초 걸리던 것이 수초 정도로 느껴질 정도로 몰라보게 빨라졌고, 더불어 에브리씽 색인 속도도 향상되었다. 고로 구버전 사용자는 업데이트를 추천한다. 다만, 어떤 돌발사가 생길지 알 수 없으므로 시간이 충분할 때 작업할 것을 추천한다.

오늘 1.8.3 업데이트에 AI 조수로, 딥시크, GPT, 제미나이를 대동했는데, 결국 해결책을 제시한 AI는 제미나이와 딥시크였다. GPT는 문제 해결책을 제시하진 않고, 어떤 정보가 더 필요하다며 말을 계속 빙빙 돌리고 똑같은 이야기를 계속 반복한다. 마치 사람이 어떤 결정을 내리기에 앞서 책임 회피하려고 말일 빙빙 돌리는 것처럼 말이다. 첫 번째 문제는 제미나이가 제시한 해결책으로 해결했지만, 두 번째 문제, 즉 업로드 문제는 잘못된 해결책을 제시해 주는 바람에 DB를 다시 복구해야 했다.

업데이트 후 문제를 해결한답시고 이런저런 SQL 쿼리를 적용해서 너저분해진 것을 DB 복구로 깔끔하게 밀어버리고, 딥시크가 제시한 해결책을 순서대로 적용하니, 위의 모든 문제가 말끔히 해결되었다.

예전에도 그랬지만, SQL DB 문제는 무료 사용자 처지에선 딥시크가 젤 나은 것 같다. 그리고 문제 해결을 위해선 아래처럼 teldirve의 로그 옵션을 사용해, 디버깅 출력을 활용하는 것 잊지 말자.

teldrive run --config config.toml --log-level debug --log-db-level debug --log-tg-enabled --log-tg-level debug

종합 정리: 1.6.3 vs 1.8.3 비교

구분 1.6.3 1.8.3
세션 저장 PostgreSQL에만 저장 (DB 부하 큼) PostgreSQL / BoltDB / 메모리 선택 가능 (DB 부하 ↓)
파일 무결성 기존 해시 방식 BLAKE3 트리 해싱 (더 빠르고 안전)
파일 목록 조회 전체 조회 방식 SSE + 페이지네이션 (응답 속도 ↑)
데이터 정합성 중복 파일 허용 고유 제약 조건으로 중복 차단
채널 관리 수동 채널 추가 필요 자동 채널 롤오버 (1.7.0)
지원 포맷 제한적 HEIF, HEIC, WebP, xz, tgz 추가

0 comments:

댓글 쓰기

본문이나 댓글을 정독하신 후 신중히 작성해주세요