diff options
| author | eunhhu <[email protected]> | 2026-09-24 17:14:54 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-24 17:14:54 +0100 |
| commit | b1ce1927022d374198441afafeb27199fc8a052a (patch) | |
| tree | 6021f175f4c67ed03b44240eaa2f90d846f12f6f /docs/research/019-byte-storage.md | |
| parent | d34f9426d5317a1948f12f229439946728bc342a (diff) | |
| download | pure-b1ce1927022d374198441afafeb27199fc8a052a.tar.gz pure-b1ce1927022d374198441afafeb27199fc8a052a.zip | |
Establish native micro runtime checkpoint
Diffstat (limited to 'docs/research/019-byte-storage.md')
| -rw-r--r-- | docs/research/019-byte-storage.md | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/docs/research/019-byte-storage.md b/docs/research/019-byte-storage.md new file mode 100644 index 0000000..faefecf --- /dev/null +++ b/docs/research/019-byte-storage.md @@ -0,0 +1,84 @@ +# 019 — SQL을 제거한 바이트 접근·저장 경로 + +> 후속 [020](020-prepared-connections.md)에서 저장·응답 구간을 작성 파일로 정의하도록 +> 확장했다. 아래는 그 이전 구현의 기록이며 현재 실행에는 `--program FILE`도 필요하다. + +2026-09-23. **RAM·storage를 SQL에 맞추지 않는다는 요구에 따라 활성 구현의 SQLite를 +제거했다.** 기존 CLI의 저장·복원 흐름은 유지하고 서버를 호출자의 바이트를 직접 기록하는 +C17/POSIX 어댑터로 교체했다. 새 저장 기술의 성능을 입증한 연구 결과가 아니라, 잘못 +도입한 내부 모델을 제거하고 연결의 의미를 확인한 구현 결과다. + +사용자는 이전처럼 작업물을 만들고 `push`·`pull`로 저장·복원한다. 서버 실행 옵션은 +`--db FILE`에서 `--store DIRECTORY`로 바뀌었다. 기존 파일은 자동 변환하거나 덮어쓰지 않는다. +실행 예는 [구현 README](../../prototypes/connections/README.md)에 있다. + +## 내부 모델의 기준 + +필요한 데이터의 범위·접근·갱신·수명에서 배치와 실행 경로를 결정한다. 테이블·행·질의 +실행기에 맞춘 뒤 다시 소비자의 표현으로 바꾸는 단계를 필수로 두지 않는다. DB는 데이터 +접근·일관성·영속성을 다룬다는 범위 이름이며 SQL 엔진 채택을 뜻하지 않는다. + +이번 경로는 RAM에 수신한 본문과 저장 파일의 읽기 범위를 같은 `PureSpan`으로 전달한다. +소비자는 포인터와 길이를 사용하며, 소유자는 소비 종료까지 데이터를 유지한다. 저장소의 +주소를 영속 포인터로 기록하거나 RAM과 저장 매체의 물리적 성질이 같다고 가정하지 않는다. +타입·의미 검증, 표현 변환이 필요한 경계, 공개·영속화·전송 완료의 차이는 남는다. + +현재 Workbench는 JSON 전체를 저장·복원한다. 이 경로에서 직렬화를 제거했다고 주장하지 +않으며, JSON이나 `PureSpan`만으로 전체 애플리케이션의 데이터 표현을 완성한 것도 아니다. +파일별 전체 교체는 지금 작업의 어댑터 선택이다. Pure 전체를 키-값 저장소로 고정하지 않는다. + +## 구현한 경로 + +쓰기: 수신 구간 → 새 파일에 원본 바이트 기록 → 파일 fsync → 원자적 이름 교체 → +디렉터리 fsync → 성공 응답. 버전 비교와 공개는 디렉터리별 쓰기 잠금 안에서 수행한다. +파일의 24 B 헤더는 식별자·버전·본문 길이만 담는다. 본문은 변환하지 않는다. + +읽기: 파일·길이 검사 → 필요한 범위의 읽기 전용 매핑 → 부분 전송 → 매핑 해제. +저장 API는 오프셋·길이 접근을 지원하며 현재 HTTP 경로는 전체 본문을 요청한다. +페이지 정렬에 필요한 접두부도 매핑하므로 요청한 바이트 수가 실제 매핑/RSS와 같지는 않다. +파일 디스크립터는 매핑 후 닫을 수 있다. [mmap 계약](https://man7.org/linux/man-pages/man2/mmap.2.html). + +저장 버전을 제자리에서 수정하지 않고 새 파일로 교체해, 읽고 있는 이전 버전과 새 요청이 +보는 버전을 분리한다. 이는 불변 파일과 이름 교체의 조합이며 `MAP_PRIVATE`만으로 외부 +파일 변경까지 격리되는 것은 아니다. [rename 계약](https://man7.org/linux/man-pages/man2/rename.2.html). + +| 쓰기 결과 | 의미 | +|---|---| +| 예상 버전 불일치 | 충돌, 기존 바이트 유지 | +| 공개 전 실패 | 기존 바이트 유지, 이 호출의 임시 파일 제거 시도 | +| 공개 후 디렉터리 fsync 실패 | 새 바이트는 보이지만 영속화 확인 불가; `PURE_UNCERTAIN` / `durability_unknown` | +| 모든 동기화 성공 | 어댑터의 저장 성공; 상대 앱의 응답 수신 완료와는 별개 | + +파일 fsync만으로 디렉터리 항목의 동기화를 대신할 수 없어 두 시점을 구분했다. +[fsync 계약](https://man7.org/linux/man-pages/man2/fsync.2.html). 이 순서를 구현했다는 사실과 +실제 전원 장애에서 파일시스템·장치의 내구성을 검증했다는 주장은 별개다. + +## 확인한 것과 남은 비용 + +Linux AArch64에서 일반 빌드와 ASan·UBSan 빌드가 모두 통과했다. SQL 라이브러리 링크는 없다. + +- 저장 단위 검사: 범위·페이지 경계·예산, 갱신 중 이전 참조, 충돌·빈 본문·버전 소진, + 잘못된 저장 파일, 공개 전후 실패 주입, 공개 전 프로세스 종료와 재개. +- 실제 TCP 통합 16개 시나리오: 기존 작성물 복원, 두 프로세스의 쓰기 경쟁, 부분 송수신, + 읽는 중 다른 저장, 연결 종료, 자원 포화와 회수, 응답 미수신, 재시작 등. +- 검사 종료 후 활성 연결과 참조 본문 길이는 0이다. 현재 기록은 지정한 자원의 정확성 + 검사이며 지연·처리량·전체 RAM 비교가 아니다. + +현재 경로는 별도 응답 본문 사본을 만들지 않고 SQL 엔진도 경유하지 않는다. 커널 복사· +페이지 폴트·파일 동기화·클라이언트 직렬화는 남는다. 동기 파일 작업은 다른 연결의 처리를 지연시킬 수 있다. +이전 매핑은 이전 파일의 디스크 수명도 연장한다. 공개 전 종료로 남은 임시 파일을 자동으로 +정리하지 않으므로 장기 디스크 사용량의 상한도 아직 보장하지 않는다. 본문 체크섬·부분 쓰기· +다중 객체 트랜잭션은 없고, macOS·전원 장애·디스크 고장도 검사하지 않았다. + +[원자료와 재현](../../prototypes/connections/results/2026-09-23-byte-storage/README.md), +[직접 저장 구현](../../prototypes/connections/store.c), +[구간·수명 API](../../prototypes/connections/store.h). +018의 원자료는 당시 SQLite 구현의 기록으로 별도 보존한다. + +## 다음 결정 + +현재 연결 순서는 여전히 C에 고정돼 있다. 다음은 **필요한 데이터 범위·연산·외부 효과· +소비 완료의 관계를 실행 가능한 Pure 정의로 표현하는 것**이다. 이미 있는 작업의 저장과 +응답 경로에서 시작하고, 공개됐지만 영속화가 불확실한 결과를 단순 실패나 롤백으로 +합치지 않는다. 데이터의 배치는 실제 소비·갱신 패턴에서 결정하며, 새 쿼리 엔진이나 +SQL 대체 제품 개발을 다음 목표로 추가하지 않는다. |
