adamluciano, I have been thinking of the following parameters related to this:
- innodb_buffer_pool_size reflects the current buffer pool size. MDEV-29445 is reimplementing buffer pool size changes, fixing the crash MDEV-35485 and preventing hangs when the buffer pool size is shrunk.
- innodb_buffer_pool_size_max would be a read-only startup parameter introduced in MDEV-29445 that specifies the maximum innodb_buffer_pool_size. This is necessary, because the current implementation in MDEV-29445 would allocate a single contiguous virtual address range for the buffer pool, instead of allocating multiple virtual address ranges.
- innodb_buffer_pool_size_auto_min (MDEV-34863 would introduce this on Linux; here we would extend it to all platforms) sets the minimum buffer pool size for automatic reduction (default: innodb_buffer_pool_size_max to disable the logic).
- innodb_buffer_pool_size_auto_max (my proposal for this task) would set the maximum for the automation (default: 0 to disable the logic).
The existence of a read-only parameter innodb_buffer_pool_size_max may conflict with what you had in mind related to the suggested buffer_pool_auto_scale_factor. Because we make frequent use of heap allocation (this could be reduced in MDEV-14602 and elsewhere), the total memory usage of the server is rather unpredictable. Also, if there were multiple containers running in the same system, if allowing unlimited memory usage in each container would seem to generate unpredictable conflicts between dynamically configured containers. I think that by forcing innodb_buffer_pool_size_max to be specified at startup, we would proactively prevent some trouble. I realize that Linux supports memory hot-plugging, so the available amount of RAM could change while the server is running. If we claimed support for that, this would have to be tested regularly by us, not in the field.
The dedicated buf_flush_page_cleaner() thread, which can by design observe when it would make sense to extend the buffer pool, is normally invoked once per second, or whenever another thread has run out of buffer pool or space in the circular ib_logfile0. https://smalldatum.blogspot.com/2022/10/reasons-for-writeback-with-update-in.html applies here; additionally, if we are lucky, some blocks can be evicted without writing them back.
I can think of the following triggering events for shrinking or extending:
- Shrink the buffer pool on a memory pressure event from Linux (a last resort to prevent an out-of-memory kill by the Linux kernel)
- Shrink after some specified time, if there have been few requests on buffer pool pages, while preserving some most recently accessed pages
- Extend if buf_flush_page_cleaner() notices that we are frequently trying to evict least recently used pages
- Extend more aggressively if buf_flush_LRU() is called frequently (the evicted pages need to be written out first)
Most of these can be based on discrete events rather than time; only the ‘preemptive’ or ‘voluntary’ shrinking would seem to require a parameter for polling frequency or a timeout for when the server is considered to be idle enough. We’d also need a parameter or two for controlling when to extend the buffer pool. I’m looking forward to specific suggestions that are compatible with the existing logic.
Do we need a parameter to control by how much to shrink or extend at a time? I think that we could do without one. In MDEV-34863 I would shrink halfway between the current innodb_buffer_pool_size and the specified innodb_buffer_pool_size_auto_min. We could use similar logic for extending. The automatic size changes would follow a curve with a negative exponent, a bit like ½, ¼, ⅛, …, (½)ⁿ. To give an example, if the minimum and maximum limits were 256MiB and 2048MiB and the current innodb_buffer_pool_size were 1024MiB, the first step would shrink to ½(256+1024)MiB (-384MiB) or extend to ½(2048+1024)MiB (+512MiB). The closer we get to the limit, the smaller the adjustment, until we reach the minimum adjustment size (8MiB with MDEV-29445). Would this be adequate?
I think that this depends on MDEV-29445, which is currently under review. The current implementation includes a fix of MDEV-34863, which is revising the handling of Linux memory pressure events. With that revision, that interface would be disabled by default. There would be a parameter that would specify the minimum innodb_buffer_pool_size that a memory pressure event could shrink the buffer pool to, and no mechanism for setting the buffer pool size back.