8.12.4.1 MySQL 如何使用内存

MySQL 分配缓冲区和高速缓存以提高数据库操作的性能。默认配置旨在允许 MySQL 服务器在具有大约 512MB RAM 的虚拟机上启动。您可以通过增加某些与缓存和缓冲区相关的系统变量的值来提高 MySQL 性能。您还可以修改默认配置,以在内存有限的系统上运行 MySQL。

下面的列 table 描述了 MySQL 使用内存的一些方式。如果适用,将引用相关的系统变量。有些项目是存储引擎或特定于功能的。

缓冲池的大小对于系统性能很重要:

对于服务器打开的每个MyISAMtable,索引文件都会打开一次;对于访问该 table 的每个并发运行的线程,该数据文件都会打开一次。对于每个并发线程,分配一个 table 结构,每个列的列结构以及大小为3 * N的缓冲区(其中* N *是最大行长,不计BLOB列)。 BLOB列需要 5 到 8 个字节加上BLOB数据的长度。 MyISAM存储引擎维护一个额外的行缓冲区供内部使用。

对于使用CREATE TABLE显式创建的MEMORYtable,只有max_heap_table_size系统变量确定 table 可以增长到多少,并且不转换为磁盘格式。

连接缓冲区和结果缓冲区均以等于net_buffer_length字节的大小开头,但根据需要动态扩展到max_allowed_packet字节。每个 SQL 语句后,结果缓冲区缩小到net_buffer_length个字节。在运行语句时,还会分配当前语句字符串的副本。

每个连接线程都使用内存来计算语句摘要。服务器为每个会话分配max_digest_length个字节。参见第 25.10 节“性能模式语句摘要”

MySQL 还需要用于 table 定义缓存的内存。 table_definition_cache系统变量定义可以存储在 table 定义高速缓存中的 table 定义的数量(来自.frm文件)。如果使用大量 table,则可以创建大 table 定义缓存以加快 table 的打开速度。与 table 高速缓存不同,table 定义高速缓存占用的空间更少,并且不使用文件 Descriptors。

ps 和其他系统状态程序可能会报告mysqld使用了大量内存。这可能是由于不同内存地址上的线程堆栈引起的。例如,Solaris 版本的 ps 将堆栈之间未使用的内存计为已用内存。要验证这一点,请使用swap -s检查可用的交换。我们使用多个内存泄漏检测器(商用和开源)测试mysqld,因此应该没有内存泄漏。

监视 MySQL 内存使用情况

以下示例演示了如何使用Performance Schemasys schema监视 MySQL 内存使用情况。

默认情况下,大多数性能架构内存检测是禁用的。可以通过更新 Performance Schema setup_instrumentstable 的ENABLED列来启用工具。内存仪器的名称以memory/code_area/instrument_name的形式 table 示,其中* code_area 是诸如sqlinnodb的值,而 instrument_name *是仪器详细信息。

mysql> SELECT * FROM performance_schema.setup_instruments
       WHERE NAME LIKE '%memory%';

您可以通过指定代码区域来缩小结果范围。例如,通过将innodb指定为代码区域,可以将结果限制为InnoDB个存储仪器。

mysql> SELECT * FROM performance_schema.setup_instruments
       WHERE NAME LIKE '%memory/innodb%';
+-------------------------------------------+---------+-------+
| NAME                                      | ENABLED | TIMED |
+-------------------------------------------+---------+-------+
| memory/innodb/adaptive hash index         | NO      | NO    |
| memory/innodb/buf_buf_pool                | NO      | NO    |
| memory/innodb/dict_stats_bg_recalc_pool_t | NO      | NO    |
| memory/innodb/dict_stats_index_map_t      | NO      | NO    |
| memory/innodb/dict_stats_n_diff_on_level  | NO      | NO    |
| memory/innodb/other                       | NO      | NO    |
| memory/innodb/row_log_buf                 | NO      | NO    |
| memory/innodb/row_merge_sort              | NO      | NO    |
| memory/innodb/std                         | NO      | NO    |
| memory/innodb/trx_sys_t::rw_trx_ids       | NO      | NO    |
...

