HNHacker News
TopNewBestAskShowJobs

tanelpoder

6,486 karma · joined July 15, 2018

A long-time computer performance nerd, creator of 0x.tools

blog: tanelpoder.com

submissionscomments
tanelpoder··on What's new in the Postgres 16 query planner
One way to look at this is that the most accurate way to "estimate" how fast a certain plan would run, is to actually run it on the full dataset. But that obviously doesn't make sense, as the optimizer is expected to come up with a plan in matter of milliseconds (or less for simple queries) and you don't want your "optimizer stats" to be as big as the whole dataset itself. So optimizer has limited information, by design, and it has to come up with _something_ in a very short amount of time.

I don't know much about Postgres optimizer, but I imagine that in addition to table/column stats, is also uses structural info as its inputs, like existence of (enabled & valid) constraints for example. If the optimizer knows that some column never has NULLs or is guaranteed to be unique, all kinds of transformation & shortcuts become possible.

(There are plenty of large big-vendor ERP/CRM/etc apps out there that do not use DB constraints for the sake of "portability"... not fun to work with these).

tanelpoder··on What's new in the Postgres 16 query planner
Indeed, hints are super-useful (essential!) for applying quick fixes when something unexpected suddenly happens in the optimizer's magic. Or you just want to instruct/nudge the optimizer towards doing the right thing, if you know the shape of your data and optimizer can't see it or doesn't act on it correctly for some reason. The downside is that people who don't really know what exactly they want to achieve, will start applying incomplete sets of hints in random locations, based on Internet searches. And sometimes you'd even get lucky, that single index hint makes the problem go away - for a while!

And few people tend to remove hints after DB version upgrades, where the optimizer magic (or your table stats) have improved. Now you're limiting optimizer's choices. That's been a problem (by now) for decades in the Oracle world with lots of legacy SQL code full of random hints where some of them aren't even valid anymore, but others still are - and limit optimizer's choices.

At least Oracle folks had enough at some point and introduced an "optimizer_ignore_hints" parameter [1], so all legacy hints that were added 20 years ago just get ignored - and the modern optimizer does a much better job getting things right.

I do regularly use hints in SQL tuning and troubleshooting experiments, just to verify and prove that a better plan is theoretically and physically possible - and if yes, then go from there. When the (deliberately placed) hints make the query faster, the next step is to check the hinted, faster plan's optimizer cost estimate and drill down from there: Why did optimizer think that the other plan was cheaper or why did the optimizer think that the faster plan was more expensive. Then you end up with measuring row-count misestimates, etc...

