25.4.1 性能架构事件计时

通过添加到服务器源代码中的工具收集事件。记录时间事件,这是性能模式如何提供事件耗时的概念。也可以将仪器配置为不收集计时信息。本节讨论可用的计时器及其特性,以及如何在事件中 table 示计时值。

性能架构计时器

两个性能架构 table 提供了计时器信息:

setup_timers中的每个计时器行必须引用performance_timers中列出的计时器之一。

计时器的精度和开销量各不相同。要查看可用的计时器及其特性,请查看performance_timerstable:

mysql> SELECT * FROM performance_schema.performance_timers;
+-------------+-----------------+------------------+----------------+
| TIMER_NAME  | TIMER_FREQUENCY | TIMER_RESOLUTION | TIMER_OVERHEAD |
+-------------+-----------------+------------------+----------------+
| CYCLE       |      2389029850 |                1 |             72 |
| NANOSECOND  |      1000000000 |                1 |            112 |
| MICROSECOND |         1000000 |                1 |            136 |
| MILLISECOND |            1036 |                1 |            168 |
| TICK        |             105 |                1 |           2416 |
+-------------+-----------------+------------------+----------------+

如果与给定计时器名称关联的值为NULL,则平台上不支持该计时器。不包含NULL的行指示您可以在setup_timers中使用哪些计时器。

这些列具有以下含义:

  • TIMER_NAME列显示可用计时器的名称。 CYCLE是指基于 CPU(处理器)周期计数器的计时器。 setup_timers中可以使用的计时器是其他列中没有NULL的计时器。如果与给定计时器名称关联的值为NULL,则平台上不支持该计时器。

  • TIMER_FREQUENCYtable 示每秒的计时器单位数。对于循环计时器,频率通常与 CPU 速度有关。显示的值是在配备 2.4GHz 处理器的系统上获得的。其他计时器基于固定的秒分数。对于TICK,频率可能因平台而异(例如,某些使用 100 滴答/秒,其他使用 1000 滴答/秒)。

  • TIMER_RESOLUTIONtable 示计时器单位的数量,计时器值一次增加。如果计时器的分辨率为 10,则其值每次都会增加 10.

  • TIMER_OVERHEAD是使用给定计时器获得一个时序的最小开销周期数。每个事件的开销是显示值的两倍,因为在事件开始和结束时都会调用计时器。

要查看哪些计时器有效或要更改计时器,请访问setup_timerstable:

mysql> SELECT * FROM performance_schema.setup_timers;
+-------------+-------------+
| NAME        | TIMER_NAME  |
+-------------+-------------+
| idle        | MICROSECOND |
| wait        | CYCLE       |
| stage       | NANOSECOND  |
| statement   | NANOSECOND  |
| transaction | NANOSECOND  |
+-------------+-------------+

mysql> UPDATE performance_schema.setup_timers
       SET TIMER_NAME = 'MICROSECOND'
       WHERE NAME = 'idle';
mysql> SELECT * FROM performance_schema.setup_timers;
+-------------+-------------+
| NAME        | TIMER_NAME  |
+-------------+-------------+
| idle        | MICROSECOND |
| wait        | CYCLE       |
| stage       | NANOSECOND  |
| statement   | NANOSECOND  |
| transaction | NANOSECOND  |
+-------------+-------------+

默认情况下,性能模式使用适用于每种乐器类型的最佳计时器,但是您可以选择其他计时器。

要为 await 事件计时,最重要的标准是减少开销,这可能会牺牲计时器精度,因此最好使用CYCLE计时器。

语句(或阶段)执行所需的时间通常比执行一次 await 所需的时间大几个数量级。对于时间 Statements,最重要的标准是要有一个精确的度量,不受处理器频率变化的影响,因此最好使用不基于周期的定时器。语句的默认计时器为NANOSECOND。与CYCLE计时器相比,额外的“开销”并不重要,因为两次调用计时器(一次语句开始时一次,结束时一次)引起的开销比执行该语句所用的 CPU 时间少几个数量级。本身。使用CYCLE计时器在这里没有好处,只有缺点。

周期计数器提供的精度取决于处理器速度。如果处理器以 1 GHz(十亿个周期/秒)或更高的频率运行,则周期计数器可提供亚纳秒级的精度。使用周期计数器比获取一天中的实际时间便宜得多。例如,标准的gettimeofday()功能可能要花费数百个周期,这对于每秒可能发生数千或数百万次的数据收集来说是不可接受的开销。

