C.W.K.
Stream
Lesson 01 of 04 · published

index 는 파생물이야

~11 min · derived, purge-and-replay, single-source-of-truth, no-patching

Level 0Empty Shelf
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"재구축할 수 있으면, 절대 수리하지 마. 재구축 못 하면, 그건 파생물이 아냐 — 그리고 넌 그걸 알아야 해."

두 종류의 상태, 그리고 어느 건지 알아야 해

Recall 의 모든 행은 둘 중 하나고, 유지보수 이야기 전체가 어느 건지 말할 수 있느냐에 달렸어:

  • durable 상태 — 지우면 진짜 잃는 것들: 영상 record, 불변 run, release, 교정, job 이력. 이게 진실이야. 한 번 authored 되고, 버전 있고, 다른 어디서도 재생성 안 돼.
  • 파생 상태 — durable 진실에서 계산된 투영: 전문 index, 품질 지표, (언젠가) vector index. 뭐든 지워도 아무것도 안 잃어, 재계산할 수 있으니까.

이 분류는 사소한 bookkeeping 이 아냐. 수리 절차를 결정해, 그리고 틀리는 게 시스템이 썩는 길이야.

파생 상태의 수리는 딱 하나: 재구축

검색 index 가 release 랑 어긋났다 치자 — 투영 중 크래시, 옛 버전의 버그, 뭐든. 경험 있는 엔지니어라면 다들 reconciliation 스크립트에 손 뻗어: index 를 release 와 diff 하고, 차이를 찾고, patch 해. 수술적이고 효율적으로 느껴져. 틀린 수야, 그리고 Recall 은 그걸 대놓고 금지해.

이유가 여기 있어. 그 patch 스크립트는 투영의 두 번째 구현이야 — index 에 뭐가 있어야 하는지 정하는 새 코드가, 이미 그걸 정하는 진짜 투영 코드 옆에 사는 거지. 진실 하나의 구현 둘, 그리고 갈라질 거야, 투영이 바뀔 때 아무도 reconciler 를 업데이트 안 하니까. 이제 조용히 살짝 틀린 행을 쓰고 고쳤다고 부르는 수리 도구가 있어. patch 가 버그 사는 데야.

맞는 수는 더 단순하고 지루해: 영향받은 파생 행을 purge 하고 durable 소스에서 replay 해. 투영 코드가 이미 있고 index 가 뭐여야 하는지 아는 유일한 거야. 다시 돌려. diff 없음, 두 번째 구현 없음, 갈라짐 없음. 이게 정확히 materialized view 야: 손으로 편집하는 테이블이 아니라 refresh 하는 cache. 그리고 형제 두뇌가 따르는 같은 규율이야 — 그 파생 mirror 가 어긋나면, 자기 append-only 진실에서 purge 하고 replay 하지, 절대 reconcile 안 해.

널 정직하게 유지하는 테스트

그러니 네가 소유한 모든 상태에 돌릴 질문이 여기 있어: 이걸 통째로 지우면, durable 한 뭔가에서 재구축할 수 있어?

  • → 파생물이야. 절대 patch 하지 마. 유일한 수리는 purge-and-replay 고, 마음 내키면 돌릴 수 있어야 해.
  • 아니 → durable 이야, 네가 의도했든 아니든. 버릴 수 있는 cache 로 다뤄왔으면, 두 번 생각 없이 지울 것 안에 선언 안 된 진실이 앉아 있는 거야.

두 번째 경우가 위험한 놈이고, 놀랍도록 흔해: 아무도 재계산 못 하는 계산된 field, 뭔가의 유일한 사본을 쥔 cache, 소스가 더는 안 가진 행을 품은 index. 그걸 찾아 선택을 강제해 — 진짜 durable 하고 버전 있게 만들거나, 진짜 재구축 가능하게 만들거나. 못 하는 건 그 사이에 두는 거야, 사이 상태는 누가 그걸 cache 로 다루는 첫날 잃을 진실이니까.

Code

purge 하고 replay. 절대 diff-and-patch 안 함.·python
# DURABLE (진실 — 다른 어디서도 재생성 안 됨)
#   videos, transcript_runs, transcript_releases, corrections, jobs

# 파생 (투영 — 항상 재구축 가능)
#   transcript_segments, transcript_segment_fts, quality_assessments

# 틀림: reconciler 는 투영의 두 번째 구현이다.
def reconcile_index():
    for release in all_releases():
        if index_differs(release):
            patch_index_rows(release)   # 투영이 바뀌는 날
                                        # 진짜와 갈라진다

# 맞음: 투영 코드가 답을 아는 유일한 것이다.
def repair(release):
    purge_derived_rows(release)         # 투영을 버린다
    project_segments_and_fts(release)   # 진짜 코드를 다시 돌린다

# 네가 소유한 모든 행에 테스트:
#   지울 수 있음 + 재구축 가능 -> 파생. purge 하고 replay.
#   재구축 불가              -> durable. 선언 안 된 진실을 찾았다.

External links

Exercise

네가 소유한 시스템의 주요 상태 조각을 나열하고 각각을 durable 또는 파생으로 라벨해. 각 '파생' 에 대해, 지금 당장 purge 하고 재구축할 수 있는지 물어 — 재구축 경로가 쓰였고, 테스트됐고, 요청 시 돌릴 수 있어? cache 로 라벨한 각각엔 삭제 테스트를 돌려: 사라지면 복구 불가능한 게 있어? 그 테스트에 실패하는 건 뭐든 선언 안 된 진실이야; 지금 durable 하게 할지 재구축 가능하게 할지 정해.
Hint
reconciliation 스크립트를 먼저 찾아 — 각각이 투영을 그냥 재구축 못 한다는 자백이자, 갈라지길 기다리는 그 투영의 두 번째 구현이야. 그다음 재구축 경로 없는 cache 를 찾아; 그게 조용히 유일한 사본을 쥔 놈이야. 건강한 최종 상태: 모든 파생물엔 한-명령 재구축이 있고, 나머지 전부는 명시적으로 durable 해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.