But yes, plenty of people (including myself) have made legacy Oracle apps run much more efficiently and faster just by globally telling the DB to stop paying attention to all the old random hints lingering on and gathering object stats using the modern settings & defaults (doesn't always work though).

[1] https://docs.oracle.com/en/database/oracle/oracle-database/1...

tanelpoder··on ML Engineering Online Book
Yes - understand first, then fix. And you’ll understand by measuring/profiling things.

I’d also recommend the detailed pytorch optimization case studies by Paul Bridger:

https://paulbridger.com/

tanelpoder··on Ask HN: Opened a LLC in USA, where should I look for clients?
Would it be correct to expand that the clients are in crypto-trading and crypto-finance?
tanelpoder··on Dell XPS laptop gets a 2024 overhaul with XPS 13, XPS 14, and XPS 16 laptops
What’s the power brick like these days?
tanelpoder··on Why use strace in 2023? [video]
The safer/non-slowing down alternative for tracing syscalls would be "perf trace" (and eBPF scripts), but I've found in past that perf trace didn't decode enough syscall arguments (and just listed pointers to structs, where strace showed the info inside these structs). But I just ran a few simple "perf trace" commands on RHEL 9, looks like it has caught up somewhat.
tanelpoder··on Why use strace in 2023? [video]
man fs_usage (report system calls and page faults related to filesystem activity in real-time :-)
tanelpoder··on Why use strace in 2023? [video]
Check out strace -y and strace -yy (--decode-fds)
tanelpoder··on Rest in Peace, Optane
You can design for that. For example, when building a persistent-memory native database engine, you probably need some sort of data versioning anyway - either Postgres style multi-version rows (or some other memory structures) that later need to be vacuumed or Oracle/InnoDB style rollback segments that hold previous values of some modified objects. Then you probably want WAL for efficient replication to other machines and point in time recovery (in case things go wrong or just DB snapshots for dev/test).

Transient & disposable memory structures like keeping track who's logged in or compiled SQL execution plans that facilitate access to the persistent "business data", much of that stuff will need to be in RAM/HBM/CPU cache anyway, for performance reasons and as these things do not necessarily need to persist across a crash/reboot. The data (and likely indexes, etc) need to. But you won't need a buffer cache manager that copies entire blocks around from storage to different places in memory and vice versa. Your giant index or graph could rely just on direct memory pointers instead of physical disk block addresses that need to get read to somewhere in memory and then are accessed via various hashtable lookups & indirect pointers. And you don't have to ship entire 512B-8kB blocks around just to access the next index/graph pointer, just access only the relevant cache line, etc.

With proper design, you'd still have layers of code that take care of coherency, consistency and recovery...

tanelpoder··on Rest in Peace, Optane
As it's part of the memory domain, not some external block device, the CPU caches can cache it (64B cache line sizes) and maintain cache coherency across CPUs, NUMA nodes (and soon with CXL 3.x ?) across memory pools shared by many servers. So your programming model will be just using CPU loads & stores to access the individual bytes you need directly from the Optane storage, instead of having to do some 512B or 4kB DMA or memcpy to RAM first and then access what you needed. And it's persistent, so you won't need to have a separate layer of code for persisting your "cache" of data... One can ditch the "database block I/O" and "buffer cache" notion and just treat Optane as byte-addressable RAM on a server that will never reboot or crash... Of course in reality your server can always catch fire or have a hardware malfunction, so you'd need to replicate your data to some distant enough backup or DR instance... which (at least in mission-critical database context) negates some of the value of persistent low-latency I/O... If you need to wait for 1+ms for the remote WAL write to be acknowledged from a different AZ or region anyway, then having an 1 us local Optane write is not gonna change the whole commit latency that radically.
tanelpoder··on Rest in Peace, Optane
Yes, which made it even more confusing, why call the Optane-cached consumer NAND disks "memory" ... but perhaps they thought that it's easier to fool the consumer segment (?)
tanelpoder··on Rest in Peace, Optane
mmap on Optane direct-access-aware (DAX) filesystems like EXT4/XFS now, is not like mmap on block devices where the OS gets in your way and pages stuff in from disk and (maybe) later syncs it back to persistent storage. Optane is the persistent storage, it's just usable/addressable as regular RAM as it's plugged in to DIMM slots.

And in the later Xeon architecture (Xeon Scalable 3rd gen, I think), intel expanded the persistence domain to CPU caches too. So, you didn't even have to bother with CLFLUSH and CLWB instructions to manually ensure that some cache lines (not 512B blocks, but 64B cache lines) get persisted. You could operate in the CPU cache and in the event of power loss, the CPU/mem controllers/and the capacitors on Optane DCPMMs ensured that the dirty cache lines got persisted to Optane before the CPU lights went off. But all this coolness a bit too late...

Another note: Intel's marketing had terrible naming for Optane stuff. Optane DCPMMs are the ones that go into DIMM slots and have all the cool features. Optane Memory SSDs (like Optane H10) are just NAND SSDs with some Optane cache in front of them. These are flash disks, installed in PCIe slots but Intel decided to call these disks "Optane Memory" ...

tanelpoder··on Rest in Peace, Optane
Yeah I'm sad to see Optane go. I bought a few DCPMMs myself (and had to upgrade my workstation CPUs to support them) to test out the capabilities and maybe even write a little toy OS/KV-store engine that runs as a multithreaded process in Linux using mmap'ed Optane memory as its persistent datastore (never got to the latter part). The "do not use mmap for databases" argument would not apply here as you wouldn't cache persistent block devices to RAM, but the "RAM" itself is persistent, no writeback or block disk I/O is needed.

Intel discontinued/deprecated Optane, before I could do anything really cool with it. But Intel can probably still reuse lots of their cache coherency logic for external CXL.mem device access.

One serious early adaptor and enterprise user of Optane tech was Oracle. More specifically Oracle's Exadata clusters (where database compute nodes are disaggregated from storage nodes that contained Optane) and connected via InfiniBand or RoCE. And since Optane is memory (memory addressable), they could skip OS involvement and some of the interrupt handling when doing RDMA ops directly to/from Optane memory located inside different nodes of the Exadata cluster. I think they could do 19 microsecond 8kB block reads from storage cells and WAL sync/commit times were also measurable in microseconds (if you didn't hit other bottlenecks). They could send concurrent RDMA write ops (to remote Optane memory) for WAL writes into multiple different storage nodes, so you could get very short commit times (of course when you need sync commits for disaster recovery, you'd have to pay higher latency).

With my Optane kit I tested out Oracle's Optane use in a single-node DB mode for local commit latency (measured in a handful of microseconds, where the actual log file write "I/O" writes were sometimes even sub-microsecond). But again, if you need sync commits across buildings/regions for disaster recovery and have to pay 1+ ms latency anyway, then the local commit latency advantage somewhat diminishes. I have written a couple of articles about this, if anyone cares: [1][2].

Fast forward a few years, Oracle is not selling Exadata clusters with PMEM anymore, but with XMEM, which is just RAM in remote cluster nodes and by using syscall-less RDMA ops, you can access it with even lower latency.

[1] - https://tanelpoder.com/posts/testing-oracles-use-of-optane-p... [2] - https://tanelpoder.com/posts/testing-oracles-use-of-optane-p...

tanelpoder··on Gron: Make JSON greppable
I like how the description is just 3 words and clearly communicates what this tool is about.
tanelpoder··on In OpenZFS and Btrfs, everyone was just guessing
Somewhat related, RedHat withdrew from the attempt to productionize BRTFS, apparently it was fully removed in RHEL 8:

- https://access.redhat.com/solutions/197643

Also, there's a PDF doc (from a conference presentation), covering many layers of potential alternatives for ZFS features:

- https://news.ycombinator.com/item?id=38484598

But "just" slapping all these layers on each other (configuring each individually and then hoping for the best) doesn't seem like the best idea for production systems either.

I guess back in the Sun/Solaris days, people still had the luxury of releasing (major) features in major versions, every few years instead of weeks or months... and as far as storage, backup, security solutions go - can't really do this right with the move fast & break things culture...

tanelpoder··on After Boeing declines to pay up, ransomware group leaks 45 GB of data
Didn't think of that, thank you.
tanelpoder··on After Boeing declines to pay up, ransomware group leaks 45 GB of data
Wouldn't it be easy to just pick a new name for the ransomware group then?

(or do we need eBay-like "seller ratings" and customer reviews for ransomware groups?)

tanelpoder··on eBPF-based auto-instrumentation outperforms manual instrumentation
So how would you demand that they’d be created in a new process? I was already using pid* provider years ago when I was working on this (and wasn’t using static compiled-in tracepoints).
tanelpoder··on eBPF-based auto-instrumentation outperforms manual instrumentation
DTrace (on Solaris at least) can instrument any userspace symbol or address, no need for static tracepoints in the app.

One problem that DTrace has is that the "pid" provider that you use for userspace app tracing only works on processes that are already running. So, if more processes with the executable of interest launch after you've started DTrace, its pid provider won't catch the new ones. Then you end up doing some tricks like tracking exec-s of the binary and restarting your DTrace script...

tanelpoder··on Not knowing the /proc file system
Same here, you can get pretty far with just catting, grepping, awk/sed/sort/uniq'ing all the various /proc entries. And not only /proc/PID/stuff, but also each individual thread (task) state from /proc/PID/task/TID/* too.

Initially I wrote a python program for flexible querying & summarizing of what the threads of interest are doing (psn) and then wrote a C version to capture & save a sampled history of thread activity (xcapture) [1]. I ended up spending too much time optimizing the C code - as just formatting strings taken from /proc pseudofiles and printing them out took very little time compared to the kernel-dives when extracting things like WCHAN and kernel stack via the proc intereface.

That's why I've since built an eBPF prototype for sampling the OS thread activity. The old approach still works even on RHEL5 machines with 2.6.x kernels without root access too :-)

