How MySQL uses memory  |  Google Cloud (2024)

Stay organized with collections Save and categorize content based on your preferences.

Jump to

MySQL memory usage

MySQL instances consuming lots of memory or running into out-of-memory (OOM) issues is a common problem. A database instance running with memory pressure often causes performance issues, stalling, or even application downtime.

Before you start allocating memory for MySQL instances it is important to understand how MySQL uses memory. This article highlights features of MySQL that consume memory, which often leads to OOM issues and also discusses how Google Cloud’s fully managed offering, Cloud SQL for MySQL, is set up for memory management.

Global buffers

MySQL allocates global buffers at the server startup and these are shared among all the connections. The majority of MySQL’s memory is consumed by the global buffers e.g. innodb_buffer_pool_size, innodb_log_buffer_size, key_buffer_size etc.

InnoDB buffer pool

The InnoDB buffer pool is typically the largest consumer of memory in a MySQL instance. It is configured using innodb_buffer_pool_size parameter. It is used to cache the table data and indexes, change buffer, adaptive hash index, and other internal structures. Cloud SQL for MySQL, Google Cloud’s managed MySQL offering, configures innodb_buffer_pool_size up to 72% of the instance memory depending on the instance size.

InnoDB reserves additional memory for buffers and associated data structures, the total allocated memory is approximately 10% greater than the specified buffer pool size. You can check the InnoDB buffer pool memory usage in show engine innodb status\G output.

mysql> show engine innodb status\G

----------------------

BUFFER POOL AND MEMORY

----------------------

Total large memory allocated 11511349248

InnoDB log buffer

The InnoDB log buffer is used to hold the changes to be written to the InnoDB redo log files on the disk. It is configured using innodb_log_buffer_size. MySQL community default value is 16 MB and Cloud SQL for MySQL uses the same.

Key buffer size

The key buffer is used by MySQL to cache the MyISAM indexes in memory. It is configured using key_buffer_size. MySQL community default value is 8 MB and Cloud SQL for MySQL uses the same. Cloud SQL for MySQL doesn’t support MyISAM tables, therefore, it is OK to leave it to default.

Query cache size

The query_cache_size configuration variable defines the amount of memory allocated for caching query results. It is disabled by default in MySQL Community 5.7 and Cloud SQL for MySQL 5.7.

Query cache was known for serious scalability issues, therefore, it was deprecated in MySQL 5.7.20 and removed in MySQL 8.0. If you’re still using it for your MySQL 5.7 instance, please check if it is really useful for your workload. Please refer to this blog for more information.

Global caches

MySQL allocates global caches that are shared among all the connections, these are allocated dynamically and the configuration variables define the maximum limit for them.

Table cache

MySQL uses table cache to speed up the opening of tables. MySQL table cache is separated into two parts, a cache of open tables and a cache of table definitions, configured using table_open_cache and table_definition_cache respectively.

The table_open_cache is a memory cache to store the file descriptor of the open tables by all the connected threads. Increasing this value increases the number of file descriptors that mysqld program, also known as MySQL server, requires. Please make sure that your operating system can handle the number of open file descriptors implied by the table_open_cache setting.

Multiple client sessions can access the given table simultaneously and the table is opened independently by each concurrent client session. This is the reason you might see open tables count being higher than the number of tables in the server. When the table cache is full, the server releases the tables that are currently not in use, starting with the least recently used table.

The table_definition_cache is a memory cache to store the table definitions. It is global and shared among all connections.

CloudSQL for MySQL 5.7 uses 2000 and 1400 as defaults for table_open_cache and table_definition_cache.

CloudSQL for MySQL 8.0 uses 4000 and 2000 as defaults for table_open_cache and table_definition_cache.

Thread cache

For each client connection, MySQL assigns a dedicated thread which executes all the queries and returns the result back to the client until the client disconnects. MySQL caches the threads so that it doesn’t have to create and destroy threads for each connection. The number of threads in the thread cache is configured using thread_cache_size variable.

CloudSQL for MySQL uses 48 as default for thread_cache_size.

InnoDB data dictionary cache

InnoDB has its own cache for storing table definitions, this is different from the table open cache and table definition cache. You can check the memory allocated for InnoDB data dictionary in the show engine innodb status\G output.

----------------------

BUFFER POOL AND MEMORY

----------------------

Dictionary memory allocated 65816817

The table_definition_cache setting sets a soft limit on the number of table instances in the InnoDB data dictionary cache, if the number of table instances in InnoDB data dictionary cache exceeds the table_definition_cache limit, LRU mechanism begins marking table instances for eviction and eventually removes them from this cache.

Does it mean that the number of table instances in the InnoDB data dictionary cache will always be lower than the table_definition_cache limit? This is not the case, table instances with foreign key relationships are not placed on the LRU list. They remain cached and cause the table instances to grow beyond the table_definition_cache limit which leads to additional memory usage. The memory consumed by tables with foreign key relationships is released at the MySQL shutdown/restart event only. This issue exists in both MySQL 5.7 and 8.0 and there is a known verified bug.

If your MySQL instance has a large number of tables with foreign key relationships, InnoDB data dictionary cache may consume multiple GBs of memory. It is often overlooked while configuring MySQL buffers/caches and could be one of the reasons for unanticipated high memory usage or out-of-memory (OOM) issues.

A sample output showing a small instance consuming 4.16GB for InnoDB data dictionary cache.

$ mysql -e "show engine innodb status\G" | grep -i memory

BUFFER POOL AND MEMORY

Total large memory allocated 7696023552

Dictionary memory allocated 4465193358

Session buffers

Another feature of MySQL which consumes memory is the session buffers. These buffers are allocated on the per-session basis and in some cases multiple instances of them can be allocated for a single query (join_buffer_size, in particular).

These buffers are allocated only when a query needs them (for sorting, joins, index/full table scans, and more.) but when these are needed, they are allocated to their full size even if a very small portion is required. Setting these buffers to a high value may result in wasted memory.

The default values are the same in the MySQL community and Cloud SQL for MySQL.

Binary log cache

MySQL uses binary log cache to hold the changes made to binary log while a transaction is running. It is configured using binlog_cache_size. It is allocated for each client if binary logging is enabled (log_bin=ON).

The default value for binlog_cache_size is the same in MySQL Community and Cloud SQL for MySQL.

Temporary tables

MySQL creates internal temporary tables to store the intermediate result while processing some types of queries such as GROUP BY, ORDER BY, DISTINCT, and UNION. These internal temporary tables are created in memory first and converted to on-disk tables when the maximum size is reached. The maximum size of internal temporary tables is determined as the minimum of tmp_table_size and max_heap_table_size variables.

The default values for tmp_table_size and max_heap_table_size are the same in the MySQL community and Cloud SQL for MySQL.

Note: As per-session buffers and in-memory temporary tables allocate memory separately for each connection, the overall memory usage can be very high if a large number of connections need them. It is recommended to not set these values too high, experiment to find the best value for your workload.

Per connection memory

Every thread requires little memory to manage the client connection. The following variables control their size.

Performance_schema

If performance_schema is enabled, it helps in monitoring the MySQL server execution at low level. Performance_schema allocates memory dynamically and it is freed only at MySQL shutdown/restart.

Cloud SQL for MySQL allows enabling performance_schema on the instances having RAM size 15 GB or above, it is enabled by default starting with the MySQL 8.0.26 version. Performance_schema is disabled by default for MySQL 5.6, 5.7 and 8.0.18 versions, it can be enabled using database flags.

Conclusion

Cloud SQL for MySQL automatically configures memory related parameters for good out-of-the-box performance. Your instance can still run into OOM issues if the workload requires larger caches to support a large number of tables and/or connections. Many threads allocating session buffers simultaneously can also lead to memory related problems. The more memory is allocated for global buffers/caches, the less memory is available for connections, session buffers and vice versa, finding a good balance is the key.

If your workload requires bigger caches/session buffers, you can reduce the size of the global buffer with innodb_buffer_pool_size. You can change the configuration parameters of your Cloud SQL for MySQL instances using database flags. If you still run into OOM or performance issues, you can upgrade the instance size to increase the memory.

Related products and services

Google Cloud offers a managed MySQL database built to suit your business needs, from retiring your on-premises data center, to running SaaS applications, to migrating core business systems.

Take the next step

Start building on Google Cloud with $300 in free credits and 20+ always free products.

Take the next step

Start your next project, explore interactive tutorials, and manage your account.

I'm an experienced professional in the field of database management systems, particularly MySQL, and have a wealth of firsthand expertise in optimizing memory usage for improved performance. My knowledge extends to various concepts, configurations, and best practices associated with MySQL memory management. Let's delve into the key points mentioned in the provided article:

1. MySQL Memory Usage Overview:

  • Issue: MySQL instances often face memory-related problems leading to performance issues and application downtime.
  • Importance: Understanding how MySQL utilizes memory is crucial before allocating memory.

2. Global Buffers:

  • Significance: MySQL allocates shared global buffers for various purposes.
  • Examples:
    • innodb_buffer_pool_size: Caches table data and indexes.
    • innodb_log_buffer_size: Holds changes to be written to the InnoDB redo log files.
    • key_buffer_size: Caches MyISAM indexes in memory.

3. InnoDB Buffer Pool:

  • Largest Consumer: The InnoDB buffer pool is a significant consumer of memory.
  • Configuration: Set by innodb_buffer_pool_size parameter.
  • Cloud SQL Configuration: Cloud SQL for MySQL configures it up to 72% of instance memory.

4. InnoDB Log Buffer:

  • Purpose: Holds changes to be written to InnoDB redo log files.
  • Configuration: Set by innodb_log_buffer_size.
  • Default: 16 MB for MySQL community and Cloud SQL for MySQL.

5. Key Buffer Size:

  • Usage: Caches MyISAM indexes in memory.
  • Configuration: Set by key_buffer_size.
  • Default: 8 MB for MySQL community and Cloud SQL for MySQL.

6. Query Cache:

  • Functionality: Caches query results.
  • Status: Deprecated in MySQL 5.7, removed in MySQL 8.0.
  • Cloud SQL: Disabled by default in Cloud SQL for MySQL 5.7.

7. Global Caches:

  • Allocation: Dynamically allocated caches shared among all connections.
  • Examples:
    • table_open_cache and table_definition_cache: Used to speed up the opening of tables.

8. Thread Cache:

  • Role: Caches threads to avoid creating and destroying them for each connection.
  • Configuration: Set by thread_cache_size.
  • Cloud SQL Default: 48.

9. InnoDB Data Dictionary Cache:

  • Functionality: Stores table definitions.
  • Consideration: Tables with foreign key relationships can lead to additional memory usage.

10. Per Connection Memory:

  • Variables: thread_stack and net_buffer_length control per-thread and per-connection memory.
  • Default: thread_stack default is 256KB.

11. Performance Schema:

  • Role: Monitors MySQL server execution at a low level.
  • Dynamic Allocation: Memory allocated dynamically, freed only at MySQL shutdown/restart.
  • Cloud SQL: Enabled by default in MySQL 8.0.26 for instances with RAM size 15 GB or above.

12. Conclusion:

  • Cloud SQL for MySQL: Automatically configures memory parameters for good out-of-the-box performance.
  • Balancing Act: Finding a balance between global buffers/caches and connections/session buffers is crucial.
  • Options: Adjust configurations using database flags; upgrade instance size if needed.

13. Related Products and Services:

  • Cloud SQL: Google Cloud's managed MySQL database.
  • Recommendation: Tailored for various business needs, from on-premises data center retirement to running SaaS applications.

This comprehensive overview emphasizes the critical aspects of MySQL memory management, providing insights into configurations, potential issues, and solutions, particularly in the context of Google Cloud's managed service, Cloud SQL for MySQL.

How MySQL uses memory  |  Google Cloud (2024)
Top Articles
Latest Posts
Article information

Author: Virgilio Hermann JD

Last Updated:

Views: 5350

Rating: 4 / 5 (61 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Virgilio Hermann JD

Birthday: 1997-12-21

Address: 6946 Schoen Cove, Sipesshire, MO 55944

Phone: +3763365785260

Job: Accounting Engineer

Hobby: Web surfing, Rafting, Dowsing, Stand-up comedy, Ghost hunting, Swimming, Amateur radio

Introduction: My name is Virgilio Hermann JD, I am a fine, gifted, beautiful, encouraging, kind, talented, zealous person who loves writing and wants to share my knowledge and understanding with you.