性能模式仪器内存使用情况,并根据以下因素聚合内存使用统计信息:
-
使用的内存类型(各种缓存、内部缓冲区等)
-
间接执行内存操作的线程、账户、用户、主机
性能模式仪器以下方面的内存使用情况:
-
使用的内存大小
-
操作计数
-
低水位和高水位
内存大小有助于了解或调整服务器的内存消耗。
操作计数有助于了解或调整服务器对内存分配器的总体压力,这对性能有影响。分配一个字节一百万次与分配一百万字节一次不同;跟踪大小和计数可以暴露差异。
低水位和高水位对于检测工作负载峰值、总体工作负载稳定性和可能的内存泄露至关重要。
内存摘要表不包含计时信息,因为内存事件不计时。
有关收集内存使用数据的信息,请参阅 内存仪器行为。
示例内存事件摘要信息:
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 节,“性能模式连接表”。
内存仪表列在 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/%';
对于内存仪表,setup_instruments
表中的 TIMED
列被忽略,因为内存操作不计时。
当服务器中的线程执行已仪表的内存分配操作时,以下规则适用:
-
如果线程未被仪表或内存仪表未启用,则分配的内存块不被仪表。
-
否则(即线程和仪表都启用),分配的内存块被仪表。
对于释放操作,以下规则适用:
-
如果内存分配操作被仪表,则相应的释放操作被仪表,无论当前仪表或线程启用状态如何。
-
如果内存分配操作未被仪表,则相应的释放操作不被仪表,无论当前仪表或线程启用状态如何。
对于每个线程的统计信息,以下规则适用。
当分配了大小为 N
的instrumented内存块时,性能模式会对内存摘要表列进行以下更新:
-
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
是新的最大值,则增加
当释放了instrumented内存块时,性能模式会对内存摘要表列进行以下更新:
-
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
是较低的估计值。性能模式报告的值保证小于或等于实际使用的最低计数或内存大小。 -
HIGH_COUNT_USED
和HIGH_NUMBER_OF_BYTES_USED
是较高的估计值。性能模式报告的值保证大于或等于实际使用的最高计数或内存大小。
对于摘要表中的较低估计值,除了 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,如同样报告。
当这两个线程属于同一个用户账户时,per-account 摘要估算该账户使用的内存范围从 11MB 到 14MB。也就是说,较低的估算值是每个 LOW_NUMBER_OF_BYTES_USED
的总和(假设最坏情况)。同样,较高的估算值是每个 HIGH_NUMBER_OF_BYTES_USED
的总和(假设最坏情况)。
11MB 是一个较低的估算值,仅当两个线程同时达到最低使用标记时才可能发生。
14MB 是一个较高的估算值,仅当两个线程同时达到最高使用标记时才可能发生。
该账户的实际内存使用可能在 11.5MB 到 13.5MB 之间。
对于容量规划,报告最坏情况实际上是所需的行为,因为它显示了在会话不相关的情况下可能发生的情况。