[1] https://0x.tools/#usage--example-output

tanelpoder··on AMD Ryzen Threadripper Pro 7000 CPUs: Up to 96 Zen 4 Cores for Workstations
For me it was just convenience - I bought a complete workstation (tower) with that CPU in it (and with all its capabilities, like 128 PCIe lanes and 8 memory channels). Does the EPYC server chip use a different socket (?), so I'd have to build a tower workstation from the components myself, a server mobo, server CPU squeezed into a tower?
tanelpoder··on AMD Ryzen Threadripper Pro 7000 CPUs: Up to 96 Zen 4 Cores for Workstations
Supposedly should be officially announced today.
tanelpoder··on Cockpit: Web-based graphical interface for servers
I ended up reading more about this and looks like SSHD in Ubuntu 22.10 and later also uses systemd socket activation. So there should be no sshd process(es) started until someone SSHs in!

https://discourse.ubuntu.com/t/sshd-now-uses-socket-based-ac...

tanelpoder··on Ask HN: Show me your half baked project
I will replace myself with a bunch of nested loops and if-then-else statements and retire after that:

https://oxtp.com

tanelpoder··on My trip to the Communication and Laptop Museum in Estonia
This is probably a decent start, there are useful references & further reading links in the end:

https://en.wikipedia.org/wiki/Soviet_deportations_from_Eston...

