작업 전체 Status 스냅샷 (2026-06-24)
⚠️ 이 06-24 스냅샷은
00_overview.md(06-25 통합)로 대체됨. 시점 고정 보고용으로 보존. (관련 문서 일부 링크는 분석 본문이docs/notes/로 이동해 깨진 상태 — 최신은 통합 원장 참조.)
시점 고정 스냅샷. task ID별 라이브 상태는
tasks/index.md가 canonical. 이 문서는 완료/진행중/대기 + follow-up 2건을 한 장에 종합한 보고용.
작업의 큰 줄기는 raw_block 백엔드 io_uring/NVMe 성능 최적화(메인)와 FDP PoC 검증(서브).
모두 #3274(io_uring 인프라, 2026-06-11 머지 완료) 위에 쌓이는 후속 작업이다.
✅ 완료 (머지됨)
#3274 — io_uring 인프라 (06-11 머지) · io_uring_post_pr3274 · perf-findings vs #3274
모든 후속 작업의 토대가 되는 PR입니다. raw_block write/read 경로에 io_uring dispatcher를 도입하고(_write_buffers/_read_buffers), fixed-buffer zero-copy 등록, NVMe passthrough(uring_cmd), MDTS 기반 청크 분할까지 포함됩니다. M1(uring 적용)이 여기에 흡수되어 별도 PR 없이 완료됐습니다.
Cleanup — RawBlockCore 중복 조건 정리 · pending_cleanup 도달 불가능하거나 중복된 조건들을 정리한 워밍업 PR로 머지 완료됐습니다.
🔄 진행 중 — PR 열림 (리뷰 단계)
P0 (#3636) — put_many io_uring batched submit · P0 계획·검증 · batch finalize · review fixes
put_many가 키마다 개별적으로 write를 던지던 것을 _put_many_batch_io로 묶어 단일 SQ 제출로 바꾼 핵심 성능 PR입니다. 리뷰 반영 과정에서 importorskip 축소, 동일 배치 내 duplicate key parity 처리, partial-completion rollback, 대량 배치의 fairness를 위한 chunk cap 보강을 추가했고 현재도 리뷰 반영 중입니다.
L3 (#3494) — batched_remove 락 N→1 · L3 변경 노트 · 리뷰 cr-2a031316
RustRawBlockBackend.batched_remove가 키마다 락을 잡던 것을 단일 락으로 줄인 PR입니다. 현재 리뷰 중입니다.
L2→fix (#3698) — dispatch 실패 시 ref/put-task 롤백 · PR #3698 정리 · L2 변경 노트
원래 L2(legacy batched_submit_put_task dedup 배치화)로 시작했지만 NVMe regression으로 dedup은 폐기하고, dispatch 스케줄링 실패 시 ref와 _put_tasks를 롤백하지 않던 버그 수정만 남긴 PR입니다. Gemini 리뷰에서 Exception을 BaseException으로 바꾸라는 지적 1건이 있습니다.
Recovery POSIX (#3835) — bringup 병렬 검증, 대규님 PR · NY+DG 총괄 노트 · 통합 합의안
재시작 시 _validate_loaded_entries가 슬롯 헤더를 직렬로 pread하던 병목을 ThreadPoolExecutor(8 reader) 기반으로 병렬화한 대규님 PR입니다. 이 PR이 dispatch 구조 골격을 만들어놔서 NY의 io_uring batched 구현이 그 위에 합류하는 구조입니다.
🔨 진행 중 — 로컬 구현 완료, PR 대기
P0-B — padded O_DIRECT write를 batched_write로 · perf/iouring-batched-padded-write (워크트리, #3636 stacked) · Part B 계획
#3636이 O_DIRECT + padding 케이스에서 batched_write를 못 쓰고 per-entry write_uring 폴백으로 빠지던 문제를 고친 후속 패치입니다. 근본 원인은 Rust batched_write가 payload_len 없이 total_len 기준으로 memcpy하면서 유효 범위 바깥을 읽는 OOB read였고, payload_lens optional 인자 추가 + bounce에서 꼬리 명시적 zero-fill로 수정했습니다. Python의 can_batch 게이트는 완전 제거했습니다. 커밋 4개, 테스트 green 상태이며 #3636 머지 후 rebase해서 PR 제출 예정입니다.
io_uring batched recovery — 실 NVMe 6.08× 검증 완료 · perf/iouring-recovery-batched-read (base=DG #3835) · NY+DG 총괄 노트 · V1 구현·검증 · 실 NVMe 가이드
대규님 #3835가 남긴 _validate_loaded_entries_iouring_serial TODO를 채운 구현입니다. batched_read 단일 제출로 N개 헤더를 한 번에 읽고, iouring_queue_depth(256) 단위로 분할해 메모리 상한을 묶었으며, batch 전체 실패 시 per-slot 폴백으로 격리 동작을 복원했습니다. 실 NVMe(524K entries)에서 직렬 대비 6.08× 확인했습니다. uring_cmd 경로는 EINVAL 버그 발견으로 이 PR에서 제거해 별도 future work(F2)로 분리했으며, #3835 머지 후 PR 제출 예정입니다.
현재 체크아웃된
test-iouring-recovery브랜치(이 테스트 클론)는 DG POSIX 병렬 + NY io_uring batched recovery를 통합 검증하는 자리.
🔬 진행 중 — FDP PoC (서브 트랙)
- 단계 1(브랜치 audit) 완료 → 공정 재평가(eval redo) Phase 0 진행 중. → PLAN.md · Phase 0 소스 verify
- 핵심 발견:
separated모드의 host write 감소가 FDP 확정 효과가 아니라 controller counter artifact일 가능성(WAF ratio 3모드 ≈1.0159 동일, replay op 수 동일). harness/generator 무수정, 오케스트레이션·config만으로 진행 결론. → 반복실험 host write 재해석
🧵 Follow-up 작업 2건 (메인 트랙에서 파생)
F1. Write Coalescing (벡터드 writev, Tier 1)
- 출처:
iouring-batch-coalesce-writev-plan.md(06-16) - 상태:
planned— 계획만, 미구현 - 계기: 팀원 지적 — "#3636 batch io는 submit/wait만 1회로 묶었지 디바이스가 받는 커맨드는 여전히 2N개다. append라면 차라리 MDTS까지 채운 큰 IO 한 방이 낫지 않냐."
- 핵심 근거(분석 완료):
- 지금 2N 커맨드인 이유 = Rust
batched_write가 버퍼 1개당opcode::WriteSQE 1개. Rust에 writev 없음. - 결정적 사실:
hdr_total == header_bytes라 한 키의 헤더+페이로드는 슬롯 연속성과 무관하게 디바이스에서 항상 물리적으로 인접 → Tier 1을 append 가정 없이 항상 유효하게 만듦.
- 지금 2N 커맨드인 이유 = Rust
- 스코프(사용자 확정): Tier 1(키 내부 헤더+페이로드 2→1 커맨드)만. Tier 2(키 사이 merge)는 실측이 "커맨드 수가 병목"임을 입증할 때만.
- 미해결/주의:
- 공통 의존성 = Rust
opcode::Writev(복사 없는 iovec). Python 단독 불가. - P0-B와 같은
batched_write시그니처를 건드림 →payload_lens(P0-B) + iovec 그룹 (coalescing) 통합 설계 필요. 통합안 후보:batched_writev(offsets, buffer_groups, payload_lens, total_lens). - 4-step 계획(측정 스파이크 go/no-go → Rust primitive → Python TDD → 실 NVMe). Step 0 측정 스파이크가 먼저 — #3636 미머지라 그 위 스택 또는 머지 후 진입.
- 공통 의존성 = Rust
F2. uring_cmd(passthrough) checkpoint read 실패
- 출처:
uring_cmd_recovery_followup.md(06-23, 06-24 보강) - 상태:
future work— recovery PR에서 분리·제거, 별도 Rust 트랙으로 격상 - 증상(실 NVMe, 524K entries, /dev/nvme6n1 ↔ /dev/ng6n1):
- posix/io_uring(block): 정상 indexed=524272 (io_uring 6.08×)
- io_uring_cmd: indexed=0 —
_load_meta_payload에서[Errno 22] EINVAL
- 원인(확정 단서 + 유력 가설):
- meta header(offset 0, 단일 4KB 페이지) read 성공, meta payload(~75MiB를 2MiB chunk) read에서 EINVAL → device_path(P1) 문제 아님, payload read 자체 실패.
- 유력 원인:
_read_uring_cmd_buffers버퍼가 비정렬bytearray인데use_odirect=false라 non-bounce로 비정렬 ptr을 그대로 DMA addr로 전달 → passthrough multi-page PRP 페이지 정렬 위반 → EINVAL. 단일 페이지인 header는 통과해서 그동안 안 드러남.
- 수정 방향(Rust 정렬 bounce):
비정렬 ptr이면 페이지 정렬let needs_align = self.use_odirect || self.use_uring_cmd;
AlignedBufbounce + copy-back. 영향 범위가 recovery만이 아니라load_many_into등 모든 uring_cmd read의 multi-page payload → passthrough read 전반 버그, 별도 이슈/Rust PR(CODEOWNER @DongDongJu 영역)으로 격상 필요. - 기존 fix 브랜치/PR 분석 완료:
- PR #3841 (
priv/sy/fix/raw-block-uring-cmd-aligned-buffers, a340ab7): 부분 fix, recovery 미해결. padding 경로(len(dst)<total_len) 임시 버퍼만 정렬. recovery_load_meta_payload는bytearray(total_len)정확 크기라else분기(정렬 안 함)로 빠져 EINVAL 잔존. - PR #3812 (
core/rawblock-load-many-iouring-batch, 3xdevv): 에러처리/배칭만, 정렬 미수정. uring_cmd read를read_uring→batched_read로 전환 +wait_iouring을Vec<bool>비트맵 반환으로 변경. 버퍼는 여전히 비정렬이고 a340ab7 Python 보강도 무력화. EINVAL 잔존(단 크래시 대신 None→indexed=0). 수정 지점 이동: #3812 후 1순위 fix 위치가lib.rs:2092batched_readsubmit 경로(use_odirect || use_uring_cmd조건)로 이동.
- PR #3841 (
- 재활성화 절차: Rust 수정·실 NVMe 검증 후 ① dispatch
not use_uring_cmd제거 ② 테스트_uring_cmd_uses_sequential→_uring_cmd_uses_batched_read③ 벤치 io_uring_cmd 경로 복원. 제거 시점 구현은 git 이력에 보존됨.
⏸️ 대기 / 보류 (착수 가능하나 미착수)
- H1/H2
_free_slotsO(1) 멤버십·FIFO (FDP 선행) — 착수 가능 → v3_standalone_items §H1/H2 - M2 io_uring setup flag 튜닝 — #3274 머지로 착수 가능 → v3_standalone_items §M2
- S2 checkpoint overflow (HC-SSD 15/30TB) — Daejun #3449 답변 대기 → S2 one-pager · verification
- G3/G4 MP/L2 fixed-buffer hook, 단일 lock N-way 샤딩(D3) — 미착수 → PR landscape §4 Gap
- v1/v2 측정·CLI 항목들 — 실 HW 의존, 보류 → v2_benchmark_tracing · v1_original_roadmap
❌ 폐기된 것 (참고)
- L1 (#3526) put_many 4N→2N 락 — NVMe 50µs 기준 이득 <1%, PR drop → 벤치 근거 · 리뷰 cr-5a27732f
- L2 dedup — NVMe regression·미입증, dev 원본 복원 (ref-rollback만 #3698로 생존) → L2 변경 노트 · PR #3698 정리
임박한 액션 (의존 체인)
- #3636 머지 → P0-B PR 제출 (rebase --onto dev)
- #3835(DG) 머지 → io_uring recovery PR 제출
- F2 EINVAL 근본 수정 — Rust
batched_readlib.rs:2092에use_odirect || use_uring_cmdbounce 조건 추가 (@DongDongJu 영역) → recovery 재활성화 - F1 coalescing Step 0 측정 스파이크 (go/no-go) — P0-B와
batched_write시그니처 공동 설계