RavenDB's response to this paper: https://ayende.com/blog/196161-C/re-are-you-sure-you-want-to...
And let's not forget sqlite!
> There can only be a single writer at a time to an SQLite database.
31–40 of 137 posts
RavenDB's response to this paper: https://ayende.com/blog/196161-C/re-are-you-sure-you-want-to...
And let's not forget sqlite!
> There can only be a single writer at a time to an SQLite database.
Earlier quoted context omitted.
> the DB has information on access patterns and table format that the OS is not aware of Aren't system calls such as madvise supposed to allow user space to let the kernel know precisely that information?
The madvise() functions and similar are a blunt and imprecise instrument. The kernel is free to ignore them, and frequently does in practice. It also does not prevent the kernel from proactively doing things you don't want it to do with your buffer pool at the worst possible time. A user space buffer pool gives you precise and deterministic control of many of these behaviors.
In this case, there is the issue of who is the you on question
For the database in isolation, maybe not ideal
For a system whre db and app run on the same machine? The OS can make sure you are on friendly terms and not fighting
Same for trying to SSH to a bust server and the OS can balance things out
Earlier quoted context omitted.
The really key part seems to be this: "If you aren’t using mmap, on the other hand, you still need to handle of all those issues" Which seems like a reasonable statement. Is it less work to make your own top-to-bottom buffer pool, and would that necessarily avoid similar issues? Or is it less work to use mmap(), but address the issues?
I suppose. Some problems with mmap() are a bit hard to fix from user land though. You will hit contention on locks inside the kernel (mmap_sem) if the database does concurrent high throughput mmap()/unmap(). I don't follow linux kernel development closely to know if this has been improved recently, but it was easy to reproduce it 4-5 years ago.
Uou map the file once, then fault it in
Earlier quoted context omitted.
The really key part seems to be this: "If you aren’t using mmap, on the other hand, you still need to handle of all those issues" Which seems like a reasonable statement. Is it less work to make your own top-to-bottom buffer pool, and would that necessarily avoid similar issues? Or is it less work to use mmap(), but address the issues?
When I worked on/with BerkeleyDB in the late 90s we came to the conclusion that the various OS mmap() implementations had been tweaked/fixed to the point where they worked for the popular high profile applications (in those days: Oracle). So it can appear like everything is fine, but that probably means your code behaves the same way as .
You get to take advantage of literally decades of experience
What is more, if you can match the profile of the optimization, you can benefit even more
The pragmatic consideration that usually influences the decision to use mmap() is the large discontinuity in skill and expertise required to replace it. Writing your own alternative to mmap() can be significantly superior in terms of performance and functionality, and often lends itself to a cleaner database architecture. However, this presumes a sufficiently sophisticated design for an mmap() replacement. The learni…
When you say “replacing mmap()”, could you elaborate a bit on it? The way you write it sounds like you’re describing a reimplementation of mmap() with the same API, while I believe the actual goal would be to completely rewrite the persistence and caching layer to be like a “real” database.
For example, while the storage will usually have a linear address space, the "pointer" to that address space won't be a literal pointer even though it may behave much like one. There may be stricter invariants around write back and page fault behavior, and madvise()-like calls have deterministic effects. You often have cheap visibility into details of page/buffer state that you don't get with mmap() that can be used in program logic. And so on. Different but similar.
† https://www.cs.vu.nl/~ast/Publications/Papers/euteco-1988.pd...
RavenDB's response to this paper: https://ayende.com/blog/196161-C/re-are-you-sure-you-want-to...
But then you have a pile of blocking-style synchronous code likely exploiting problematic assumptions to rewrite when you realize you want something that doesn't just work, but works well.
RavenDB's response to this paper: https://ayende.com/blog/196161-C/re-are-you-sure-you-want-to...
You don't want the OS to take care of reading from disk and page caching/eviction. You want the DB itself to have explicit control over that, because the DB has information on access patterns and table format that the OS is not aware of. It is better equipped than the OS to anticipate what portions of tables/indices need to be cached in memory. It is better equipped to calculate when/where/what/how much to prefetch f…
If your database server is the only process in the system that is using significant memory, then sure, you might as well manage it yourself. But if there are multiple processes competing for memory, the kernel is better equipped to decide which processes' pages should be paged out or kept into memory.
why settle for errno when you can have a segfault.
Yup. Why use the operating system's async I/O system when you can simply burn a thread and do blocking I/O? Been down that primrose path, have the road rash to prove it. mmap() is great until you realize that pretty much all you've avoided is some buffer management that you probably need to do anyway. The OS just doesn't have the information it needs to do a great (or even correct) job of caching database pages.