tanelpoder··on My trip to the Communication and Laptop Museum in Estonia
I (being an Estonian), recently started using the phrase "was occupied by USSR..." instead of "was part of USSR". We never wanted to be a part of that evil empire and never _formally_ were (when looking in from outside), so after seeing someone point it out in a forum, I also started usign the better description.

But yeah, USSR didn't manage to break our culture (and our own language is a noteworthy part of that). Although there was corruption in various government institutions after USSR collapse, systemic open corruption wasn't part of our culture.

Most (many?) people are ok to work for their own success instead of cheating others as the first choice, that helps the startup culture. And Skype is the most notheworthy company affecting Estonian startup culture. Although not founded/funded by Estonians, the tech & business was built in Estonia from scratch, by mostly Estonians. And now there are multiple generations of ex-Skypers who've successfully built startups & businesses more than once.

Culture & neighbors - that's what I usually tell other people, when they ask about our quick recovery after the USSR occupation.

tanelpoder··on PostgreSQL: No More Vacuum, No More Bloat
> You generally want to keep your CPU fully utilized.

Not in real life concurrent systems where latency matters. In addition to the queuing/random request arrival rate reasons, all kinds of funky latency hiccups start happening both at the DB and OS level when you run your CPU average utilization near 100%. Spinlocks, priority inversion, etc. Some bugs show up that don’t manifest when running with lower CPU utilization etc.

tanelpoder··on Ask HN: Could you share your personal blog here?
https://tanelpoder.com

Mostly about systematic troubleshooting of Linux and SQL tuning (mostly Oracle stuff, but the concepts are universal)

tanelpoder··on Everything that uses configuration files should report where they're located
There's also fs_usage that doesn't require disabling SIP:

https://mohit.io/blog/fs_usage-trace-file-system-calls-on-ma...

tanelpoder··on My Inventions – Nikola Tesla (1919)
When I come up with something new and complex (either something that qualifies as an invention or just trying to solve a complex data analysis problem using a single SQL statement), I tend to first have a big blur in my brain... And then it may feel promising... and then individual structural components of the final solution start to emerge non-visually (like where to apply recursion in SQL that generates data for the remaining layers)... it's more like that I feel that there are some solid parts (vs entropy?) in that blob... the whole thing doesn't fully make sense until the last important component has "manifested" itself. Nothing visual though and often I have to "roll back" to the blurry blob from half an hour ago and wait until something better manifests itself from there. Doesn't always work and sleep helps! :-)
← PreviousPage 8 of 13Next →