IndexedDB: Cache record versions per transaction

ABANDONED2026contentindexeddbleveldbperformance
2026. 9. 2.zbnerd 프로필 이미지zbnerd

IndexedDB의 LevelDB 백엔드에서 레코드 버전을 트랜잭션별로 캐시해,
연속 쓰기 중 메타데이터 조회가 유발하는 flush를 줄이는 변경을 제안했습니다.
리뷰에서 해당 백엔드가 deprecated 상태여서 비핵심 개선을 받지 않는다는
방침을 확인했고, 이를 수용해 2026년 9월 2일 CL을 중단했습니다.
이번 기여에서는 구현 내용과 함께, 리뷰를 통해 배운 작업 대상 선정 기준을
중심으로 정리합니다.

문제 설명

CL 설명
PutRecord()마다 LAST_VERSION을 읽으면서 대기 중인 LevelDB 쓰기와
undo log를 flush하는 문제를 다룹니다. 관련 이슈는 커밋 메시지에 연결된
Chromium Issue 41460075입니다.

기존 GetNewVersionNumber()는 레코드를 쓸 때마다 object store의 마지막
버전을 GetInt()로 읽고, 1을 더한 값을 다시 기록했습니다.
이 읽기가 사용하는
TransactionalLevelDBTransaction::Get()
실제 조회 전에 WriteChangesAndUndoLog()를 호출합니다. 따라서 같은
트랜잭션에서 레코드를 연속으로 써도 버전 조회 때문에 이전 쓰기를 반복해서
내보낼 수 있었습니다.

이 내부 flush와 트랜잭션의 논리적 커밋은 서로 다른 단계입니다. 이번 CL은
버전 조회로 발생하는 불필요한 내부 쓰기를 줄이려는 최적화였습니다.

해결 내용

1. 트랜잭션별 버전 캐시 제안

병합되지 않은 최종 Patch Set 2에는 다음 변경을 구현했습니다.

  1. BackingStore::Transaction에 object store ID와 마지막 버전을 저장하는
    object_store_last_version_numbers_ 맵을 추가했습니다.
  2. GetNewVersionNumber()를 트랜잭션의 private 메서드로 옮겼습니다.
    캐시에 값이 없을 때만 기존 메타데이터를 읽고, 이후에는 캐시에서 버전을
    가져오도록 했습니다.
  3. 새 버전은 기존처럼 PutInt()로 기록하되, 기록 요청이 성공한 뒤 캐시도
    갱신했습니다. 반복적인 메타데이터 읽기를 생략해 쓰기를 버퍼에 유지하려는
    접근입니다.
  4. 같은 트랜잭션에서 새 object store를 만들면 초기 버전인 1을 캐시에
    넣었습니다. 첫 레코드를 쓸 때도 이미 알고 있는 초기값을 다시 읽지 않게
    했습니다.
  5. 공용 LevelDB operations 파일에서 기존 helper의 선언과 구현을 제거하고,
    PutRecord()가 새 메서드를 호출하도록 바꿨습니다.

변경은 content/browser/indexed_db/instance/leveldb/ 아래의 구현·헤더·테스트
5개 파일에 한정되며, 총 83줄 추가와 48줄 삭제입니다. Patch Set 2는
커밋 메시지를 수정한 것으로, Patch Set 1과 코드 변경은 동일합니다.

2. 핵심 리뷰: deprecated 백엔드의 변경 수용 범위

2026년 9월 2일 Evan Stade는
Patch Set 2의 리뷰 코멘트에서
다음과 같이 설명했습니다.

we are not really accepting non-critical improvements for IndexedDB's LevelDB backend as it's deprecated.

IndexedDB의 LevelDB 백엔드가 deprecated 상태이므로, 그 백엔드에 대한
비핵심 개선은 받지 않는다는 의미입니다. 이 코멘트는 작업 대상의 유지보수
단계와 변경의 필요성을 먼저 확인하게 했습니다.

이번 제안은 레코드 버전 조회를 줄이는 최적화였고, 리뷰어는 이 백엔드에서
그러한 개선을 받아들이는 범위가 제한되어 있음을 알려줬습니다. 공개된
리뷰에는 캐시 구현의 특정 결함이나 테스트 실패를 지적한 내용은 없습니다.
따라서 중단 사유는 deprecated 백엔드에 대한 비핵심 개선이라는 점으로
기록하는 것이 정확합니다.

이 피드백을 통해, 구현 가능한 개선점을 찾은 다음에는 해당 코드가 현재도
적극적으로 개선하는 대상인지 확인해야 한다는 점을 배웠습니다. 오래된
이슈와 수정 가능한 코드가 남아 있다는 사실만으로 현재의 기여 우선순위까지
알 수는 없습니다. 작업을 시작하기 전에 최근 리뷰와 담당자의 방침을
확인해야 합니다.

또한 코멘트의 범위는 IndexedDB의 LevelDB 백엔드에 대한 non-critical
improvements
입니다. 긴급한 수정까지 모두 거절한다는 뜻으로 확대해서
해석할 수는 없으며, 이 코멘트만으로 예외가 되는 변경의 구체적인 기준까지
확정할 수도 없습니다.

3. 대응: CL 중단과 다음 이슈 선택 기준 정리

리뷰를 확인한 뒤 CL을 abandoned로 변경했습니다.
후속 답변에서는
이미 CL을 중단했음을 알리고, 앞으로 IndexedDB 이슈를 선택할 때 이 방침을
고려해 deprecated LevelDB 백엔드의 비핵심 작업을 피하겠다고 답했습니다.

아래 시각과 문서의 업로드 날짜는 한국 표준시(KST) 기준입니다.

시각 진행 내용
9월 2일 04:00 Patch Set 1 업로드
9월 2일 04:03 커밋 메시지를 정리한 Patch Set 2 업로드
9월 2일 15:15 Evan Stade가 백엔드의 deprecated 상태와 변경 수용 방침 설명
9월 2일 15:52 CL 중단
9월 2일 16:02 중단 사실과 향후 이슈 선택 방향을 후속 답변으로 전달

결과적으로 이 변경은 Chromium에 병합되지 않았습니다. 리뷰의 취지를
수용하고 다음 작업의 선정 기준을 바꾼 것이 이번 기여의 주요 결과입니다.

테스트 방법

패치에는 leveldb_backing_store_unittest.cc
LevelDbBackingStoreTest.PutRecordsDoNotFlushBeforeCommit 테스트를
추가했습니다. 테스트가 검증하도록 작성된 내용은 다음과 같습니다.

  1. 데이터베이스와 object store를 만들고 read-write 트랜잭션을 시작합니다.
  2. 같은 object store에 PutRecord()로 레코드 두 개를 씁니다.
  3. 트랜잭션을 커밋하기 전에 하위 데이터베이스에서 LAST_VERSION을 직접
    읽어, 저장된 값이 초기 버전 1인지 확인합니다.
  4. 트랜잭션을 커밋한 뒤 다시 읽어 최종 버전이 3인지 확인합니다.

이 테스트의 검증 범위는 위 연속 쓰기 시나리오의 커밋 전후 메타데이터
값입니다. 성능 향상률은 측정하지 않습니다.

공개된 CL 설명과 메시지에는 로컬 테스트 실행 결과, CQ 통과 기록,
성능 측정치가 없어 통과 여부나 개선 수치를 확인할 수 없습니다.
이 기록에서는 패치에 추가된 테스트의 검증 내용까지만 설명합니다.

배운 점

  • 이슈를 고를 때 백엔드의 유지보수 상태부터 확인해야 합니다. 동일한
    IndexedDB 영역이라도 작업 대상 구현의 deprecated 여부에 따라 변경을
    받아들이는 기준이 달라질 수 있습니다.
  • 최적화의 구현 가능성과 프로젝트의 우선순위를 함께 판단해야 합니다.
    불필요한 읽기를 줄일 수 있다는 근거에 더해, 현재 그 백엔드에 변경을
    추가할 필요가 있는지도 확인해야 합니다.
  • 짧은 리뷰에서도 적용 범위를 정확히 읽어야 합니다. 이번 코멘트는
    deprecated LevelDB 백엔드의 비핵심 개선에 관한 방침이었습니다.
    구현이 틀렸다는 평가나 IndexedDB 전체에 대한 방침으로 일반화하지 않고,
    실제로 언급된 범위에 맞춰 대응했습니다.
  • 중단 이유와 후속 행동을 함께 남기면 다음 작업에 활용할 수 있습니다.
    abandoned 상태와 함께 이유를 기록하고, 이후 이슈 선택에서 같은 종류의
    작업을 피하겠다는 구체적인 방향을 답변에 남겼습니다.
  • 저장소의 읽기가 쓰기를 유발할 수 있습니다. 트랜잭션 내부의
    메타데이터 조회가 버퍼와 undo log를 flush하므로, 반복 조회를 최적화할
    때는 하위 저장 계층의 동작까지 확인해야 합니다.

참고 자료