29.12.20.10 内存总结表
性能模式工具监控内存使用情况,并根据以下因素聚合内存使用统计信息:
-
使用的内存类型(各种缓存、内部缓冲区等)
-
执行内存操作的线程、账户、用户、主机
性能模式工具监控以下方面的内存使用:
-
使用的内存大小
-
操作次数
-
低和高水位线
内存大小有助于理解或调优服务器的内存消耗。
操作次数有助于理解或调优服务器对内存分配器施加的总压力,这对性能产生影响。分配一个字节一百万次与一次性分配一百万个字节是不同的;追踪大小和计数可以揭示差异。
低和高水位线对于检测工作负载的波峰、总体工作负载的稳定性以及可能的内存泄漏至关重要。
内存总结表中不包含时间信息,因为内存事件没有被计时。
有关收集内存使用数据的信息,请参阅内存监控行为。
示例内存事件总结信息:
mysql> SELECT *
FROM performance_schema.memory_summary_global_by_event_name
WHERE EVENT_NAME = 'memory/sql/TABLE'\G
*************************** 1. row ***************************
EVENT_NAME: memory/sql/TABLE
COUNT_ALLOC: 1381
COUNT_FREE: 924
SUM_NUMBER_OF_BYTES_ALLOC: 2059873
SUM_NUMBER_OF_BYTES_FREE: 1407432
LOW_COUNT_USED: 0
CURRENT_COUNT_USED: 457
HIGH_COUNT_USED: 461
LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 652441
HIGH_NUMBER_OF_BYTES_USED: 669269
每个内存总结表都有一个或多个分组列,以指示如何对事件进行聚合。事件名称指的是setup_instruments
表中的事件工具名称:
-
memory_summary_by_account_by_event_name
有USER
、HOST
和EVENT_NAME
列。每行总结了给定账户(用户和主机组合)和事件名称的事件。 -
memory_summary_by_host_by_event_name
有HOST
和EVENT_NAME
列。每行总结了给定主机和事件名称的事件。 -
memory_summary_by_thread_by_event_name
有THREAD_ID
和EVENT_NAME
列。每行总结了给定线程和事件名称的事件。 -
memory_summary_by_user_by_event_name
有USER
和EVENT_NAME
列。每行总结了给定用户和事件名称的事件。 -
memory_summary_global_by_event_name
有一个EVENT_NAME
列。每行总结了给定事件名称的事件。
每个内存总结表都有这些汇总列,包含聚合值:
-
COUNT_ALLOC
、COUNT_FREE
分配和释放内存的调用次数的聚合数。
-
SUM_NUMBER_OF_BYTES_ALLOC
、SUM_NUMBER_OF_BYTES_FREE
分配和释放内存块大小的聚合总和。
-
CURRENT_COUNT_USED
当前未被释放的已分配块数量的聚合数。这是一个便捷列,等同于
COUNT_ALLOC
减去COUNT_FREE
。 -
CURRENT_NUMBER_OF_BYTES_USED
当前未被释放的已分配内存块大小的聚合总和。这是一个便捷列,等同于
SUM_NUMBER_OF_BYTES_ALLOC
减去SUM_NUMBER_OF_BYTES_FREE
。 -
LOW_COUNT_USED
、HIGH_COUNT_USED
与
CURRENT_COUNT_USED
相关的低和高水位线。 -
LOW_NUMBER_OF_BYTES_USED
、HIGH_NUMBER_OF_BYTES_USED
与
CURRENT_NUMBER_OF_BYTES_USED
相关的低和高水位线。
内存总结表有这些索引:
-
memory_summary_by_account_by_event_name
:-
主键在(
USER
、HOST
、EVENT_NAME
)上
-
-
memory_summary_by_host_by_event_name
:-
主键在(
HOST
,EVENT_NAME
)上
-
-
memory_summary_by_thread_by_event_name
:-
主键在(
THREAD_ID
,EVENT_NAME
)上
-
-
memory_summary_by_user_by_event_name
:-
主键在(
USER
,EVENT_NAME
)上
-
-
memory_summary_global_by_event_name
:-
主键在(
EVENT_NAME
)上
-
TRUNCATE TABLE
对内存总结表格是允许的。它有以下效果:
-
在一般情况下,截断重置统计基线,但不改变服务器状态。这意味着对内存表进行截断不会释放内存。
-
COUNT_ALLOC
和COUNT_FREE
被重置为新的基线,通过减少每个计数器的值相同。 -
同样地,
SUM_NUMBER_OF_BYTES_ALLOC
和SUM_NUMBER_OF_BYTES_FREE
被重置为新的基线。 -
LOW_COUNT_USED
和HIGH_COUNT_USED
被重置为CURRENT_COUNT_USED
。 -
LOW_NUMBER_OF_BYTES_USED
和HIGH_NUMBER_OF_BYTES_USED
被重置为CURRENT_NUMBER_OF_BYTES_USED
。
此外,每个依赖于连接表的内存总结表格在连接表或 memory_summary_global_by_event_name
表格进行截断时都会被隐式截断。有关详细信息,请参阅第29.12.8节,“Performance Schema Connection Tables”。
内存仪器在setup_instruments
表格中列出,并以形式memory/
的名称命名。内存仪器默认启用。code_area
/instrument_name
以memory/performance_schema/
开头的仪器名称揭示了性能架构内部缓冲区分配的内存使用情况。memory/performance_schema/
仪器是内置的,始终启用,并且不能在启动或运行时禁用。内置的内存仪器仅在memory_summary_global_by_event_name
表格中显示。
要在服务器启动时控制内存仪器状态,请在您的 my.cnf
文件中使用类似于这些行的设置:
-
启用:
[mysqld] performance-schema-instrument='memory/%=ON'
-
禁用:
[mysqld] performance-schema-instrument='memory/%=OFF'
要在运行时控制内存仪器状态,请更新setup_instruments
表格中相关仪器的 ENABLED
列:
-
启用:
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'memory/%';
-
禁用:
UPDATE performance_schema.setup_instruments SET ENABLED = 'NO' WHERE NAME LIKE 'memory/%';
对于内存仪器,TIMED
列在setup_instruments
中被忽略,因为内存操作不进行计时。
当服务器中的线程执行已被仪器化的内存分配操作时,这些规则适用:
-
如果线程未被仪器化或内存仪器未启用,分配的内存块不进行仪器化。
-
否则(即线程和仪器都已启用),分配的内存块进行仪器化。
对于释放操作,这些规则适用:
-
如果有一个内存分配操作被仪器化,那么对应的释放操作无论当前仪器或线程是否启用,都将进行仪器化。
-
如果没有内存分配操作被仪器化,那么对应的释放操作不管当前仪器或线程是否启用,都不会进行仪器化。
对于每个线程的统计数据,这些规则适用。
当一个带有性能监控的内存块大小为 N
被分配时,性能_schema 会对内存总结表中的列进行以下更新:
-
COUNT_ALLOC
: 增加 1 -
CURRENT_ COUNT_USED
: 增加 1 -
HIGH_COUNT_USED
: 如果CURRENT_COUNT_USED
是一个新的最大值,则增加 -
SUM_NUMBER_OF_BYTES_ALLOC
: 增加N
-
CURRENT_NUMBER_OF_BYTES_USED
: 增加N
-
HIGH_NUMBER_OF_BYTES_USED
: 如果CURRENT_NUMBER_OF_BYTES_USED
是一个新的最大值,则增加
当一个带有性能监控的内存块被释放时,性能_schema 会对内存总结表中的列进行以下更新:
-
COUNT_FREE
: 增加 1 -
CURRENT_COUNT_USED
: 减少 1 -
LOW_COUNT_USED
: 如果CURRENT_COUNT_USED
是一个新的最小值,则减少 -
SUM_NUMBER_OF_BYTES_FREE
: 增加N
-
CURRENT_NUMBER_OF_BYTES_USED
: 减少N
-
LOW_NUMBER_OF_BYTES_USED
: 如果CURRENT_NUMBER_OF_BYTES_USED
是一个新的最小值,则减少
对于更高级别的聚合(全局、按账户、按用户、按主机),遵循相同的规则,预期低和高水位标记。
-
LOW_COUNT_USED
和LOW_NUMBER_OF_BYTES_USED
是较低估计值。性能_schema 报告的值保证不大于运行时实际使用内存的最低计数或大小。 -
HIGH_COUNT_USED
和HIGH_NUMBER_OF_BYTES_USED
是较高估计值。性能_schema 报告的值保证不小于运行时实际使用内存的最高计数或大小。
对于摘要表中的其他列(除了 memory_summary_global_by_event_name
),如果内存所有权在线程之间转移,可能会出现负值。
以下是一个估计计算的例子,但请注意估计实现可能会更改:
线程 1 在执行期间使用内存范围,从 1MB 到 2MB,这在 memory_summary_by_thread_by_event_name
表的 LOW_NUMBER_OF_BYTES_USED
和 HIGH_NUMBER_OF_BYTES_USED
列中报告。
线程 2 在执行期间使用内存范围,从 10MB 到 12MB,同样报告。
当这两个线程属于相同的用户账户时,这个账户在摘要表中的更高级别估计显示了内存使用范围从 11MB 到 14MB。也就是说,LOW_NUMBER_OF_BYTES_USED
对于更高级别的聚合是每个 LOW_NUMBER_OF_BYTES_USED
的总和(假设最坏的情况)。同样地,HIGH_NUMBER_OF_BYTES_USED
对于更高级别的聚合是每个 HIGH_NUMBER_OF_BYTES_USED
的总和(假设最坏的情况)。
11MB 是一个较低估计值,只有当两个线程同时达到最低使用标记时才会发生。
14MB 是一个较高估计值,只有当两个线程同时达到最高使用标记时才会发生。
这个账户的实际内存使用可能在 11.5MB 到 13.5MB 之间。
对于容量规划,报告最坏的情况是实际所需行为,因为它显示了当会话不相关时可能发生的情况,这通常是常见情况。