[MDEV-24270] Misuse of io_getevents() causes wake-ups at least twice per second Created: 2020-11-24 Updated: 2020-11-25 Resolved: 2020-11-25 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB |
| Affects Version/s: | 10.2, 10.3, 10.4, 10.5 |
| Fix Version/s: | 10.5.9 |
| Type: | Bug | Priority: | Major |
| Reporter: | Marko Mäkelä | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | performance | ||
| Environment: |
Linux libaio |
||
| Issue Links: |
|
||||||||||||
| Description |
|
In the asynchronous I/O interface, InnoDB is invoking io_getevents() with a timeout value of half a second, and requesting exactly 1 event at a time. Apparently, the reason to have such a short timeout is to facilitate shutdown. We can do better: Use an infinite timeout, wait for a larger maximum number of events. For shutdown, submit a dummy request that informs the io_getevents() caller thread to terminate. |
| Comments |
| Comment by Marko Mäkelä [ 2020-11-25 ] |
|
I ended up implementing my own wrapper of the io_getevents system call, because the one in libaio includes some code that would attempt to elide the system call, causing it to return 0 immediately without blocking. That would not only cause 100% CPU usage in our use case, but also cause SIGSEGV on shutdown, because every now and then, that extra user-mode code would be dereferencing what io_destroy() is destroying in another thread. Based on buildbot.askmonty.org (running various Linux kernel versions in virtual machines), executing io_destroy() while io_getevents is blocking in another thread appears to be safe, causing an EINVAL result. |