문제 해결

GitHub에서 소스 보기

AWR의 무언가가 예상대로 동작하지 않을 때, 이 가이드는 증상에서 수정으로 나아갑니다: 먼저 상태 검사, 그다음 데이터베이스 문제, 그다음 소스 파일의 중단된 변경. 각 섹션은 실행할 정확한 명령과 출력을 읽는 방법을 제공합니다. 일상적인 명령은 일상 워크플로와 CLI 레퍼런스를 참조하세요.

첫 번째 단계: 상태 검사 실행

AWR은 Doctor라는 내장 진단 명령을 두 가지 수준으로 제공합니다:

awr --json doctor --database-only
awr --json doctor
  • --database-only는 SQLite 데이터베이스 자체를 검사합니다: 무결성, 외래 키, 스키마 버전, 마이그레이션 신원, AWR 소유 스키마 객체.
  • 전체 doctor는 추가로 선택된 소스 파일과 런타임 기록 및 디스크상 파일 사이의 바인딩을 검사합니다.

Doctor는 데이터베이스를 읽기 전용으로 엽니다. 스키마를 마이그레이션하거나, 소스를 재인덱싱하거나, 보류 중인 뮤테이션을 적용하거나, 클레임을 만료시키거나, 고아 파일을 삭제하지 않습니다 — 따라서 손상된 프로젝트에서도 항상 안전하게 실행할 수 있습니다.

Doctor의 발견 사항 읽기

Doctor는 추측 대신 명시적인 발견 사항으로 문제를 보고합니다:

  • schema_issues — 번들 마이그레이션과 대조하여 검사한, 누락되거나 변경된 AWR 소유 테이블, 열, 인덱스, 트리거. 추가 객체는 공존할 수 있습니다; Doctor는 정의를 복구하거나 그 SQL을 출력하지 않습니다.
  • foreign_key_check_error — 잘못 형성된 참조가 SQLite의 외래 키 검사 자체 실행을 방해했습니다. 이 필드가 보이면 데이터베이스가 건강하지 않은 것이며, 보고된 위반 0건은 "모든 것이 괜찮다"가 아니라 "셀 수 없었다"를 의미합니다.
  • 활성 세션 — 정보 제공용일 뿐; 오래된 기록이 프로세스가 죽었음을 증명하지는 않습니다.
  • 누락된 의존성, dangling 엣지, 사용 불가 소스, 중단된 저장, 손상되거나 등록되지 않은 아티팩트는 각각 발견 사항으로 보고됩니다. 읽을 수 없는 페이지나 외부(non-AWR) 데이터베이스는 오해를 부르는 상태가 아니라 명시적 오류를 생성합니다.

증상: "AWR이 내 소스 파일을 거부했습니다"

YAML 소스 파일에 구문 오류나 잘못된 타입의 필드가 있으면, AWR은 오류 코드 InvalidInput과 구조화된 상세 정보로 실패합니다:

{
  "location": {
    "locator": "file:///project/work.yaml",
    "pointer": "/work_items/0/title",
    "line": 3,
    "column": 10
  },
  "rule": "ledger.string",
  "repair": "Use a quoted string or a YAML block scalar (|) for multiline text."
}

읽는 방법: pointer는 소스 파일 자체의 어휘(구성된 중국어 필드 이름 포함)로 문제의 필드를 지명합니다; line과 column은 1부터 시작합니다. 순수 구문 오류는 파서 좌표만 가질 수 있고, 일부 조회(예: YAML 별칭)는 null 좌표와 함께 포인터를 유지합니다 — 이것이 다른 면에서 유효한 파일을 거부하지는 않습니다. rule은 실패한 기대를 지명하고, repair는 기대하는 구조를 기술합니다. 파일을 편집하거나 거부된 값을 에코하지 않습니다.

흔한 경우: title: [Draft, Review]를 쓰면 YAML은 이를 리스트로 파싱하지만, 필드는 문자열을 요구합니다. 쉼표가 문자 그대로 의도된 것이라면:

