I saw a post on profiling memory usage today and this reminds me of several discussions I have had with different people.
Why would you want to profile the memory usage? Usually to see where memory is allocated and for what purposes, and usually you only care when memory usage is higher than expected. That is a DBA normally wants to use all available memory on a server for mysqld, whatever that size may be.
Configuration parameters may be inappropriate and need adjusting, so having a way to determine the range of memory usage based on those parameters would be most helpful. However, the configuration parameters as a whole put no limit on memory used, so different workloads can quite easily lead to memory being insufficient on the OS, triggering swapping or perhaps the mysqld process to be killed by the kernel’s OOM. None of this is ideal.
So I would like to configure a cap on the maximum amount of memory that can be used and indeed that is what most RDBMSes do. That is the allocation is made on startup, ensuring the memory is available, and any memory requests are taken out of this pool. This technique _should_ avoid you swapping (though I still see issues on NUMA architecture boxes). It also means that at some points in time the database server may not be able to honour memory requests and therefore must fail, wait until those needed resources are available, or it must free existing resources to make space for the requested new resource.
Doing this well is probably hard enough. Doing it in MySQL with different storage engines is probably harder still as each engine does things its own way.
Some mechanism like that would certainly help avoid strange behavioural issues when the query profiles change and this causes the server to behave in unexpected ways, such as swapping itself to death. The only solution right now seems to be to configure the server to ensure that these “edge cases” can not happen by using less memory, thus wasting valuable resources on the server.
Currently it is also pretty hard to see how memory is used. If you use InnoDB you know that the buffer pool takes up a sizeable portion of memory, but there is still a significant amount of other memory that’s used by each individual connection and this can vary significantly depending on the query profiles. It would be really nice to dynamically look inside MySQL and see how memory is used, and also see how adjusting different parameters may adjust this.
Of course none of this is in MySQL at the moment. I would certainly like to see first better information on current memory usage, I would guess some more tables in performance_schema, and at a later stage some way to cap memory usage to a desired level, and hope that when those limits get reached mysqld will figure out how to free up some resources in order to continue, wait or fail “gracefully”.
Until then we will have to continue playing the game of “configure mysqld”. See if it works and then ensure that queries to the system do not change enough to break the system and require us to go back and do it all again.
Note: there are several feature requests for this, so I do not think I am the only one in wishing for more visibility and configurability of the memory usage.
Update: 2013-01-17
Some feature requests that seem related to all this are shown below:
- WL#3249 – PERFORMANCE SCHEMA, Instrument memory usage
- 9420: Shared memory limits
- 9736: DISABLE USER
- 10139: limit ressource usage instead of nr of queries
- 15250: Limit a user CPU usage
- 21038: quota support for mysql
- 22037: limits number of tables per database
- 24757: No way to limit memory consumption of some server subsystems.
- 25058: ignored return codes in memory allocation functions
- 32353: Report where memory is used
- 34870: open_files_limit not being updated
- 43154: Implement a Cap on the Total Used Memory
- 43237: Add Bytes_allocated to SHOW STATUS for #bytes currently allocated in MEM_ROOT
- 48112: Add limits for (total and per user) temporary tables usage
- 54455: innodb needs a way to limit transaction age
- 55323: add an option to limit the write rate to slow query log