Skip to content

m2.1 : introduce configurable fsync strategies - #4

Merged
SantanuKar43 merged 5 commits into
mainfrom
m2.1/configurable-fsync-strategy
Apr 25, 2026
Merged

m2.1 : introduce configurable fsync strategies#4
SantanuKar43 merged 5 commits into
mainfrom
m2.1/configurable-fsync-strategy

Conversation

@SantanuKar43

@SantanuKar43 SantanuKar43 commented Apr 15, 2026

Copy link
Copy Markdown
Owner

This PR introduces 3 fsync strategies for the WAL operations -

  1. EVERY_SEC - If this is selected, a cron is scheduled to run every second which Fsyncs the wal file (balanced performance, at most 1 second of data loss). If fsync fails in this mode, server is stopped.
  2. ALWAYS - Fsync happens on each append call synchronously (Least performant but no data loss)
  3. NEVER - No explicit Fsync. Let the operating system semantics handle it. (Most performant, susceptible to data loss)

It also adds a memory buffer for the WAL contents. All WAL writes are appended to the buffer first (except in ALWAYS mode) and then flushed based on the strategy.

@SantanuKar43
SantanuKar43 requested a review from Priyansh61 April 15, 2026 04:25
Comment thread internal/wal/wal.go
Comment thread internal/wal/wal.go Outdated
Comment thread internal/wal/wal.go Outdated
Comment thread internal/wal/wal.go
Comment thread internal/wal/wal.go Outdated
@SantanuKar43
SantanuKar43 requested a review from Priyansh61 April 20, 2026 02:04
Comment thread internal/wal/wal.go
Comment on lines +64 to +67
if err != nil {
log.Printf("wal fsync failure: %s, stopping the server", err)
w.fatalErrChan <- err
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ig this will cause a race condition , i am not sure here but i had a scenario in my head

lets say

thread 1 - calls append get error in fsync its holding the mutex tries to send to fatalErrChan and blocked here

thread 2 - cant aquire lock blocked here

fsync error 1 → goes into channel (buffered, doesn't block)
handleFatalErrors reads it → calls cancel() → exits

fsync error 2 → channel is empty, goes in (buffered, doesn't block)

fsync error 3 → channel is full (error 2 still in it)
send BLOCKS while holding mutex → deadlock

Like what if this error piles up in fatalErrChan isnt that a deadlock help me out here?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thread 1 returns after sending to fatalErrChan and unlocks the mutex. fatalErrChan is buffered so it won't block.
fatalErrChan will trigger the server to close the wal file. There can be two cases here for thread 2 on acquiring the mutex lock -

  • case1 wal is closed -> thread2 simply returns and unlocks the mutex.
  • case2 wal is not closed yet -> thread2 tries to write and gets error. Sends it to fatalErrChan and returns unlocking the mutex. The previous error wouldn't be there in FatalErrChan as there is nothing blocking the handle interrupt processing. And subsequent calls to cancel function do nothing.

Comment thread internal/wal/wal.go
Comment on lines +55 to +58
if w.fsyncStrategy != ALWAYS {
bytes, err := fmt.Fprintf(w.asyncBuffer, "%s\n", strings.Join(cmd, " "))
return bytes, err
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this never goes to the os only stays in the buffer and fills it up shouldnt we flush this to buffer?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a cron scheduled which does the flushing. But yes the cron is not started in NEVER mode. Good point.

@SantanuKar43
SantanuKar43 requested a review from Priyansh61 April 24, 2026 10:02
@SantanuKar43
SantanuKar43 merged commit 21dd83c into main Apr 25, 2026
1 check passed
@SantanuKar43
SantanuKar43 deleted the m2.1/configurable-fsync-strategy branch April 25, 2026 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants