memory_summary_*表 - xiaoboluo768/mysql-system-schema GitHub Wiki

  • 有如下几张表,performance_schema在这些表中按照不同的分组列(不同纬度)进行聚合内存事件相关的数据(例如:执行次数,总等待时间,最小、最大、平均等待时间),注意,内存事件instruments 除了performance_schema自身内存分配相关的事件采集默认开启之外,其他的内存事件都是默认关闭的,在consumers表中无具体的对应配置
admin@localhost : performance_schema 06:56:56> show tables like '%memory%summary%';
+-------------------------------------------------+
| Tables_in_performance_schema (%memory%summary%) |
+-------------------------------------------------+
| memory_summary_by_account_by_event_name        |
| memory_summary_by_host_by_event_name            |
| memory_summary_by_thread_by_event_name          |
| memory_summary_by_user_by_event_name            |
| memory_summary_global_by_event_name            |
+-------------------------------------------------+
5 rows in set (0.00 sec)
  • 其中,都有表的字段,除持之外,memory_summary_by_account_by_event_name表多了USER和HOST字段,memory_summary_by_host_by_event_name表多了HOST字段,memory_summary_by_thread_by_event_name表多了THREAD_ID字段,memory_summary_by_user_by_event_name表多了USER字段
CREATE TABLE `memory_summary_global_by_event_name` (
  `EVENT_NAME` varchar(128) NOT NULL,
  `COUNT_ALLOC` bigint(20) unsigned NOT NULL,
  `COUNT_FREE` bigint(20) unsigned NOT NULL,
  `SUM_NUMBER_OF_BYTES_ALLOC` bigint(20) unsigned NOT NULL,
  `SUM_NUMBER_OF_BYTES_FREE` bigint(20) unsigned NOT NULL,
  `LOW_COUNT_USED` bigint(20) NOT NULL,
  `CURRENT_COUNT_USED` bigint(20) NOT NULL,
  `HIGH_COUNT_USED` bigint(20) NOT NULL,
  `LOW_NUMBER_OF_BYTES_USED` bigint(20) NOT NULL,
  `CURRENT_NUMBER_OF_BYTES_USED` bigint(20) NOT NULL,
  `HIGH_NUMBER_OF_BYTES_USED` bigint(20) NOT NULL
) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
  • performance_schema会记录内存使用情况并聚合内存使用统计信息,如:使用的内存类型(各种缓存,内部缓冲区等)和线程、帐号、用户、主机的相关操作间接执行的内存操作。performance_schema从使用的内存大小、相关操作数量、高低水位(内存一次操作的最大和最小的相关统计值)

    • 内存大小统计信息有助于了解当前server的内存消耗,以便及时进行内存调整
    • 内存相关操作计数有助于了解当前server的内存分配器的整体压力,及时掌握server性能数据。例如:分配单个字节一百万次与单次分配一百万个字节的性能开销是不同的,通过跟踪内存分配器分配的内存大小和分配次就可以知道两者的差异
    • 检测内存工作负载峰值、内存总体的工作负载稳定性、可能的内存泄漏等是至关重要
    • PS:内存摘要表不包含计时信息,因为内存事件不支持时间信息收集
  • 每个内存摘要表都有一个或多个分组列,表示如何聚合事件信息。事件名称来自setup_instruments表中的name字段:

    • 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列的低和高水位标记
  • 内存摘要表允许使用TRUNCATE TABLE语句。使用truncate语句时有如下行为:

    • 通常,truncate操作会重置统计信息的基准数据(即清空之前的数据),但不会修改当前server的内存分配等状态。也就是说,truncate内存摘要表不会释放已分配内存
    • 将COUNT_ALLOC和COUNT_FREE列重置,并重新开始计数(等于内存统计信息以重置后的数值作为基准数据)
    • SUM_NUMBER_OF_BYTES_ALLOC和SUM_NUMBER_OF_BYTES_FREE列重置与COUNT_ALLOC和COUNT_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表,如果在对其依赖的accounts、hosts、users表执行truncate时,会隐式对这些内存摘要表执行truncate语句
  • 内存行为监控设置:

    • 内存instruments在setup_instruments表中具有memory/code_area/instrument_name格式的名称。但默认情况下大多数instruments都被禁用了,默认只开启了memory/performance_schema/*开头的instruments
    • 以前缀memory/performance_schema命名的instruments可以收集performance_schema自身消耗的内部缓存区大小等信息。memory/performance_schema/* instruments默认启用,无法在启动时或运行时关闭。performance_schema相关的内存统计信息只保存在memory_summary_global_by_event_name表中,不会保存在按照帐户,主机,用户或线程分类聚合的内存摘要表中
    • 要在server启动时控制内存instruments状态,可以在server启动之前在my.cnf文件中进行配置:
      • 开启所有memory instruments:performance-schema-instrument='memory/%=ON'
      • 关闭所有memory instruments(performance_schema自身的memory instruments除外):performance-schema-instrument='memory/%=OFF'
    • 运行时配置:
      • 开启:UPDATE setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'memory/%';
      • 关闭:UPDATE setup_instruments SET ENABLED = 'NO' WHERE NAME LIKE 'memory/%';
    • 对于memory instruments,setup_instruments表中的TIMED列无效,因为内存操作不支持时间统计
    • 注意:如果在server启动之后再修改memory instruments,可能会导致由于丢失之前的分配操作数据而导致在释放之后内存统计信息出现负值,所以不建议在运行时反复开关memory instruments,稍后会讲到原因
  • 当server中的某线程执行了内存分配操作时,按照如下规则进行检测与聚合:

    • 如果该线程在threads表中没有开启采集功能或者说在setup_instruments中对应的instruments没有开启,则该线程分配的内存块不会被监控
    • 如果threads表中该线程的采集功能和setup_instruments表中相应的memory instruments都启用了,则该线程分配的内存块会被监控
  • 对于内存块的释放,按照如下规则进行检测与聚合:

    • 如果一个线程开启了采集功能,但是内存相关的instruments没有启用,则该内存释放操作不会被监控到,统计数据也不会发生改变
    • 如果一个线程没有开启采集功能,但是内存相关的instruments启用了,则该内存释放的操作会被监控到,统计数据会发生改变,这也是前面提到的为啥反复在运行时修改memory instruments可能导致统计数据为负数的原因
  • 对于每个线程的统计信息,适用以下规则。

    • 当一个可被监控的内存块N被分配时,performance_schema会对内存摘要表中的如下列进行更新:
      • COUNT_ALLOC:增加1
      • CURRENT_COUNT_USED:增加1
      • HIGH_COUNT_USED:如果CURRENT_COUNT_USED增加1是一个新的最高值,则该字段值相应增加
      • SUM_NUMBER_OF_BYTES_ALLOC:增加N
      • CURRENT_NUMBER_OF_BYTES_USED:增加N
      • HIGH_NUMBER_OF_BYTES_USED:如果CURRENT_NUMBER_OF_BYTES_USED增加N之后是一个新的最高值,则该字段值相应增加
    • 当一个可被监控的内存块N被释放时,performance_schema会对摘要表中的如下列进行更新:
      • COUNT_FREE:增加1
      • CURRENT_COUNT_USED:减少1
      • LOW_COUNT_USED:如果CURRENT_COUNT_USED减少1之后是一个新的最低值,则该字段相应减少
      • SUM_NUMBER_OF_BYTES_FREE:增加N
      • CURRENT_NUMBER_OF_BYTES_USED:减少N
      • LOW_NUMBER_OF_BYTES_USED:如果CURRENT_NUMBER_OF_BYTES_USED减少N之后是一个新的最低值,则该字段相应减少
    • 对于较高级别的聚合(全局,按帐户,按用户,按主机)摘要表中,低水位和高水位适用于如下规则
      • LOW_COUNT_USED和LOW_NUMBER_OF_BYTES_USED是较低的低水位估算值。performance_schema输出的低水位值可以保证摘要表中的内存分配次数和内存小于或等于当前server中真实的内存分配值
      • HIGH_COUNT_USED和HIGH_NUMBER_OF_BYTES_USED是较高高水位的估算值。performance_schema输出的低水位值可以保证摘要表中的内存分配次数和内存大于或等于当前server中真实的内存分配值
    • 对于内存摘要表中的低水位估算值,在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的内存,信息输出来源同线程1
    • 如果这两个线程属于同一个帐号,则在按照帐号进行聚合的内存摘要表中,这个帐号的内存估算值为11MB到14MB之间。也就是说,最差的情况下,较高级别摘要表中的LOW_NUMBER_OF_BYTES_USED值是每个较低级别的内存摘要表中的多行数据的LOW_NUMBER_OF_BYTES_USED字段之和。同样,较高级别摘要表中的HIGH_NUMBER_OF_BYTES_USED值是每个较低级别内存摘要表中多行数据的HIGH_NUMBER_OF_BYTES_USED字段之和。
    • 对于按照帐号聚合的摘要表中,11MB是较低的估算值,只有同一个帐号的两个线程同时命中该低水位估算值时,才会把11MB当作是LOW_NUMBER_OF_BYTES_USED列值
    • 对于按照帐号聚合的摘要表中,14MB是一个较高的估算值,只有同一个帐号的两个线程同时命中该高水位估算值时,才会把14MB当作是HIGH_NUMBER_OF_BYTES_USED列值
    • 而该帐户的实际内存使用量可能在11.5MB到13.5MB之间
    • 所以,对于容量规划,这些内存摘要表中输出最坏情况的统计值实际上是很合理的
  • 表记录内容示例

# memory_summary_by_account_by_event_name表
admin@localhost : performance_schema 04:02:28> select * from memory_summary_by_account_by_event_name limit 1\G;
*************************** 1. row ***************************
                        USER: NULL
                        HOST: NULL
                  EVENT_NAME: memory/sql/Locked_tables_list::m_locked_tables_root
                COUNT_ALLOC: 0
                  COUNT_FREE: 0
  SUM_NUMBER_OF_BYTES_ALLOC: 0
    SUM_NUMBER_OF_BYTES_FREE: 0
              LOW_COUNT_USED: 0
          CURRENT_COUNT_USED: 0
            HIGH_COUNT_USED: 0
    LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 0
  HIGH_NUMBER_OF_BYTES_USED: 0
1 row in set (0.00 sec)

# memory_summary_by_host_by_event_name表
admin@localhost : performance_schema 04:03:05> select * from memory_summary_by_host_by_event_name limit 1\G;
*************************** 1. row ***************************
                        HOST: NULL
                  EVENT_NAME: memory/sql/Locked_tables_list::m_locked_tables_root
                COUNT_ALLOC: 0
                  COUNT_FREE: 0
  SUM_NUMBER_OF_BYTES_ALLOC: 0
    SUM_NUMBER_OF_BYTES_FREE: 0
              LOW_COUNT_USED: 0
          CURRENT_COUNT_USED: 0
            HIGH_COUNT_USED: 0
    LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 0
  HIGH_NUMBER_OF_BYTES_USED: 0
1 row in set (0.00 sec)

# memory_summary_by_thread_by_event_name表
admin@localhost : performance_schema 04:03:50> select * from memory_summary_by_thread_by_event_name limit 1\G;
*************************** 1. row ***************************
                  THREAD_ID: 1
                  EVENT_NAME: memory/sql/Locked_tables_list::m_locked_tables_root
                COUNT_ALLOC: 0
                  COUNT_FREE: 0
  SUM_NUMBER_OF_BYTES_ALLOC: 0
    SUM_NUMBER_OF_BYTES_FREE: 0
              LOW_COUNT_USED: 0
          CURRENT_COUNT_USED: 0
            HIGH_COUNT_USED: 0
    LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 0
  HIGH_NUMBER_OF_BYTES_USED: 0
1 row in set (0.00 sec)

# memory_summary_by_user_by_event_name表
admin@localhost : performance_schema 04:04:16> select * from memory_summary_by_user_by_event_name limit 1\G;
*************************** 1. row ***************************
                        USER: NULL
                  EVENT_NAME: memory/sql/Locked_tables_list::m_locked_tables_root
                COUNT_ALLOC: 0
                  COUNT_FREE: 0
  SUM_NUMBER_OF_BYTES_ALLOC: 0
    SUM_NUMBER_OF_BYTES_FREE: 0
              LOW_COUNT_USED: 0
          CURRENT_COUNT_USED: 0
            HIGH_COUNT_USED: 0
    LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 0
  HIGH_NUMBER_OF_BYTES_USED: 0
1 row in set (0.00 sec)

# memory_summary_global_by_event_name表
admin@localhost : performance_schema 04:04:42> select * from memory_summary_global_by_event_name limit 1\G;
*************************** 1. row ***************************
                  EVENT_NAME: memory/performance_schema/mutex_instances
                COUNT_ALLOC: 1
                  COUNT_FREE: 0
  SUM_NUMBER_OF_BYTES_ALLOC: 131072
    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: 131072
  HIGH_NUMBER_OF_BYTES_USED: 131072
1 row in set (0.00 sec)

上一篇: socket_summary_*表 | 下一篇: status_by_account、status_by_host、status_by_user