Performance Schema 会跟踪内存使用情况,并按以下因素汇总内存使用统计信息:
使用的内存类型(各种缓存、内部缓冲区等等)
间接执行内存操作的线程、帐户、用户、主机
Performance Schema 会跟踪内存使用的以下方面:
使用的内存大小
操作计数
最低和最高水位标记
内存大小有助于理解或调整服务器的内存消耗。
操作计数有助于理解或调整服务器对内存分配器的总体压力,这会影响性能。分配一百万次一个字节与分配一次一百万个字节不同;跟踪大小和计数都可以揭示这种差异。
最低和最高水位标记对于检测工作负载峰值、总体工作负载稳定性和可能的内存泄漏至关重要。
内存汇总表不包含时间信息,因为内存事件没有计时。
有关收集内存使用情况数据的更多信息,请参见 内存跟踪行为。
示例内存事件汇总信息
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 连接表”。
内存检测器列在 setup_instruments
表中,并具有以下形式的名称:memory/
。内存检测默认启用。code_area
/instrument_name
以 memory/performance_schema/
为前缀命名的检测器会公开 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
的已检测内存块时,Performance Schema 会对内存摘要表列进行以下更新
COUNT_ALLOC
:增加 1CURRENT_COUNT_USED
:增加 1HIGH_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
是新的最大值,则增加
当释放已检测内存块时,Performance Schema 会对内存摘要表列进行以下更新
COUNT_FREE
:增加 1CURRENT_COUNT_USED
:减少 1LOW_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
是较低的估计值。Performance Schema 报告的值保证小于或等于运行时有效使用的最低计数或内存大小。HIGH_COUNT_USED
和HIGH_NUMBER_OF_BYTES_USED
是较高的估计值。Performance 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 之间。
对于容量规划,报告最坏情况实际上是期望的行为,因为它显示了当会话不相关时可能发生的情况,而这通常是这种情况。