Skip to content

fix(replica): fsync directory after durable renames#1344

Open
corylanou wants to merge 1 commit into
mainfrom
issue-1342-restore-dir-fsync
Open

fix(replica): fsync directory after durable renames#1344
corylanou wants to merge 1 commit into
mainfrom
issue-1342-restore-dir-fsync

Conversation

@corylanou

Copy link
Copy Markdown
Collaborator

Description

Adds internal.FsyncDir and calls it after every rename that finalizes a durable file:

  • both Replica.Restore output paths (main + V3),
  • local L0 LTX staging in db.go,
  • the file replica backend's WriteLTXFile.

WriteTXIDFile's existing inline directory sync is refactored onto the same helper, so the crash-durability pattern (temp + fsync + rename + dir-sync) now lives in one place.

Motivation and Context

Without a directory fsync, a crash shortly after a successful os.Rename can lose the directory entry — a restore that reported success can leave no database file, and the file backend can lose a replica LTX object it reported as written. WriteTXIDFile already did this correctly; the other rename sites did not. The two non-restore sites were found by review while fixing the restore path (same defect class).

Fixes #1342

How Has This Been Tested?

go build ./..., go vet ./..., and go test -race for the root, file, and internal packages all pass. Durability-on-crash itself is not directly testable without fault injection; the change is the established WriteTXIDFile pattern applied to the remaining sites.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (would cause existing functionality to not work as expected)

Checklist

  • My code follows the code style of this project (go fmt, go vet)
  • I have tested my changes (go test ./...)
  • I have updated the documentation accordingly (if needed)

Add internal.FsyncDir and call it after every rename that finalizes a
durable file: both restore output paths, local L0 LTX staging, and the
file replica backend's LTX write. Refactor WriteTXIDFile's inline
directory sync onto the helper. Without the directory fsync a crash
shortly after a successful rename can lose the directory entry.
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

PR Build Metrics

All clear — no issues detected

Check Status Summary
Binary size 36.95 MB (0.0 KB / 0.00%)
Dependencies No changes
Vulnerabilities None detected
Go toolchain 1.25.12 (latest)
Module graph 1240 edges (0)

Binary Size

Size Change
Base (c96c0f4) 36.95 MB
PR (96711bc) 36.95 MB 0.0 KB (0.00%)

Dependency Changes

No dependency changes.

govulncheck Output

=== Symbol Results ===

No vulnerabilities found.

Your code is affected by 0 vulnerabilities.
This scan also found 0 vulnerabilities in packages you import and 1
vulnerability in modules you require, but your code doesn't appear to call these
vulnerabilities.
Use '-show verbose' for more details.

Build Info

Metric Value
Build time 42s
Go version go1.25.12
Commit 96711bc

🤖 Updated on each push.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Restore finalizes via rename without a directory fsync

2 participants