6,486 karma · joined July 15, 2018
blog: tanelpoder.com
When 3000-series was launched, it was first OEM only (Lenovo) but later became available in retail too.
[1] https://www.amazon.com/AMD-ThreadripperTM-PRO-5975WX-64-Thre...
Yep, the platform is 2 years old, but supports both the Zen2 and current Zen3 CPUs (but not PCIe5.0 & DDR5 as Zen 4 requires a different CPU socket and is only announced right now, not available from AMD until the end this month).
However, 8 x DDR4 channels and 128 x PCIe4.0 lanes still give you better total bandwidth than 2 x DDR5 and 24 x PCIe5.0 like the few currently available DDR5/PCIe5 platforms support.
[1] https://tanelpoder.com/posts/11m-iops-with-10-ssds-on-amd-th...
[1] https://tanelpoder.com/posts/testing-oracles-use-of-optane-p...
Edit: I'm still keeping my Optane DIMMs (called DCPMMS - data center persistent memory modules), I just love the tech adventure of having persistent RAM. Should try to write an experimental OS or something (but I also know that's not gonna happen :)
* "Fixes an issue in Safari where a tab may revert back to a previous page"
Maybe related?
$ ls -l /proc/$$/stack
-r-------- 1 tanel tanel 0 May 26 21:52 /proc/967141/stack
$
$ cat /proc/$$/stack
cat: /proc/967141/stack: Permission denied
$
$ sudo cat /proc/$$/stack
[<0>] do_wait+0x1c3/0x230
[<0>] kernel_wait4+0xaf/0x150
[<0>] __do_sys_wait4+0x85/0x90
[<0>] __x64_sys_wait4+0x1e/0x20
[<0>] do_syscall_64+0x49/0xc0
[<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Edit: Adding one more comment - my impression has been that the "no userland-visible changes" promise applies to system calls - how procfs presents data as human-readable text in the /proc files has changed every now and then before (I recall the sar command showing wrong numbers after a kernel update, for example).A quick way to check if PMU access is enabled is this:
dmesg | grep "Performance Events"
Edit: Oh, unfortunately VMware Fusion 12 (on Mac OSX Intel) does not expose the performance counters to the VM anymore, as it's using the OSX Hypervisor Framework instead of its own kernel module.1. db file async I/O submit
2. db file parallel write
(the 2nd one has such a name for historical reasons, but it's the I/O reaping/completion check timing, not the submission).
But I'm talking about the cases where the app is done with the other work and needs to ensure that the previous write is persisted (for example to a write ahead log), before moving on? It will have to deliberately wait for I/O completion now, thus will run io_getevents() with the "willing to wait" mode enabled. I see this in Oracle database world all the time and MySQL world occasionally too:
- Not seeing a high number of threads in D state or PSI IO figure does not mean that there are no threads waiting for I/O
- Seeing a high number of threads in D state and high PSI IO figure means that there are threads waiting for I/O (but possibly even more, if you'd look into the ones in S state, but in io_getevents syscall, with WCHAN=read_events.
So, the I/O component of Linux system load and PSI do not include the async I/O waiting threads that decide to synchronoysly wait for asynchronously submitted I/O requests :-)
I see MySQL is using libaio in some places too (the io_submit/io_getevents show up in syscalls), but I haven't looked deeper into whether the getevents are "willing to wait" or not. But any application using libaio, that at some point uses io_getevents() in "willing to wait" mode, would be affected by this discrepancy.
But yeah, even that doesn't clearly tell you what amount of active threads is normal for your workload/configuration. Or you can just save the thread count info (grouped by thread state) and save/graph it over time, to have a better idea of what's normal. The difference of this approach vs just graphing Linux-reported load is that you'll get a breakdown of how much of it was CPU demand vs sync I/O demand. Or you could even break the the thread states down further, by syscall and WCHAN, for example. This will give you a much more detailed idea of why the load is high, not just that it is high.
(Like I mentioned in the article), I even have a tool for sampling /proc at regular intervals (1 Hz by default) and saving it into hourly CSV files, so you can easily go "back in time" and zoom into short spikes and see what was going on:
$ xcapture
0xTools xcapture v1.0 by Tanel Poder [https://0x.tools]
Sampling /proc...
DATE TIME PID TID USERNAME ST COMMAND SYSCALL WCHAN
2020-10-17 12:01:50.583 6404 7524 mysql R (mysqld) fsync wait_on_page_bit
2020-10-17 12:01:50.583 6404 8944 mysql D (mysqld) fsync wait_on_page_bit
2020-10-17 12:01:50.583 6404 8946 mysql D (mysqld) fsync wait_on_page_bit
2020-10-17 12:01:50.583 6404 76046 mysql D (mysqld) fsync wait_on_page_bit
2020-10-17 12:01:50.583 6404 76811 mysql D (mysqld) fdatasync xfs_log_force_lsn
2020-10-17 12:01:50.583 6404 76815 mysql D (mysqld) fsync blkdev_issue_flush
2020-10-17 12:01:50.583 8803 8803 root R (md10_resync) [running] 0
DATE TIME PID TID USERNAME ST COMMAND SYSCALL WCHAN
2020-10-17 12:01:51.623 6404 7521 mysql D (mysqld) pwrite64 xfs_file_buffered_aio_write
2020-10-17 12:01:51.623 6404 7524 mysql D (mysqld) fsync xfs_log_force_lsn
...I think the author didn't realize that the unit of load is just "number of threads" doing _something_ (wanting to be on CPU, running on CPU or waiting for I/O in D state on Linux, just CPU stuff on other Unixes).
Load average is just "average number of threads" doing something over last 1,5,15 minutes.
So if just the single-number averaged over multiple minutes is not good enough for drilling down into your load spikes, then you just go look into the data source (not necessarily source code) yourself. Just use ps or /proc filesystem to list the _number of threads_ that are currently either in R or D state. That's your system load at the current moment. If you want some summary/average over 10 seconds, run the same commant 100x in a row (and sleep a bit in the between) and count all threads in R & D state (and then divide by 100 to normalize it to an average).
It's basically sampling-based profiling of Linux thread states.
Asynchronous I/O completion checks (libaio's io_getevents) that are willing to wait for I/O completion, will not contribute to Linux system load (threads in S state).
Asynchronous I/O submissions (libaio's io_submit) either quickly submit their I/O (a small amount of time in R state) OR get stuck in io_submit() if the underlying block device I/O queue is full. When io_submit() gets stuck, then you're sleeping in D mode, thus contributing to system load again.
For those that are interested:
https://tanelpoder.com/posts/high-system-load-low-cpu-utiliz...
But Oracle usually does point out the exact character/token in the SQL statement where the error originated from.
https://tanelpoder.com/posts/measuring-java-jvm-thread-level...
Edit: Also, run a cluster of anything (in VMs or containers) and muck around killing individual cluster nodes or just suspending them/throttling them to be extremely slow to simulate a brownout/straggling cluster node.
Yep, agreed, hints should be temporary workarounds (or just experimentation aid when developing/testing SQL performance to validate some hypothesis). But many of these temporary workarounds end up being permanent temporary workarounds :-) That’s why Oracle now has hints and parameters to make the optimizer ignore all other hints in the SQL code :-)
Edit: Can’t speak much for MSSQL and DB2, but there are lots of similar problems in the Oracle world too, sometimes due to an app design that works against the intended use of the DB/optimizer, sometimes due to a database optimizer bug and sometimes just due to the complexity of estimating the optimal plan based on limited statistical summaries of the “shape of your data” and expectation that the optimization won’t take longer than a few milliseconds.
There actually is a “pg_hint_plan” [2] Postgres module that adds some hints to Postgres optimizer (but it’s not part of Postgres core as I understand):
[1] https://wiki.postgresql.org/wiki/OptimizerHintsDiscussion
- eBPF script: https://www.brendangregg.com/blog/2016-10-08/linux-bcc-runql...
- perf sched: https://www.brendangregg.com/blog/2017-03-16/perf-sched.html
- schedlat: https://tanelpoder.com/posts/schedlat-low-tech-script-for-me...
The last one (written by me) is using /proc/PID/schedstat pseudofile for monitoring % time spent in the CPU runqueue of a single process (not systemwide). I don't always have (root) access for running perf or eBPF scripts (or the old Linux/kernel version don't allow that). But I can still measure how much time a process on a request's critical path (like a RDBMS transaction log writer on commit) spent waiting to get back onto CPU before doing any work.
Like others have already said, the OS CPU queuing/scheduling latency is just one component contributing to the total responsiveness/reaction latency of your app.
https://news.ycombinator.com/item?id=25956670
Had to use direct I/O and use random large IO patterns to avoid various caching, buffering and prefetching effects.