title: "Draft, Review"

여러 줄 설명에는 YAML 블록 스칼라(|)를 사용하세요; 유효한 중국어 텍스트와 공백이 포함된 경로는 완전히 지원됩니다.

증상: "변경 사항이 쿼리에 나타나지 않습니다"

소스 파일을 편집했는데 AWR이 여전히 오래된 사실을 보여줍니다. 재인덱스를 실행하세요:

awr source reindex

그다음 보고서의 두 부분을 모두 확인하세요: 연산 성공 그리고 프로젝션 완전성. 스캔은 변경된 사실을 가져오지 않고 소스를 관찰하기 때문에, 프로젝션이 불완전한 상태로 남아도 스캔은 성공할 수 있습니다. 같은 보고서가 --json으로 JSON으로, MCP awr_source_reindex를 통해서도 제공됩니다. 동등한 시작 스냅샷의 출력을 비교하세요; 재인덱싱 자체가 소스 상태를 갱신합니다.

작업 항목의 증적이 이상해 보이면, work show(또는 MCP awr_work_get)가 플랫한 evidence 목록 옆에 evidence_groups를 보고합니다. 각 그룹은 하나의 정확한 로케이터를 가집니다; 같은 경로의 소스 참조와 검증된 보고서는 구분된 상태로 남으며, 그룹화는 레코드 간에 검증을 이전하지 않습니다.

증상: "데이터베이스가 손상되거나 손실되었습니다"

소스 파일이 프로젝트 사실의 권위 있는 원본이지만, SQLite 데이터베이스 (.awr/state.db)도 그 파일들이 담지 않는 상태를 보유합니다: 세션, 클레임, 체크포인트, 런타임 이벤트, 아티팩트 등록, 뮤테이션 시도. 재인덱싱은 소스로부터 프로젝션을 갱신하지만, 그 런타임 이력을 재구축할 수는 없습니다 — 같은 소스에서 새 데이터베이스를 초기화하는 것도 마찬가지입니다.

올바른 백업

복구 가능한 스냅샷을 위해, 다음 모두를 함께 보관하고, 모으는 동안 프로젝트 쓰기를 일시 중지하세요(SQLite의 백업 API는 일관된 데이터베이스 이미지를 제공하지만 주변 파일을 스냅샷하지는 않습니다):

  • SQLite의 백업 API 또는 동등한 도구로 만든 .awr/state.db의 일관된 백업 — 쓰기가 활성 상태일 때 파일을 복사하면 write-ahead 로그에 아직 있는 커밋된 기록을 놓칠 수 있습니다.
  • 대응되는 소스 파일, Git 리비전, .awr/project.toml, 인가된 루트 구성, 명시적으로 인가된 외부 소스.
  • 관리되는 아티팩트 파일, 관리 디렉터리 밖에 등록된 로컬 아티팩트, 보류 중인 연산이 참조하는 .awr/mutations 복구 저널과 스냅샷.

복원

  1. 프로젝트를 중지합니다.
  2. 기록된 정규 루트에서 복원합니다; 밀려난 상태를 삭제하지 말고 보관하세요.
  3. awr --json doctor --database-only를 실행한 다음, 전체 awr --json doctor를 실행합니다.

복원은 파일이 아직 누락된 상태에서 아티팩트 등록을 복구할 수 있습니다 — 파일을 복원하거나 발견 사항을 미해결로 남겨두세요. awr source reindex는 런타임 복원도 데이터베이스 재배치 도구도 아닙니다.

Doctor는 지명된 복구를 수행할 수 있지만, 현재 프로젝트 리비전, 선택된 객체, 사유가 있을 때만 가능합니다; 복구는 소스와 무관한 런타임 상태를 보존합니다. 데이터베이스 무결성이 깨져 있다면, 제안되는 런타임 복구는 비활성화됩니다 — 자동 재구성은 없습니다.

증상: "쓰기 중간에 뮤테이션이 중단되었습니다"

