On 1/16/25 10:36 AM, Theodore Ts'o wrote:
On Thu, Jan 16, 2025 at 08:59:19AM -0500, Chuck Lever wrote:
See my previous reply in this thread: WRITE_SAME has a long-standing
existing use case in the database world. The NFSv4.2 WRITE_SAME
operation was designed around this use case.
You remember database workloads, right? ;-)
My understanding is that the database use case maps onto BLKZEROOUT
--- specifically, databases want to be able to extend a tablespace
file, and what they want to be able to do is to allocate a contiguous
range using fallocate(2), but then want to make sure that the blocks
in the block are marked as initialized so that future writes to the
file do not require metadata updates when fsync(2) is called.
Enterprise databases like Oracle and db2 have been doing this for
decades; and just in the past two months recently I've had
representatives from certain open source databases ask for something
like the FALLOC_FL_WRITE_ZEROES.
So yes, I'm very much aware of database workloads --- but all they
need is to write zeros to mark a file range that was freshly allocated
using fallocate to be initialized. They do not need the more
expansive features which as defined by the SCSI or NFSv4.2. All of
the use cases done by enterprise Oracle, db2, and various open source
databases which have approached me are typically allocating a chunk
of aligned space (say, 32MiB) and then they want to initalize this
range of blocks.
This then doesn't require poison sentinals, since it's strictly
speaking an optimization. The extent tree doesn't get marked as
initalized until the zero-write has been commited to the block device
via a CACHE FLUSH. If we crash before this happens, reads from the
file will get zeros, and writes to the blocks that didn't get
initialized will still work, but the fsync(2) might trigger a
filesystem-level journal commit. This isn't a disaster....
Now, there might be some database that needs something more
complicated, but I'm not aware of them. If you know of any, is that
something that you are able to share?
Any database that uses a block size that is larger than the block
size of the underlying storage media is at risk of a torn write.
The purpose of WRITE_SAME is to demark the database blocks with
sentinels on each end of the database block containing a time
stamp or hash.
If, when read back, the sentinels match, the whole database
block is good to go. If they do not, then the block is torn
and recovery is necessary.
--
Chuck Lever