1,112 karma · joined March 5, 2015
https://github.com/tvondra/
For example, I see they do this for Postgres:
`let max_wal_gb = (shared_buffers_gb).clamp(2, 16);`
2-16GB of WAL is not a lot, but I have no idea how large is the data set.
- I'm not sure how to interpret the Figure 1. It says "Flash writes (KB) per page", but it doesn't really say which page sizes were used. AFAIK MySQL has 16K by default, PostgreSQL has 8K, LeanStore has 4K, but that which makes the numbers a bit hard to compare.
- Likewise, I'm a bit unsure about the doublewrite buffering in Postgres, described as "indirect". Postgres doesn't really do doublewrite (we really should, I think), we write pages to WAL and then to data files. I assume that's what is meant by "indirect" in the paper. But this very much depends on the checkpoint frequency and write pattern, as the FPI is written only for the first page change. I wonder if the results in the paper consider this. Maybe the workload is such that it always hits the page just once between checkpoints (i.e. a worst case). Also, the WAL part is nicely sequential, which should play nice with SSDs.
fio --filename=/dev/md127 --direct=1 --rw=randread --bs=8k --ioengine=io_uring --iodepth=1 --runtime=120 --numjobs=1 --time_based --group_reporting --name=iops-test-job --eta-newline=1 --readonly
i.e. with iodepth=1 and numjobs=1. Because this is what "mimics" index scan (without prefetch) on cold data. More or less.
The command I posted earlier does ~10GB/s on my RAID, which matches your data.
I wouldn't be all that surprised if this was (partially) due to Postgres being less optimized back then, which might have hidden some of the random vs. sequential differences. But that's just a wild guess.
I've observed exactly this behavior on a wide range of hardware / environments, it's not very specific to particular SSDs models (at least not for reads, which is what the blog post was measuring). That's why I showed results from three very different systems.
Some information for the two physical machines:
1) ryzen: Ryzen 9 9900X, RAID0 with 4x Samsung 990 PRO 1TB (in Asus Hyper M.2 Gen5 card)
2) xeon: E5-2699v4, WD Ultrastar DC SN640 960GB (U.3)
I don't know what exactly is backing the SSD storage on the Azure instance.
For example, I have a RAID0 with 4 SSDs (Samsung 990 PRO, so consumer, but quite good for reads). And this is what fio says:
# random reads, 8K, direct IO, depth=1
fio --filename=device name --direct=1 --rw=randread --bs=4k --ioengine=libaio --iodepth=256 --runtime=120 --numjobs=4 --time_based --group_reporting --name=iops-test-job --eta-newline=1 --readonly
-> read: IOPS=19.1k, BW=149MiB/s (156MB/s)(4473MiB/30001msec)
# sequential reads, 8K, direct IO, depth=1
fio --filename=/dev/md127 --direct=1 --rw=read --bs=8k --ioengine=io_uring --iodepth=1 --runtime=30 --numjobs=1 --time_based --group_reporting --name=random-1 --eta-newline=1 --readonly
-> read: IOPS=85.5k, BW=668MiB/s (700MB/s)(19.6GiB/30001msec)
With buffered I/O, random read stay at ~19k IOPS, while sequential reads get to ~1M IOPS (thanks to read-ahead, either at the OS level, or in the SSD).
So part of this is sequential reads benefiting from implicit "prefetching", which reduces the observed cost of a page. But for random I/O there's no such thing, and so it seems more expensive.
It's more complex (e.g. sequential reads allow issuing larger reads), of course.
As for indexes, it can help, but not in this particular example - the "code" tables are tiny, and the planner adds Memoize nodes anyway, so it acts like an ad hoc index.
Indexes are more of a complementary improvement, not an alternative to this optimization (i.e. neither makes the other unnecessary). FWIW in this case the indexes won't help very much - if you use more data in the code tables, it'll use a hash join, not nested loop / merge join.
That doesn't mean we couldn't do better with indexes, there probably are smart execution strategies for certain types of queries. But indexes also come with quite a bit of overhead (even in read-only workloads).
I believe that's one of the reasons why it took about ~8 years (the original patch was proposed in 2017).
Some of these limitations are mostly due to Postgres design, no doubt about that.
With io_uring everything happens in the backend process, and so consumes some of the CPU time that might otherwise be spent executing the query. All the checksum verification, memcpy into shared buffers, etc. happen in the backend. And those things can be quite expensive. With worker this happens in the other processes, spreading the overhead.
Of course, on truly I/O-bound workload (actually waiting on the I/O), this may not be a huge difference. For warmed-up cases it may be more significant.
Sorry, should have mentioned that in the blog post.
Those are good guesses, IMHO.
For sequential scans, some of the "async" work could be done by kernel read-ahead, but AIO makes it explicit and loads the data into shared buffers, not just page cache. For bitmap scans we already had prefetching by fadvise, which is somewhat similar to read-ahead (also into page cache), and there were some bugs that made it ineffective in some cases, and AIO fixes that.
For index scans the difference can be an order of magnitude (say, 5-10x). Doing random I/O block by block is simply awful, prefetching data is important. I was just doing some testing on TPC-H, and on scale 50 I see Q8 going from 130s to 20s, and Q19 from 50s to 8s. And smaller improvements for a couple more queries. Of course, it depends on what else the query is doing - if it's spending 1% on the index, you won't notice a difference.
At least that's how I see it right now, we'll see how that works on a much wider range of hardware and systems. The github repo linked from the pgsql-hackers post has a lot more results, some charts include results for the index prefetching patch - and there it makes more difference in some cases. But the patch is still fairly rough, it could be a bug in it too, and it changed a lot since August.
The reasoning was roughly:
* Mordor is obviously meant to be USSR, as it's in the east.
* The orcs are clearly heavy industry workers, building the world of future.
* Bilbo is obviously a son from a bourgeoisie family, disgusted by hard work.
* The west is represented by elves = aristocracy, people = bourgeoisie, hobbits = landowners.
* The group of reactionaries are afraid of a made up "threat from the east", led by Gandalf.
* Gandalf = a reactionary ideologue, keeping people in state of fear of progress and knowledge.
* Saruman = protector of the oppressed, declared a traitor and destroyed by the reactionaries.
* But socialism can't be destroyed by throwing something in the fire. All the power to Mordor, surrounded by reactionary neighbors.
This is how "talking to AI" feels like for anything mildly complex.
In several such cases, the company was repeatedly warned about how they implemented some functionalities, and that it will cause severe issues with bloat/vacuuming, etc. Along with suggestions how to modify the application to not hit those issues. Their 10x engineers chose to completely ignore that advice, because in their minds they constructed an "ideal database" and concluded that anything that behaves differently is "wrong" and it's not their application that should change. Add a dose of politics where a new CTO wants to rebuild everything from scratch, engineers with NIH syndrome, etc. It's about incentives - if you migrate to a new system, you can write flashy blog posts how the new system is great and saved everything.
You can always argue the original system would be worse, because everyone saw it had issues - you just leave out the details about choosing not to address the issues. The engineering team is unlikely to argue against that, because that'd be against their interests too.
I'm absolutely not claiming the problems do not exist. They certainly do. Nor am I claiming Postgres is the ideal database for every possible workload. It certainly is not. But the worst examples that I've seen were due to deliberate choices, driven by politics. But that's not described anywhere. In public everyone pretends it's just about the tech.
For backups, I don't them the qubes way, I do "regular" backups within VM using rsync/duplicity/... When moving to a new machine I prefer to setup everything from scratch (and then restore the data). And it gives me all the features like incremental backups etc.
It often helped to actually give the VM more cores (not just the default 2), but sometimes it was due to some weirdo codec/quality setting, and recoding the video just solved it. Sometimes switching to vlc (from mplayer) helped. Other times it was simply due to the sys-usb vm being overloaded.
When I had similar issues in the past, I posted a question either to the mailing list or forum, and people were helpful.
I understand the usual story is that the goal is security benefits, and the compartmentalization (or rather the implied inconvenience) is the price for that. But for me the compartmentalization turned out to be a benefit on it's own, and actually convenient.
I find it extremely convenient to have multiple isolated / virtual workspaces for different stuff, even if you assume attackers / malice do not exist. Having separate VMs is not the same as having separate folders. I also love the VM templates, which allow me to do all kinds of experiments (e.g. install packages in the app VM, which disappear after restart). Or run VMs with a mix of distros/versions/... Yes, I could do some of that with plain VMs, but Qubes integrates that in a way that I find very convenient. The commands for copying stuff between VMs are muscle memory at this point.
Yes, there are limitations, like the lack of GPU acceleration. But movies in 1080p play just fine without it, and I'm not a gamer, so I don't mind much. I can't play with CUDA etc. on these QubesOS machines, and scrolling web pages with large images is laggy, but I find this to be an acceptable price.
I went through multiple laptops / workstations over the years, and the situation improved a lot I think. Initially I had to solve quite a few issues with installer, some hardware not working (or requiring setting something special), or poor battery life on the laptops. But after a while that mostly either went away, especially once I switched to laptops with official Linux support (Dell Precision were good, I'm on Thinkpad P1 G7 now). The battery life is pretty decent too (especially once I disabled HT in BIOS).
Is it perfect for everyone? No, certainly not. But it sure is great for me, and I hope they keep working on it.
Anyway, I have no idea what would it take to do something like that in Postgres, I'm not familiar with this sfuff. But if someone submits a patch with some measurements, I'm sure we'll take a look.