周期计数器也有缺点:

  • 最终用户希望以壁钟为单位查看计时,例如几分之一秒。从周期转换为几分之一秒可能会很昂贵。因此,转换是一种快速且相当粗略的乘法运算。

  • 处理器周期率可能会发生变化,例如当笔记本电脑进入节能模式时或当 CPU 速度降低以减少热量产生时。如果处理器的周期速率波动,则从周期到实时单位的转换会出错。

  • 周期计数器可能不可靠或不可用,具体取决于处理器或 os。例如,在奔腾上,该指令是RDTSC(汇编语言而不是 C 指令),并且从理论上讲,os 有可能阻止用户模式程序使用它。

  • 与乱序执行或 multiprocessing 器同步有关的某些处理器详细信息可能会使计数器看起来快或慢达 1000 个周期。

MySQL 在 x386(Windows,macOS,Linux,Solaris 和其他 Unix 版本),PowerPC 和 IA-64 上使用周期计数器。

事件中的性能架构计时器 table 示

Performance Schematable 中存储当前事件和历史事件的行具有三列来 table 示时序信息:TIMER_STARTTIMER_END指示事件何时开始和结束,TIMER_WAIT指示事件持续时间。

setup_instrumentstable 具有ENABLED列,以指示要为其收集事件的工具。该 table 还具有TIMED列以指示要计时的仪器。如果未启用仪器,则不会产生任何事件。如果未对启用的仪器进行计时,则仪器产生的事件的TIMER_STARTTIMER_ENDTIMER_WAIT计时器值将为NULL。反过来,当在汇总 table 中计算汇总时间值(总和,最小值,最大值和平均值)时,这些值将被忽略。

在内部,事件内的时间以事件计时开始时有效的计时器给定的单位存储。为了显示从“性能模式”table 中检索事件时的显示时间,以皮秒(万亿分之一秒)为单位将其归一化为标准单位,而不管选择了哪个计时器。

setup_timerstable 的修改会立即影响监视。已经进行的事件可以将原始计时器用于开始时间,将新计时器用于结束时间。为避免更改计时器后出现不可预测的结果,请使用TRUNCATE TABLE重置性能架构统计信息。

计时器基线(“零时间”)在服务器启动期间的性能架构初始化时发生。事件中的TIMER_STARTTIMER_END值 table 示自基准以来的皮秒。 TIMER_WAIT值是以皮秒为单位的持续时间。

事件中的皮秒值是近似值。它们的准确性受与从一个单位转换到另一单位相关的常见误差形式的影响。如果使用了CYCLE计时器,并且处理器速率有所不同,则可能会有偏差。由于这些原因,将事件的TIMER_START值视为自服务器启动以来经过的时间的准确度量是不合理的。另一方面,在ORDER BY子句中使用TIMER_STARTTIMER_WAIT值按开始时间或持续时间对事件进行排序是合理的。

事件中皮秒的选择而不是诸如微秒之类的值具有性能基础。一个实现目标是以统一的时间单位显示结果,而与计时器无关。在理想的世界中,该时间单位看起来像壁钟单位,并且相当精确。换句话说,微秒。但是要将周期或纳秒转换为微秒,有必要对每种仪器进行除法。在许多平台上划分都很昂贵。乘法并不昂贵,因此使用了乘法。因此,时间单位是最大可能的TIMER_FREQUENCY值的整数倍,并使用足够大的乘数以确保没有大的精度损失。结果是时间单位为“皮秒”。这种精度是虚 Pseudo,但是该决定可以使开销最小化。

在执行 await,阶段,语句或事务事件时,相应的当前事件 table 显示当前事件时序信息:

events_waits_current
events_stages_current
events_statements_current
events_transactions_current

为了确定尚未完成的事件已经运行了多长时间,计时器列设置如下:

  • TIMER_START已填充。

  • TIMER_END使用当前计时器值填充。

  • TIMER_WAIT已填充到目前为止的时间(TIMER_END-TIMER_START)。

尚未完成的事件的END_EVENT_ID值为NULL。要评估到目前为止某个事件已花费的时间,请使用TIMER_WAIT列。因此,要确定到目前为止尚未完成并且花费的时间超过* N *皮秒的事件,监视应用程序可以在查询中使用此 table 达式:

WHERE END_EVENT_ID IS NULL AND TIMER_WAIT > N

刚刚描述的事件标识假定相应的工具已将ENABLEDTIMED设置为YES,并且启用了相关的使用者。