Live data from Hacker News

Why `fsync()`: Losing unsynced data on a single node leads to global data loss

redpanda.com

21–30 of 47 posts

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#21

I'm pretty sure Redpanda has identified a real issue here, but my only response to any situation where you need to be absolutely, positively, 100% sure that `fsync()` has done The Right Thing would be: "Good luck with that!" Even in a relatively simple modern storage stack, say a single NVMe Flash device on a local PCIe controller, the question 'are these exact bits irrevocably committed to the media?' is pretty much…

" the question 'are these exact bits irrevocably committed to the media?' is pretty much impossible to answer" Well, kind of. fsync()'s job is only to ensure caches are written to durable storage. Its job is not to ensure the integrity of durable storage. Your idea of fsync()'s "Right Thing" is not quite correct, because these types of durable storage failures can happen outside of the context of a write -- so it's a…

> Again, fsync()'s job is only to ensure the data is moved to durable storage.

The problem is that every layer in the stack lies. They say "yes it is definitely written to durable storage" when it is just in some cache layer and about to be written.

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#22

Protocol Aware Recovery is really needed if you want Raft to tolerate disk corruption. https://www.usenix.org/conference/fast18/presentation/alagap...

the blog posts mentions that it is for any protocol that is non bft

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#23
I'm confused here. If I'm reading this correctly, the following is happening:

- Node 3 is the leader.

- Node 1 is isolated (failure #1).

- 10 records are written. They are successful because a majority is still alive (persisted to Node 2 and 3).

- Node 3 loses data (failure #2).

- Node 1 comes back up again.

However, isn't this two failures at the same time? Kafka with three nodes can only guarantee a single failure, no?

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#24
post #19
post #9

Earlier quoted context omitted.

> sing fsync() to flush data to disk is, generally speaking, the wrong way to do things. I think this is an old "statement" due to the Linux ext4 sync issue from quite awhile ago. As far as I know it has been fixed. I doubt it is discouraged on the BSDs. But, curious, what is the Right Thing to do ? There are cases where you want to be sure the data reaches the platter. On a mini I use to program on, if a filename st…

I stand by my position. The problem with fsync() is the question of when and where do errors get reported. If code checks errors on completion of each write it becomes significantly easier to know what write has failed. The error reporting is the granularity of the write being performed. In contrast, fsync() has to report errors for everything that has happened since the last fsync() call. If you are doing anything c…

it tends to be true. we do things at the application tier to minimize these things.

for example, assume you have to write A, B, C ... in syscalls it would be

write( A ), flush() write( B ), flush() write( C ), flush()

so if you add a debounce of say 4ms you get

Write( A ), Write( B ), Write( C ), Flush()

and saved 2 flush()-es

This is common with protocol aware storage applications.

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#25
post #19

Earlier quoted context omitted.

I stand by my position. The problem with fsync() is the question of when and where do errors get reported. If code checks errors on completion of each write it becomes significantly easier to know what write has failed. The error reporting is the granularity of the write being performed. In contrast, fsync() has to report errors for everything that has happened since the last fsync() call. If you are doing anything c…

it tends to be true. we do things at the application tier to minimize these things. for example, assume you have to write A, B, C ... in syscalls it would be write( A ), flush() write( B ), flush() write( C ), flush() so if you add a debounce of say 4ms you get Write( A ), Write( B ), Write( C ), Flush() and saved 2 flush()-es This is common with protocol aware storage applications.

And I guess the idea is furthermore that just because you don't fsync after every write does not mean that you haven't fsync-ed before responding to the user request saying the data is stored durably. I assume that you do actually guarantee the flush before returning a success to the user.

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#26
post #21

Earlier quoted context omitted.

" the question 'are these exact bits irrevocably committed to the media?' is pretty much impossible to answer" Well, kind of. fsync()'s job is only to ensure caches are written to durable storage. Its job is not to ensure the integrity of durable storage. Your idea of fsync()'s "Right Thing" is not quite correct, because these types of durable storage failures can happen outside of the context of a write -- so it's a…

> Again, fsync()'s job is only to ensure the data is moved to durable storage. The problem is that every layer in the stack lies. They say "yes it is definitely written to durable storage" when it is just in some cache layer and about to be written.

> it is just in some cache layer and about to be written

Definitely not. I get that sometimes we find things that do lie, but lying about this is a huge P0 bug and everyone with an interest in data storage knows to be on the lookout for such brokenness. E.g. such people do not buy SSD that lack some sort of power fail flush protection.

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#27

Earlier quoted context omitted.

it tends to be true. we do things at the application tier to minimize these things. for example, assume you have to write A, B, C ... in syscalls it would be write( A ), flush() write( B ), flush() write( C ), flush() so if you add a debounce of say 4ms you get Write( A ), Write( B ), Write( C ), Flush() and saved 2 flush()-es This is common with protocol aware storage applications.

And I guess the idea is furthermore that just because you don't fsync after every write does not mean that you haven't fsync-ed before responding to the user request saying the data is stored durably. I assume that you do actually guarantee the flush before returning a success to the user.

exactly. you improve latency and throughput at the same time. is kinda cool. by delaying the reponses just a small bit you get huge benefits

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#28
post #23

I'm confused here. If I'm reading this correctly, the following is happening: - Node 3 is the leader. - Node 1 is isolated (failure #1). - 10 records are written. They are successful because a majority is still alive (persisted to Node 2 and 3). - Node 3 loses data (failure #2). - Node 1 comes back up again. However, isn't this two failures at the same time? Kafka with three nodes can only guarantee a single failure,…

I don't know what consistency Kafka is targeting but usually with 'consistent' systems in the situation where the cluster cannot serve valid data it should serve failure responses instead of giving back bogus data. if your system is 'eventually consistent' then that's a different game.

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#29

I'm pretty sure Redpanda has identified a real issue here, but my only response to any situation where you need to be absolutely, positively, 100% sure that `fsync()` has done The Right Thing would be: "Good luck with that!" Even in a relatively simple modern storage stack, say a single NVMe Flash device on a local PCIe controller, the question 'are these exact bits irrevocably committed to the media?' is pretty much…

> Even in a relatively simple modern storage stack, say a single NVMe Flash device on a local PCIe controller, the question 'are these exact bits irrevocably committed to the media?' is pretty much impossible to answer without an NDA with the disk manufacturer and a hefty dose of proprietary IOCTLs (and even then, I would not bet my life on it).

This would limit throughput quite a bit and might significantly shorten the lifespan of the disk, but you could put the disk on a separate power supply that the computer could control. Don't consider data as written until you've power cycled the disk and been able to read that data back. :-)

Re: Why `fsync()`: Losing unsynced data on a single node leads to global data loss

#30
post #23

I'm confused here. If I'm reading this correctly, the following is happening: - Node 3 is the leader. - Node 1 is isolated (failure #1). - 10 records are written. They are successful because a majority is still alive (persisted to Node 2 and 3). - Node 3 loses data (failure #2). - Node 1 comes back up again. However, isn't this two failures at the same time? Kafka with three nodes can only guarantee a single failure,…

Strongly consistent protocols such as a Paxos and Raft always choose consistency over availability and when consistency isn't certain they refuse to answer.

Raft & Paxos: any number of nodes may be down, as soon as the majority is available a replicated system is available and doesn't lie.

Kafka as it's described in the post(): any number of nodes may be down, at most one power outage is allowed (loss of unsynced data), as soon as the majority is available a replicated system is available and doesn't lie.

The counter-example simulates a single power outage

() https://jack-vanlightly.com/blog/2023/4/24/why-apache-kafka-...

Post reply on HN