AWR은 승인된 제안을 내구성 가드와 함께 소스 파일에 적용합니다: 불변의 before/after 스냅샷이 시도가 기록되기 전에 저장되고, 성공에는 의도된 소스 바이트, 재구축된 프로젝션, 최종 적용 이벤트가 필요합니다. 프로세스가 쓰기 도중 죽으면, 시도는 열린 채로 복구 가능한 상태로 남습니다.

write_outcome: pending_recovery와 함께 MutationIncomplete를 받았다면, 먼저 검사하세요:

awr --json doctor
awr --json proposal show PROPOSAL_ID

출력에서 현재 project_revision을 읽은 다음, 제안을 재개합니다:

awr --json proposal recover PROPOSAL_ID \
  --actor reviewer \
  --reason "Resume the interrupted report review" \
  --expected-revision CURRENT_REVISION

복구가 무엇을 하는지는 시도가 얼마나 진행되었는지에 달려 있습니다:

중단 후 상태복구 동작
스냅샷 존재, 적용 저널 없음소스는 변경되지 않음; 새 proposal apply를 시작할 수 있음.
저널 존재, 소스가 여전히 "before"와 일치소유권, 구성, 소스, 리비전을 재검증한 다음 기록된 "after" 바이트를 설치.
소스가 이미 "after"와 일치, 프로젝션 불완전파일을 다시 쓰지 않고 프로젝션을 재구축.
프로젝션 커밋됨, 최종 이벤트 없음프로젝션을 검증하고 최종 이벤트를 커밋 — 두 번째 파일 쓰기 없음.
최종 이벤트 커밋됨, 응답 손실영구 영수증을 반환; 복구 반복은 InvalidTransition으로 실패, 중복 이벤트 없음.
소스나 스냅샷이 기록된 계획과 불일치소스를 보존하고, 충돌을 보고하고, 완료를 보류.

성공적인 재시도는 recovered를 보고하고, 원래 시도를 지명하고, resolved_event_id를 최종 이벤트에 바인딩합니다.

하지 말아야 할 두 가지:

  • 결과를 강제하기 위해 스냅샷을 편집하지 마세요. 현재 소스가 어느 스냅샷과도 일치하지 않으면, 소스 충돌을 해결하고 새 제안을 준비하세요.
  • 재시도가 파일을 썼다고 가정하지 마세요. source_write_performed는 현재 호출만 기술합니다 — 이것이 복구가 먼저 재검증하는 이유입니다.

동시성: AWR 쓰기 주체들은 소스별 OS 잠금과 트랜잭션 expected_revision 검사로 조율합니다. 별도의 소스는 독립적으로 진행되지만, 그 사이의 프로젝트 리비전이 명시적인 복구 재시도를 요구할 수 있습니다. 외부 에디터는 잠금에 참여하지 않습니다; 지문 검사가 그 변경을 감지합니다.

멈추고 도움을 요청해야 할 때

다음의 경우 임기응변 대신 멈추고 에스컬레이션하세요:

  • Doctor가 깨진 데이터베이스 무결성을 보고(foreign_key_check_error, 읽을 수 없는 페이지) — 런타임 복구가 비활성화되며 자동 재구성이 없습니다.
  • 뮤테이션 복구가 소스/스냅샷 충돌을 보고 — 지원되는 경로는 스냅샷이나 저널의 수동 편집이 아니라 새 제안입니다.
  • 시나리오가 머신 전원 손실, 분산 쓰기 주체, 다른 운영 체제를 포함 — 복구 보장은 로컬 프로세스 중단을 다루며; 그 너머는 확립되지 않았습니다.

도움을 요청하거나 이슈를 제기하기 전에, 상태가 신선할 때 캡처하세요:

awr --json doctor --database-only
awr --json doctor
awr --json proposal show PROPOSAL_ID   # if a mutation is involved

밀려난 데이터베이스, .awr/mutations 저널, 관련 소스 파일을 손대지 않은 채로 보관하세요 — 이것들이 보고서를 실행 가능하게 만들고, 수정이 잘못될 경우의 대비책입니다.