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복구 저널과 스냅샷.
복원
- 프로젝트를 중지합니다.
- 기록된 정규 루트에서 복원합니다; 밀려난 상태를 삭제하지 말고 보관하세요.
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 저널, 관련 소스 파일을 손대지 않은 채로 보관하세요 — 이것들이 보고서를 실행 가능하게 만들고, 수정이 잘못될 경우의 대비책입니다.