通过添加到服务器源代码的工具收集事件。仪器时间事件,这就是性能模式如何提供事件需要多长时间的想法。也可以将仪器配置为不收集计时信息。本节讨论可用的计时器及其特性,以及计时值如何在事件中表示。
两个 Performance Schema 表提供计时器信息:
performance_timers
列出可用的定时器及其特性。setup_timers
指示哪些定时器用于哪些仪器。
中的每个计时器行setup_timers
必须引用中列出的计时器之一
performance_timers
。
计时器的精度和开销量各不相同。要查看可用的定时器及其特性,请查看下
performance_timers
表:
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_FREQUENCY
指示每秒的计时器单元数。对于循环定时器,频率通常与 CPU 速度有关。显示的值是在具有 2.4GHz 处理器的系统上获得的。其他计时器基于固定的秒数。对于TICK
,频率可能因平台而异(例如,一些使用 100 刻/秒,其他 1000 刻/秒)。TIMER_RESOLUTION
指示计时器值一次增加的计时器单元数。如果计时器的分辨率为 10,则其值每次增加 10。TIMER_OVERHEAD
是用给定定时器获得一个定时的最小开销周期数。每个事件的开销是显示值的两倍,因为在事件开始和结束时调用计时器。
要查看哪些计时器有效或更改计时器,请访问该setup_timers
表:
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 |
+-------------+-------------+
默认情况下,Performance Schema 使用适用于每种仪器类型的最佳计时器,但您可以选择不同的计时器。
对等待事件计时,最重要的标准是减少开销,但可能会牺牲定时器的准确性,所以使用CYCLE
定时器是最好的。
语句(或阶段)执行所需的时间通常比执行单个等待所需的时间大几个数量级。对于时间语句,最重要的标准是要有一个准确的度量,不受处理器频率变化的影响,所以最好使用不基于周期的定时器。语句的默认计时器是NANOSECOND
. 额外的
“开销”相比
CYCLE
timer 并不重要,因为调用 timer 两次(语句开始时一次,语句结束时一次)所导致的开销与用于执行语句本身的 CPU 时间相比要少几个数量级。使用CYCLE
计时器在这里没有好处,只有缺点。
循环计数器提供的精度取决于处理器速度。如果处理器以 1 GHz(十亿周期/秒)或更高频率运行,则周期计数器可提供亚纳秒精度。使用循环计数器比获取一天中的实际时间要便宜得多。例如,标准gettimeofday()
功能可能需要数百个周期,这对于每秒可能发生数千或数百万次的数据收集来说是不可接受的开销。
循环计数器也有缺点:
最终用户希望看到以挂钟为单位的计时,例如几分之一秒。从周期转换为几分之一秒可能很昂贵。因此,转换是一种快速且相当粗略的乘法运算。
处理器循环率可能会发生变化,例如当笔记本电脑进入省电模式或当 CPU 减速以减少热量产生时。如果处理器的周期率波动,从周期到实时单位的转换就会出错。
取决于处理器或操作系统,循环计数器可能不可靠或不可用。例如,在 Pentium 上,该指令是
RDTSC
(一种汇编语言而不是 C 指令),理论上操作系统可以阻止用户模式程序使用它。一些与乱序执行或多处理器同步相关的处理器细节可能会导致计数器看起来快或慢最多 1000 个周期。
MySQL 在 x386(Windows、macOS、Linux、Solaris 和其他 Unix 风格)、PowerPC 和 IA-64 上使用循环计数器。
存储当前事件和历史事件的 Performance Schema 表中的行具有三列来表示时间信息:指示事件何时开始和结束,并TIMER_START
指示
事件持续时间。
TIMER_END
TIMER_WAIT
该setup_instruments
表有一ENABLED
列指示为其收集事件的工具。该表还有一
TIMED
列来指示哪些仪器是定时的。如果未启用仪器,则不会产生任何事件。如果启用的仪器未计时,则仪器产生的事件具有NULL
、
TIMER_START
和TIMER_END
计时器TIMER_WAIT
值。这反过来会导致在计算汇总表(总和、最小值、最大值和平均值)中的聚合时间值时忽略这些值。
在内部,事件中的时间以事件计时开始时有效的计时器给定的单位存储。对于从 Performance Schema 表中检索事件时的显示,时间以皮秒(万亿分之一秒)显示,以将它们标准化为标准单位,而不管选择哪个计时器。
对setup_timers
表的修改会立即影响监控。已经在进行中的事件可以使用原始计时器作为开始时间,使用新计时器作为结束时间。为避免在更改计时器后出现不可预知的结果,请使用
TRUNCATE TABLE
重置性能模式统计信息。
计时器基线(“时间零”)发生在服务器启动期间的性能模式初始化时。
TIMER_START
事件中的
TIMER_END
值表示自基线以来的皮秒。TIMER_WAIT
值是以皮秒为单位的持续时间。
事件中的皮秒值是近似值。它们的准确性受与从一种单位转换为另一种单位相关的常见误差形式的影响。如果使用CYCLE
定时器并且处理器速率发生变化,则可能存在漂移。TIMER_START
由于这些原因,将事件的值视为自服务器启动以来经过的时间的准确度量是不合理的
。另一方面,在子句中使用
TIMER_START
或
TIMER_WAIT
值ORDER
BY
按开始时间或持续时间对事件排序是合理的。
在事件中选择皮秒而不是微秒这样的值是有性能基础的。一个实施目标是以统一的时间单位显示结果,而不考虑计时器。在理想世界中,这个时间单位看起来像一个挂钟单位并且相当精确;换句话说,微秒。但是要将周期或纳秒转换为微秒,则有必要对每个仪器进行除法。在许多平台上,除法是昂贵的。乘法并不昂贵,所以这就是使用的。因此,时间单位是最高可能的整数倍TIMER_FREQUENCY
值,使用足够大的乘数以确保没有重大的精度损失。结果是时间单位是
“皮秒”。”这种精度是虚假的,但该决策使开销最小化。
在执行等待、阶段、语句或事务事件时,相应的当前事件表显示当前事件计时信息:
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
皮秒的事件,监控应用程序可以在查询中使用此表达式:
WHERE END_EVENT_ID IS NULL AND TIMER_WAIT > N
刚才描述的事件识别假设相应的工具已经设置为ENABLED
并且
相关的消费者被启用。
TIMED
YES