根据您的 MySQL 安装,代码区域可能包括performance_schemasqlclientinnodbmyisamcsvmemoryblackholearchivepartition等。

performance-schema-instrument='memory/%=COUNTED'

Note

启动时启用内存工具可确保计算启动时发生的内存分配。

重新启动服务器后,“性能模式setup_instruments”table 的ENABLED列应报告YEStable 示已启用的内存工具。内存工具会忽略setup_instrumentstable 中的TIMED列,因为内存操作未计时。

mysql> SELECT * FROM performance_schema.setup_instruments
       WHERE NAME LIKE '%memory/innodb%';
+-------------------------------------------+---------+-------+
| NAME                                      | ENABLED | TIMED |
+-------------------------------------------+---------+-------+
| memory/innodb/adaptive hash index         | NO      | NO    |
| memory/innodb/buf_buf_pool                | NO      | NO    |
| memory/innodb/dict_stats_bg_recalc_pool_t | NO      | NO    |
| memory/innodb/dict_stats_index_map_t      | NO      | NO    |
| memory/innodb/dict_stats_n_diff_on_level  | NO      | NO    |
| memory/innodb/other                       | NO      | NO    |
| memory/innodb/row_log_buf                 | NO      | NO    |
| memory/innodb/row_merge_sort              | NO      | NO    |
| memory/innodb/std                         | NO      | NO    |
| memory/innodb/trx_sys_t::rw_trx_ids       | NO      | NO    |
...

以下查询返回InnoDB缓冲池的内存数据。有关列的说明,请参见第 25.12.15.9 节“内存摘要 table”

mysql> SELECT * FROM performance_schema.memory_summary_global_by_event_name
       WHERE EVENT_NAME LIKE 'memory/innodb/buf_buf_pool'\G
                  EVENT_NAME: memory/innodb/buf_buf_pool
                 COUNT_ALLOC: 1
                  COUNT_FREE: 0
   SUM_NUMBER_OF_BYTES_ALLOC: 137428992
    SUM_NUMBER_OF_BYTES_FREE: 0
              LOW_COUNT_USED: 0
          CURRENT_COUNT_USED: 1
             HIGH_COUNT_USED: 1
    LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 137428992
   HIGH_NUMBER_OF_BYTES_USED: 137428992

可以使用sys模式memory_global_by_current_bytestable 查询相同的基础数据,该 table 显示了全局服务器中当前的内存使用情况,并按分配类型进行了细分。

mysql> SELECT * FROM sys.memory_global_by_current_bytes
       WHERE event_name LIKE 'memory/innodb/buf_buf_pool'\G
*************************** 1. row ***************************
       event_name: memory/innodb/buf_buf_pool
    current_count: 1
    current_alloc: 131.06 MiB
current_avg_alloc: 131.06 MiB
       high_count: 1
       high_alloc: 131.06 MiB
   high_avg_alloc: 131.06 MiB

sys模式查询按代码区域汇总当前分配的内存(current_alloc):

mysql> SELECT SUBSTRING_INDEX(event_name,'/',2) AS
       code_area, sys.format_bytes(SUM(current_alloc))
       AS current_alloc
       FROM sys.x$memory_global_by_current_bytes
       GROUP BY SUBSTRING_INDEX(event_name,'/',2)
       ORDER BY SUM(current_alloc) DESC;
+---------------------------+---------------+
| code_area                 | current_alloc |
+---------------------------+---------------+
| memory/innodb             | 843.24 MiB    |
| memory/performance_schema | 81.29 MiB     |
| memory/mysys              | 8.20 MiB      |
| memory/sql                | 2.47 MiB      |
| memory/memory             | 174.01 KiB    |
| memory/myisam             | 46.53 KiB     |
| memory/blackhole          | 512 bytes     |
| memory/federated          | 512 bytes     |
| memory/csv                | 512 bytes     |
| memory/vio                | 496 bytes     |
+---------------------------+---------------+

有关sys模式的更多信息,请参见第 26 章,MySQL sys 模式

首页