29.1 性能模式快速入门
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-quick-start.html
本节简要介绍了性能模式,并提供了示例以展示如何使用它。有关更多示例,请参见第 29.19 节“使用性能模式诊断问题”。
性能模式默认启用。要显式启用或禁用它,请使用将服务器启动时performance_schema
变量设置为适当值。例如,在服务器的my.cnf
文件中使用以下行:
[mysqld]
performance_schema=ON
当服务器启动时,它会查看performance_schema
并尝试初始化性能模式。要验证初始化是否成功,请使用以下语句:
mysql> SHOW VARIABLES LIKE 'performance_schema';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| performance_schema | ON |
+--------------------+-------+
ON
的值表示性能模式成功初始化并准备就绪。OFF
的值表示发生了一些错误。请检查服务器错误日志以获取有关出现问题的信息。
性能模式被实现为一个存储引擎,因此您可以在信息模式ENGINES
表或SHOW ENGINES
语句的输出中看到它:
mysql> SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE ENGINE='PERFORMANCE_SCHEMA'\G
*************************** 1\. row ***************************
ENGINE: PERFORMANCE_SCHEMA
SUPPORT: YES
COMMENT: Performance Schema
TRANSACTIONS: NO
XA: NO
SAVEPOINTS: NO
mysql> SHOW ENGINES\G
...
Engine: PERFORMANCE_SCHEMA
Support: YES
Comment: Performance Schema
Transactions: NO
XA: NO
Savepoints: NO
...
PERFORMANCE_SCHEMA
存储引擎在performance_schema
数据库中操作表。您可以将performance_schema
设置为默认数据库,这样对其表的引用就不需要用数据库名称限定:
mysql> USE performance_schema;
性能模式表存储在performance_schema
数据库中。关于该数据库及其表结构的信息可以像获取其他数据库信息一样,通过从INFORMATION_SCHEMA
数据库中选择或使用SHOW
语句。例如,使用以下语句之一查看存在哪些性能模式表:
mysql> SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'performance_schema';
+------------------------------------------------------+
| TABLE_NAME |
+------------------------------------------------------+
| accounts |
| cond_instances |
...
| events_stages_current |
| events_stages_history |
| events_stages_history_long |
| events_stages_summary_by_account_by_event_name |
| events_stages_summary_by_host_by_event_name |
| events_stages_summary_by_thread_by_event_name |
| events_stages_summary_by_user_by_event_name |
| events_stages_summary_global_by_event_name |
| events_statements_current |
| events_statements_history |
| events_statements_history_long |
...
| file_instances |
| file_summary_by_event_name |
| file_summary_by_instance |
| host_cache |
| hosts |
| 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 |
| metadata_locks |
| mutex_instances |
| objects_summary_global_by_type |
| performance_timers |
| replication_connection_configuration |
| replication_connection_status |
| replication_applier_configuration |
| replication_applier_status |
| replication_applier_status_by_coordinator |
| replication_applier_status_by_worker |
| rwlock_instances |
| session_account_connect_attrs |
| session_connect_attrs |
| setup_actors |
| setup_consumers |
| setup_instruments |
| setup_objects |
| socket_instances |
| socket_summary_by_event_name |
| socket_summary_by_instance |
| table_handles |
| table_io_waits_summary_by_index_usage |
| table_io_waits_summary_by_table |
| table_lock_waits_summary_by_table |
| threads |
| users |
+------------------------------------------------------+
mysql> SHOW TABLES FROM performance_schema;
+------------------------------------------------------+
| Tables_in_performance_schema |
+------------------------------------------------------+
| accounts |
| cond_instances |
| events_stages_current |
| events_stages_history |
| events_stages_history_long |
...
随着额外的仪器化实施的进行,性能模式表的数量会随时间增加。
performance_schema
数据库的名称是小写的,其中的表名也是小写的。查询应该使用小写指定名称。
要查看单个表的结构,请使用SHOW CREATE TABLE
:
mysql> SHOW CREATE TABLE performance_schema.setup_consumers\G
*************************** 1\. row ***************************
Table: setup_consumers
Create Table: CREATE TABLE `setup_consumers` (
`NAME` varchar(64) NOT NULL,
`ENABLED` enum('YES','NO') NOT NULL,
PRIMARY KEY (`NAME`)
) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
表结构也可以通过选择诸如INFORMATION_SCHEMA.COLUMNS
之类的表或使用诸如SHOW COLUMNS
之类的语句来获取。
performance_schema
数据库中的表可以根据其信息类型进行分组:当前事件、事件历史和摘要、对象实例以及设置(配置)信息。以下示例说明了这些表的一些用途。有关每个组中表的详细信息,请参阅第 29.12 节“性能模式表描述”。
最初,并非所有仪器和消费者都被启用,因此性能模式不会收集所有事件。要打开所有这些并启用事件计时,执行两个语句(行数可能因 MySQL 版本而异):
mysql> UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES';
Query OK, 560 rows affected (0.04 sec)
mysql> UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES';
Query OK, 10 rows affected (0.00 sec)
要查看服务器当前正在执行的操作,请查看events_waits_current
表。它包含每个线程的一行,显示每个线程的最近监视事件:
mysql> SELECT *
FROM performance_schema.events_waits_current\G
*************************** 1\. row ***************************
THREAD_ID: 0
EVENT_ID: 5523
END_EVENT_ID: 5523
EVENT_NAME: wait/synch/mutex/mysys/THR_LOCK::mutex
SOURCE: thr_lock.c:525
TIMER_START: 201660494489586
TIMER_END: 201660494576112
TIMER_WAIT: 86526
SPINS: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL
INDEX_NAME: NULL
OBJECT_TYPE: NULL
OBJECT_INSTANCE_BEGIN: 142270668
NESTING_EVENT_ID: NULL
NESTING_EVENT_TYPE: NULL
OPERATION: lock
NUMBER_OF_BYTES: NULL
FLAGS: 0
...
此事件表示线程 0 正在等待 86,526 皮秒来获取THR_LOCK::mutex
上的锁,这是mysys
子系统中的一个互斥体。前几列提供以下信息:
-
ID 列指示事件来自哪个线程以及事件编号。
-
EVENT_NAME
指示被检测的内容,SOURCE
指示包含被检测代码的源文件。 -
计时器列显示事件开始和结束的时间以及持续时间。如果事件仍在进行中,则
TIMER_END
和TIMER_WAIT
值为NULL
。计时器值是近似值,以皮秒表示。有关计时器和事件时间收集的信息,请参阅第 29.4.1 节“性能模式事件计时”。
历史表包含与当前事件表相同类型的行,但具有更多行,并显示服务器“最近”而不是“当前”正在执行的操作。events_waits_history
和events_waits_history_long
表分别包含每个线程的最近 10 个事件和最近 10,000 个事件。例如,要查看线程 13 生成的最近事件的信息,请执行以下操作:
mysql> SELECT EVENT_ID, EVENT_NAME, TIMER_WAIT
FROM performance_schema.events_waits_history
WHERE THREAD_ID = 13
ORDER BY EVENT_ID;
+----------+-----------------------------------------+------------+
| EVENT_ID | EVENT_NAME | TIMER_WAIT |
+----------+-----------------------------------------+------------+
| 86 | wait/synch/mutex/mysys/THR_LOCK::mutex | 686322 |
| 87 | wait/synch/mutex/mysys/THR_LOCK_malloc | 320535 |
| 88 | wait/synch/mutex/mysys/THR_LOCK_malloc | 339390 |
| 89 | wait/synch/mutex/mysys/THR_LOCK_malloc | 377100 |
| 90 | wait/synch/mutex/sql/LOCK_plugin | 614673 |
| 91 | wait/synch/mutex/sql/LOCK_open | 659925 |
| 92 | wait/synch/mutex/sql/THD::LOCK_thd_data | 494001 |
| 93 | wait/synch/mutex/mysys/THR_LOCK_malloc | 222489 |
| 94 | wait/synch/mutex/mysys/THR_LOCK_malloc | 214947 |
| 95 | wait/synch/mutex/mysys/LOCK_alarm | 312993 |
+----------+-----------------------------------------+------------+
当向历史表添加新事件时,如果表已满,则会丢弃旧事件。
摘要表提供了随时间汇总所有事件的信息。此组中的表以不同方式汇总事件数据。要查看哪些仪器执行次数最多或等待时间最长,请根据COUNT_STAR
或SUM_TIMER_WAIT
列对events_waits_summary_global_by_event_name
表进行排序,这两列分别对应于所有事件计算的COUNT(*)
或SUM(TIMER_WAIT)
值:
mysql> SELECT EVENT_NAME, COUNT_STAR
FROM performance_schema.events_waits_summary_global_by_event_name
ORDER BY COUNT_STAR DESC LIMIT 10;
+---------------------------------------------------+------------+
| EVENT_NAME | COUNT_STAR |
+---------------------------------------------------+------------+
| wait/synch/mutex/mysys/THR_LOCK_malloc | 6419 |
| wait/io/file/sql/FRM | 452 |
| wait/synch/mutex/sql/LOCK_plugin | 337 |
| wait/synch/mutex/mysys/THR_LOCK_open | 187 |
| wait/synch/mutex/mysys/LOCK_alarm | 147 |
| wait/synch/mutex/sql/THD::LOCK_thd_data | 115 |
| wait/io/file/myisam/kfile | 102 |
| wait/synch/mutex/sql/LOCK_global_system_variables | 89 |
| wait/synch/mutex/mysys/THR_LOCK::mutex | 89 |
| wait/synch/mutex/sql/LOCK_open | 88 |
+---------------------------------------------------+------------+
mysql> SELECT EVENT_NAME, SUM_TIMER_WAIT
FROM performance_schema.events_waits_summary_global_by_event_name
ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;
+----------------------------------------+----------------+
| EVENT_NAME | SUM_TIMER_WAIT |
+----------------------------------------+----------------+
| wait/io/file/sql/MYSQL_LOG | 1599816582 |
| wait/synch/mutex/mysys/THR_LOCK_malloc | 1530083250 |
| wait/io/file/sql/binlog_index | 1385291934 |
| wait/io/file/sql/FRM | 1292823243 |
| wait/io/file/myisam/kfile | 411193611 |
| wait/io/file/myisam/dfile | 322401645 |
| wait/synch/mutex/mysys/LOCK_alarm | 145126935 |
| wait/io/file/sql/casetest | 104324715 |
| wait/synch/mutex/sql/LOCK_plugin | 86027823 |
| wait/io/file/sql/pid | 72591750 |
+----------------------------------------+----------------+
这些结果显示THR_LOCK_malloc
互斥锁“热门”,无论是使用频率还是线程等待尝试获取它的时间量。
注意
THR_LOCK_malloc
互斥锁仅在调试构建中使用。在生产构建中,它不是热门,因为它不存在。
实例表记录了被仪器化的对象类型。当服务器使用被仪器化的对象时,会产生一个事件。这些表提供事件名称和解释说明或状态信息。例如,file_instances
表列出了文件 I/O 操作的仪器实例及其关联文件:
mysql> SELECT *
FROM performance_schema.file_instances\G
*************************** 1\. row ***************************
FILE_NAME: /opt/mysql-log/60500/binlog.000007
EVENT_NAME: wait/io/file/sql/binlog
OPEN_COUNT: 0
*************************** 2\. row ***************************
FILE_NAME: /opt/mysql/60500/data/mysql/tables_priv.MYI
EVENT_NAME: wait/io/file/myisam/kfile
OPEN_COUNT: 1
*************************** 3\. row ***************************
FILE_NAME: /opt/mysql/60500/data/mysql/columns_priv.MYI
EVENT_NAME: wait/io/file/myisam/kfile
OPEN_COUNT: 1
...
设置表用于配置和显示监控特性。例如,setup_instruments
列出了可以收集事件的一组仪器,并显示哪些已启用:
mysql> SELECT NAME, ENABLED, TIMED
FROM performance_schema.setup_instruments;
+---------------------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+---------------------------------------------------+---------+-------+
...
| stage/sql/end | NO | NO |
| stage/sql/executing | NO | NO |
| stage/sql/init | NO | NO |
| stage/sql/insert | NO | NO |
...
| statement/sql/load | YES | YES |
| statement/sql/grant | YES | YES |
| statement/sql/check | YES | YES |
| statement/sql/flush | YES | YES |
...
| wait/synch/mutex/sql/LOCK_global_read_lock | YES | YES |
| wait/synch/mutex/sql/LOCK_global_system_variables | YES | YES |
| wait/synch/mutex/sql/LOCK_lock_db | YES | YES |
| wait/synch/mutex/sql/LOCK_manager | YES | YES |
...
| wait/synch/rwlock/sql/LOCK_grant | YES | YES |
| wait/synch/rwlock/sql/LOGGER::LOCK_logger | YES | YES |
| wait/synch/rwlock/sql/LOCK_sys_init_connect | YES | YES |
| wait/synch/rwlock/sql/LOCK_sys_init_slave | YES | YES |
...
| wait/io/file/sql/binlog | YES | YES |
| wait/io/file/sql/binlog_index | YES | YES |
| wait/io/file/sql/casetest | YES | YES |
| wait/io/file/sql/dbopt | YES | YES |
...
要了解如何解释仪器名称,请参见第 29.6 节,“性能模式仪器命名约定”。
要控制是否为仪器收集事件,请将其ENABLED
值设置为YES
或NO
。例如:
mysql> UPDATE performance_schema.setup_instruments
SET ENABLED = 'NO'
WHERE NAME = 'wait/synch/mutex/sql/LOCK_mysql_create_db';
性能模式使用收集的事件来更新performance_schema
数据库中的表,这些表充当事件信息的“消费者”。setup_consumers
表列出了可用的消费者以及哪些已启用:
mysql> SELECT * FROM performance_schema.setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
| events_statements_cpu | NO |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| events_transactions_current | YES |
| events_transactions_history | YES |
| events_transactions_history_long | NO |
| events_waits_current | NO |
| events_waits_history | NO |
| events_waits_history_long | NO |
| global_instrumentation | YES |
| thread_instrumentation | YES |
| statements_digest | YES |
+----------------------------------+---------+
要控制性能模式是否将消费者作为事件信息的目的地,请设置其ENABLED
值。
要了解有关设置表及如何使用它们来控制事件收集的更多信息,请参见第 29.4.2 节,“性能模式事件过滤”。
有一些杂项表不属于前述任何组。例如,performance_timers
列出了可用的事件计时器及其特性。有关计时器的信息,请参见第 29.4.1 节,“性能模式事件计时”。
29.2 性能模式构建配置
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-build-configuration.html
性能模式是强制性的,并且始终在编译中。可以排除性能模式仪表的某些部分。例如,要排除阶段和语句仪表,可以执行以下操作:
$> cmake . \
-DDISABLE_PSI_STAGE=1 \
-DDISABLE_PSI_STATEMENT=1
更多信息,请参阅第 2.8.7 节,“MySQL 源配置选项”中DISABLE_PSI_*
XXX*
CMake 选项的描述。
如果您在之前没有配置性能模式(或者使用缺失或过时表的旧版本性能模式)的情况下安装 MySQL,那么在安装 MySQL 时可能会出现以下错误日志中的消息:
[ERROR] Native table 'performance_schema'.'events_waits_history'
has the wrong structure
[ERROR] Native table 'performance_schema'.'events_waits_history_long'
has the wrong structure
...
要解决这个问题,请执行 MySQL 升级过程。参见第三章,升级 MySQL。
因为性能模式在构建时配置到服务器中,所以在SHOW ENGINES
的输出中会出现PERFORMANCE_SCHEMA
的行。这意味着性能模式是可用的,而不是已启用。要启用它,必须在服务器启动时执行,如下一节所述。
29.3 性能模式启动配置
dev.mysql.com/doc/refman/8.0/en/performance-schema-startup-configuration.html
要使用 MySQL 性能模式,必须在服务器启动时启用,以便进行事件收集。
性能模式默认启用。要显式启用或禁用它,请使用将服务器启动时performance_schema
变量设置为适当值。例如,在服务器my.cnf
文件中使用以下行:
[mysqld]
performance_schema=ON
如果服务器在性能模式初始化期间无法分配任何内部缓冲区,则性能模式会禁用自身,并将performance_schema
设置为OFF
,服务器将在没有仪器的情况下运行。
性能模式还允许在服务器启动时配置仪器和消费者。
要在服务器启动时控制仪器,请使用以下形式的选项:
--performance-schema-instrument='*instrument_name*=*value*'
这里,*instrument_name
是一个仪器名称,例如wait/synch/mutex/sql/LOCK_open
,value
*是以下值之一:
-
OFF
、FALSE
或0
:禁用仪器 -
ON
、TRUE
或1
:启用并计时仪器 -
COUNTED
:启用并计数(而不是计时)仪器
每个--performance-schema-instrument
选项只能指定一个仪器名称,但可以给出多个选项的实例以配置多个仪器。此外,仪器名称中允许使用模式以配置与模式匹配的仪器。要将所有条件同步仪器配置为启用和计数,请使用此选项:
--performance-schema-instrument='wait/synch/cond/%=COUNTED'
要禁用所有仪器,请使用此选项:
--performance-schema-instrument='%=OFF'
例外:memory/performance_schema/%
仪器是内置的,无法在启动时禁用。
较长的仪器名称字符串优先于较短的模式名称,无论顺序如何。有关指定模式以选择仪器的信息,请参阅第 29.4.9 节,“用于过滤操作的命名仪器或消费者”。
未识别的仪器名称将被忽略。后来安装的插件可能会创建该仪器,届时名称将被识别并配置。
要在服务器启动时控制消费者,请使用以下形式的选项:
--performance-schema-consumer-*consumer_name*=*value*
这里,*consumer_name
是一个消费者名称,例如events_waits_history
,value
*是以下值之一:
-
OFF
、FALSE
或0
:不为消费者收集事件 -
ON
、TRUE
或1
:为消费者收集事件
例如,要启用events_waits_history
消费者,请使用此选项:
--performance-schema-consumer-events-waits-history=ON
可以通过检查 setup_consumers
表找到允许的消费者名称。不允许使用模式。setup_consumers
表中的消费者名称使用下划线,但对于在启动时设置的消费者,名称中的破折号和下划线是等效的。
Performance Schema 包括几个提供配置信息的系统变量:
mysql> SHOW VARIABLES LIKE 'perf%';
+--------------------------------------------------------+---------+
| Variable_name | Value |
+--------------------------------------------------------+---------+
| performance_schema | ON |
| performance_schema_accounts_size | 100 |
| performance_schema_digests_size | 200 |
| performance_schema_events_stages_history_long_size | 10000 |
| performance_schema_events_stages_history_size | 10 |
| performance_schema_events_statements_history_long_size | 10000 |
| performance_schema_events_statements_history_size | 10 |
| performance_schema_events_waits_history_long_size | 10000 |
| performance_schema_events_waits_history_size | 10 |
| performance_schema_hosts_size | 100 |
| performance_schema_max_cond_classes | 80 |
| performance_schema_max_cond_instances | 1000 |
...
performance_schema
变量为 ON
或 OFF
,表示 Performance Schema 是否已启用或已禁用。其他变量表示表大小(行数)或内存分配值。
注意
启用 Performance Schema 后,Performance Schema 实例的数量会影响服务器的内存占用,可能在很大程度上。Performance Schema 会自动调整许多参数,仅在需要时使用内存;请参见 Section 29.17, “The Performance Schema Memory-Allocation Model”。
要更改 Performance Schema 系统变量的值,请在服务器启动时设置它们。例如,将以下行放入 my.cnf
文件中以更改等待事件的历史表大小:
[mysqld]
performance_schema
performance_schema_events_waits_history_size=20
performance_schema_events_waits_history_long_size=15000
Performance Schema 在服务器启动时会自动调整一些参数的值,如果它们没有被显式设置。例如,它会以这种方式调整控制事件等待表大小的参数。Performance Schema 会逐步分配内存,根据实际服务器负载来调整内存使用量,而不是在服务器启动时分配所有需要的内存。因此,许多调整参数根本不需要设置。要查看哪些参数是自动调整或自动缩放的,请使用 mysqld --verbose --help 并查看选项描述,或参见 Section 29.15, “Performance Schema System Variables”。
对于每个未在服务器启动时设置的自动调整参数,Performance Schema 根据以下系统值的值确定如何设置其值,这些值被视为关于如何配置 MySQL 服务器的“提示”:
max_connections
open_files_limit
table_definition_cache
table_open_cache
要覆盖给定参数的自动调整或自动缩放,请在启动时将其设置为非 -1 的值。在这种情况下,Performance Schema 将其分配为指定的值。
在运行时,SHOW VARIABLES
显示自动调整参数设置的实际值。自动缩放参数显示为 -1。
如果性能模式被禁用,其自动调整大小和自动缩放参数仍设置为−1,SHOW VARIABLES
显示−1。
29.4 性能模式运行时配置
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-runtime-configuration.html
29.4.1 性能模式事件定时
29.4.2 性能模式事件过滤
29.4.3 事件预过滤
29.4.4 按仪器预过滤
29.4.5 按对象预过滤
29.4.6 按线程预过滤
29.4.7 按消费者预过滤
29.4.8 示例消费者配置
29.4.9 为过滤操作命名仪器或消费者
29.4.10 确定什么被仪器化
特定的性能模式功能可以在运行时启用,以控制发生哪些类型的事件收集。
性能模式设置表包含有关监控配置的信息:
mysql> SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'performance_schema'
AND TABLE_NAME LIKE 'setup%';
+-------------------+
| TABLE_NAME |
+-------------------+
| setup_actors |
| setup_consumers |
| setup_instruments |
| setup_objects |
| setup_threads |
+-------------------+
您可以检查这些表的内容,以获取有关性能模式监控特性的信息。如果您拥有UPDATE
权限,可以通过修改设置表来改变性能模式的操作,从而影响监控的方式。有关这些表的更多详细信息,请参阅第 29.12.2 节,“性能模式设置表”。
setup_instruments
和setup_consumers
表列出了可以收集事件的仪器和实际收集事件信息的消费者类型。其他设置表可以进一步修改监控配置。第 29.4.2 节,“性能模式事件过滤”讨论了如何修改这些表以影响事件收集。
如果有必须在运行时使用 SQL 语句进行性能模式配置更改,并且希望这些更改在每次服务器启动时生效,请将这些语句放入一个文件中,并使用init_file
系统变量设置文件名来启动服务器。如果您有多个监控配置,每个配置都针对不同类型的监控,比如常规服务器健康监控、事件调查、应用行为故障排除等,这种策略也很有用。将每个监控配置的语句放入各自的文件中,并在启动服务器时将适当的文件指定为init_file
的值。
29.4.1 性能模式事件计时
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-timing.html
事件是通过添加到服务器源代码的仪器来收集的。仪器计时事件,这就是性能模式提供事件持续时间的方式。还可以配置仪器不收集计时信息。本节讨论可用计时器及其特性,以及事件中计时值的表示方式。
性能模式计时器
性能模式计时器在精度和开销量上有所不同。要查看可用的计时器及其特性,请查看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 |
| THREAD_CPU | 339101694 | 1 | 798 |
+-------------+-----------------+------------------+----------------+
如果与给定计时器名称相关联的值为NULL
,则该计时器在您的平台上不受支持。
列的含义如下:
-
TIMER_NAME
列显示可用计时器的名称。CYCLE
指的是基于 CPU(处理器)周期计数器的计时器。 -
TIMER_FREQUENCY
表示每秒的计时器单位数。对于循环计时器,频率通常与 CPU 速度有关。显示的值是在一个 2.4GHz 处理器系统上获得的。其他计时器基于固定的秒分数。 -
TIMER_RESOLUTION
表示计时器值每次增加的计时器单位数。如果计时器的分辨率为 10,那么每次增加 10。 -
TIMER_OVERHEAD
是获取给定计时器的一个计时所需的最小周期数。每个事件的开销是显示值的两倍,因为计时器在事件开始和结束时被调用。
性能模式将计时器分配如下:
-
等待计时器使用
CYCLE
。 -
空闲、阶段、语句和事务计时器在支持
NANOSECOND
计时器的平台上使用NANOSECOND
,否则使用MICROSECOND
。
在服务器启动时,性能模式会验证构建时关于计时器分配的假设是否正确,并在计时器不可用时显示警告。
对于计时等待事件,最重要的标准是减少开销,可能会牺牲计时器的准确性,因此使用CYCLE
计时器是最好的选择。
语句(或阶段)执行所需的时间通常比执行单个等待所需的时间大几个数量级。为了计时语句,最重要的标准是要有一个准确的测量,不受处理器频率变化的影响,因此使用不基于循环的计时器是最好的。语句的默认计时器是NANOSECOND
。与CYCLE
计时器相比的额外“开销”并不显著,因为由于调用计时器两次(一次在语句开始时,一次在语句结束时)引起的开销与执行语句本身所用的 CPU 时间相比,数量级要小得多。在这里使用CYCLE
计时器没有好处,只有缺点。
循环计数器提供的精度取决于处理器速度。如果处理器运行速度为 1 GHz(十亿个周期/秒)或更高,则循环计数器提供亚纳秒级精度。使用循环计数器比获取实际的当天时间要便宜得多。例如,标准的gettimeofday()
函数可能需要数百个周期,这对于可能每秒发生数千次或数百万次的数据收集来说是不可接受的开销。
循环计数器也有缺点:
-
最终用户希望看到墙钟单位的时间,例如秒的分数。从循环到秒的转换可能很昂贵。因此,转换是一个快速且相当粗糙的乘法运算。
-
处理器的循环速率可能会发生变化,例如当笔记本电脑进入节能模式或当 CPU 减速以减少热量产生时。如果处理器的循环速率波动,从循环到实时单位的转换可能会出现错误。
-
根据处理器或操作系统的不同,循环计数器可能不可靠或不可用。例如,在奔腾处理器上,指令是
RDTSC
(汇编语言而不是 C 指令),理论上操作系统可以阻止用户模式程序使用它。 -
与乱序执行或多处理器同步相关的一些处理器细节可能导致计数器看起来快或慢多达 1000 个周期。
MySQL 在 x386(Windows,macOS,Linux,Solaris 和其他 Unix 变种),PowerPC 和 IA-64 上使用循环计数器。
Performance Schema 事件中的计时器表示
Performance Schema 表中存储当前事件和历史事件的行有三列用于表示时间信息:TIMER_START
和TIMER_END
表示事件开始和结束的时间,TIMER_WAIT
表示事件持续时间。
setup_instruments
表具有一个 ENABLED
列,用于指示要收集事件的仪器。该表还有一个 TIMED
列,用于指示哪些仪器是定时的。如果一个仪器未启用,则不会产生事件。如果启用的仪器未定时,则由仪器产生的事件的 TIMER_START
、TIMER_END
和 TIMER_WAIT
计时器值为 NULL
。这反过来导致在汇总表(总和、最小值、最大值和平均值)中计算聚合时间值时忽略这些值。
在事件内部,事件中的时间以事件定时开始时的计时器给定的单位存储。当从性能模式表中检索事件时,时间以皮秒(万亿分之一秒)显示,以将它们归一化为标准单位,而不管选择了哪个计时器。
计时器基线(“零时间点”)发生在服务器启动期间的性能模式初始化。事件中的 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
,并且相关的消费者已启用。
29.4.2 性能模式事件过滤
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-filtering.html
事件以生产者/消费者方式进行处理:
-
仪器化代码是事件的来源并产生要收集的事件。
setup_instruments
表列出了可以收集事件的仪器,它们是否已启用以及(对于已启用的仪器)是否收集计时信息:mysql> SELECT NAME, ENABLED, TIMED FROM performance_schema.setup_instruments; +---------------------------------------------------+---------+-------+ | NAME | ENABLED | TIMED | +---------------------------------------------------+---------+-------+ ... | wait/synch/mutex/sql/LOCK_global_read_lock | YES | YES | | wait/synch/mutex/sql/LOCK_global_system_variables | YES | YES | | wait/synch/mutex/sql/LOCK_lock_db | YES | YES | | wait/synch/mutex/sql/LOCK_manager | YES | YES | ...
setup_instruments
表提供了对事件生成最基本的控制形式。为了根据被监视的对象或线程类型进一步细化事件生成,可以使用其他表,如第 29.4.3 节“事件预过滤”中所述。 -
性能模式表是事件的目的地并消耗事件。
setup_consumers
表列出了可以发送事件信息的消费者类型以及它们是否已启用:mysql> SELECT * FROM performance_schema.setup_consumers; +----------------------------------+---------+ | NAME | ENABLED | +----------------------------------+---------+ | events_stages_current | NO | | events_stages_history | NO | | events_stages_history_long | NO | | events_statements_cpu | NO | | events_statements_current | YES | | events_statements_history | YES | | events_statements_history_long | NO | | events_transactions_current | YES | | events_transactions_history | YES | | events_transactions_history_long | NO | | events_waits_current | NO | | events_waits_history | NO | | events_waits_history_long | NO | | global_instrumentation | YES | | thread_instrumentation | YES | | statements_digest | YES | +----------------------------------+---------+
过滤可以在性能监控的不同阶段进行:
-
预过滤。 这是通过修改性能模式配置,以便只从生产者收集某些类型的事件,并且收集的事件仅更新某些消费者。为此,启用或禁用仪器或消费者。预过滤由性能模式执行,并具有适用于所有用户的全局效果。
使用预过滤的原因:
-
减少开销。即使启用了所有仪器,性能模式的开销也应该很小,但也许你想进一步减少它。或者你不关心计时事件,想要禁用计时代码以消除计时开销。
-
为了避免将你不感兴趣的事件填充到当前事件或历史表中。预过滤为启用的仪器类型的行实例留下更多“空间”在这些表中。如果只启用了文件仪器并进行了预过滤,那么不会为非文件仪器收集行。通过后过滤,会收集非文件事件,为文件事件留下较少的行。
-
避免维护某些类型的事件表。如果禁用了一个消费者,服务器就不会花时间维护该消费者的目的地。例如,如果你不关心事件历史,可以禁用历史表消费者以提高性能。
-
-
后过滤。 这涉及在从性能模式表中选择信息的查询中使用
WHERE
子句,以指定您想要查看哪些可用事件。后过滤是基于每个用户进行的,因为个别用户选择感兴趣的可用事件。使用后过滤的原因:
-
避免为个别用户做出关于哪些事件信息感兴趣的决定。
-
当事先不知道要施加的预过滤限制时,可以使用性能模式来调查性能问题。
-
以下各节提供有关预过滤的更多详细信息,并提供有关在过滤操作中命名仪器或消费者的指南。有关编写查询以检索信息(后过滤)的信息,请参见第 29.5 节,“性能模式查询”。
29.4.3 事件预过滤
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-pre-filtering.html
预过滤由性能模式执行,并具有适用于所有用户的全局效果。预过滤可以应用于事件处理的生产者或消费者阶段:
-
要在生产者阶段配置预过滤,可以使用多个表:
-
setup_instruments
指示可用的仪器。在此表中禁用的仪器不会产生任何事件,而不管其他与生产相关的设置表的内容如何。在此表中启用的仪器被允许产生事件,取决于其他表的内容。 -
setup_objects
控制性能模式是否监视特定表和存储程序对象。 -
threads
指示每个服务器线程是否启用监视。 -
setup_actors
确定新前台线程的初始监视状态。
-
-
要在消费者阶段配置预过滤,请修改
setup_consumers
表。这确定事件发送到的目的地。setup_consumers
还隐含影响事件产生。如果某个事件未发送到任何目的地(即,从未被消费),性能模式不会产生它。
对任何这些表的修改立即影响监视,但有一个例外,即对setup_actors
表的修改仅影响创建修改后的前台线程,而不影响现有线程。
当您更改监视配置时,性能模式不会刷新历史表。已经收集的事件会保留在当前事件和历史表中,直到被新事件替换。如果禁用仪器,您可能需要等待一段时间,直到它们的事件被新的感兴趣的事件替换。或者,使用TRUNCATE TABLE
清空历史表。
在进行仪表化更改后,您可能希望截断摘要表。通常,效果是将摘要列重置为 0 或NULL
,而不是删除行。这使您能够清除收集的值并重新开始聚合。例如,在您进行运行时配置更改后,这可能很有用。个别摘要表部分中会注意到此截断行为的异常情况。
以下部分描述如何使用特定表格来控制性能模式的预过滤。
29.4.4 按工具进行预过滤
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-instrument-filtering.html
setup_instruments
表列出了可用的工具:
mysql> SELECT NAME, ENABLED, TIMED
FROM performance_schema.setup_instruments;
+---------------------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+---------------------------------------------------+---------+-------+
...
| stage/sql/end | NO | NO |
| stage/sql/executing | NO | NO |
| stage/sql/init | NO | NO |
| stage/sql/insert | NO | NO |
...
| statement/sql/load | YES | YES |
| statement/sql/grant | YES | YES |
| statement/sql/check | YES | YES |
| statement/sql/flush | YES | YES |
...
| wait/synch/mutex/sql/LOCK_global_read_lock | YES | YES |
| wait/synch/mutex/sql/LOCK_global_system_variables | YES | YES |
| wait/synch/mutex/sql/LOCK_lock_db | YES | YES |
| wait/synch/mutex/sql/LOCK_manager | YES | YES |
...
| wait/synch/rwlock/sql/LOCK_grant | YES | YES |
| wait/synch/rwlock/sql/LOGGER::LOCK_logger | YES | YES |
| wait/synch/rwlock/sql/LOCK_sys_init_connect | YES | YES |
| wait/synch/rwlock/sql/LOCK_sys_init_slave | YES | YES |
...
| wait/io/file/sql/binlog | YES | YES |
| wait/io/file/sql/binlog_index | YES | YES |
| wait/io/file/sql/casetest | YES | YES |
| wait/io/file/sql/dbopt | YES | YES |
...
要控制工具是否启用,请将其ENABLED
列设置为YES
或NO
。要配置是否为已启用工具收集计时信息,请将其TIMED
值设置为YES
或NO
。设置TIMED
列会影响 Performance Schema 表内容,如第 29.4.1 节“性能模式事件计时”中所述。
对大多数setup_instruments
行的修改立即影响监视。对于某些工具,修改仅在服务器启动时生效;在运行时更改对其没有影响。这主要影响服务器中的互斥体、条件和读写锁,尽管可能还有其他工具也是如此。
setup_instruments
表提供了对事件生成最基本的控制形式。为了根据被监视的对象或线程类型进一步细化事件生成,可以使用其他表,如第 29.4.3 节“事件预过滤”中所述。
以下示例演示了对setup_instruments
表可能的操作。这些更改,像其他预过滤操作一样,会影响所有用户。其中一些查询使用LIKE
运算符和模式匹配工具名称。有关指定模式以选择工具的更多信息,请参阅第 29.4.9 节“为过滤操作命名工具或消费者”。
-
禁用所有工具:
UPDATE performance_schema.setup_instruments SET ENABLED = 'NO';
现在不再收集任何事件。
-
禁用所有文件工具,并将它们添加到当前禁用工具集中:
UPDATE performance_schema.setup_instruments SET ENABLED = 'NO' WHERE NAME LIKE 'wait/io/file/%';
-
仅禁用文件工具,启用所有其他工具:
UPDATE performance_schema.setup_instruments SET ENABLED = IF(NAME LIKE 'wait/io/file/%', 'NO', 'YES');
-
启用除了
mysys
库中的工具之外的所有工具:UPDATE performance_schema.setup_instruments SET ENABLED = CASE WHEN NAME LIKE '%/mysys/%' THEN 'YES' ELSE 'NO' END;
-
禁用特定工具:
UPDATE performance_schema.setup_instruments SET ENABLED = 'NO' WHERE NAME = 'wait/synch/mutex/mysys/TMPDIR_mutex';
-
要切换工具的状态,“翻转”其
ENABLED
值:UPDATE performance_schema.setup_instruments SET ENABLED = IF(ENABLED = 'YES', 'NO', 'YES') WHERE NAME = 'wait/synch/mutex/mysys/TMPDIR_mutex';
-
禁用所有事件的计时:
UPDATE performance_schema.setup_instruments SET TIMED = 'NO';
29.4.5 对象预过滤
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-object-filtering.html
setup_objects
表控制性能模式监视特定表格和存储程序对象。初始setup_objects
内容如下:
mysql> SELECT * FROM performance_schema.setup_objects;
+-------------+--------------------+-------------+---------+-------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | ENABLED | TIMED |
+-------------+--------------------+-------------+---------+-------+
| EVENT | mysql | % | NO | NO |
| EVENT | performance_schema | % | NO | NO |
| EVENT | information_schema | % | NO | NO |
| EVENT | % | % | YES | YES |
| FUNCTION | mysql | % | NO | NO |
| FUNCTION | performance_schema | % | NO | NO |
| FUNCTION | information_schema | % | NO | NO |
| FUNCTION | % | % | YES | YES |
| PROCEDURE | mysql | % | NO | NO |
| PROCEDURE | performance_schema | % | NO | NO |
| PROCEDURE | information_schema | % | NO | NO |
| PROCEDURE | % | % | YES | YES |
| TABLE | mysql | % | NO | NO |
| TABLE | performance_schema | % | NO | NO |
| TABLE | information_schema | % | NO | NO |
| TABLE | % | % | YES | YES |
| TRIGGER | mysql | % | NO | NO |
| TRIGGER | performance_schema | % | NO | NO |
| TRIGGER | information_schema | % | NO | NO |
| TRIGGER | % | % | YES | YES |
+-------------+--------------------+-------------+---------+-------+
对setup_objects
表的修改会立即影响对象监视。
OBJECT_TYPE
列指示行适用的对象类型。TABLE
过滤影响表格 I/O 事件(wait/io/table/sql/handler
仪器)和表格锁事件(wait/lock/table/sql/handler
仪器)。
OBJECT_SCHEMA
和OBJECT_NAME
列应包含文字模式或对象名称,或'%'
以匹配任何名称。
ENABLED
列指示是否监视匹配对象,TIMED
指示是否收集时间信息。设置TIMED
列会影响性能模式表内容,如第 29.4.1 节“性能模式事件定时”中所述。
默认对象配置的效果是对除mysql
、INFORMATION_SCHEMA
和performance_schema
数据库中的对象之外的所有对象进行仪器化。 (无论setup_objects
的内容如何,INFORMATION_SCHEMA
数据库中的表格都不会被仪器化;information_schema.%
的行只是明确说明了这一默认值。)
当性能模式在setup_objects
中查找匹配时,它首先尝试找到更具体的匹配。对于匹配给定OBJECT_TYPE
的行,性能模式按照以下顺序检查行:
-
行中的
OBJECT_SCHEMA='*
文字*'
和OBJECT_NAME='*
文字*'
。 -
行中的
OBJECT_SCHEMA='*
文字*'
和OBJECT_NAME='%'
。 -
表格中的
OBJECT_SCHEMA='%'
和OBJECT_NAME='%'
。
例如,对于表格db1.t1
,性能模式会在TABLE
行中查找匹配'db1'
和't1'
,然后是'db1'
和'%'
,最后是'%'
和'%'
。匹配发生的顺序很重要,因为不同的匹配setup_objects
行可能具有不同的ENABLED
和TIMED
值。
对于与表相关的事件,性能模式将 setup_objects
的内容与 setup_instruments
结合起来,以确定是否启用仪器以及是否计时启用的仪器:
-
对于与
setup_objects
中的行匹配的表,只有在setup_instruments
和setup_objects
中的ENABLED
都是YES
时,表仪器才会产生事件。 -
两个表中的
TIMED
值被合并,只有当两个值都是YES
时才收集时间信息。
对于存储过程对象,性能模式直接从 setup_objects
行中获取 ENABLED
和 TIMED
列。 不会将值与 setup_instruments
结合。
假设 setup_objects
包含适用于 db1
、db2
和 db3
的以下 TABLE
行:
+-------------+---------------+-------------+---------+-------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | ENABLED | TIMED |
+-------------+---------------+-------------+---------+-------+
| TABLE | db1 | t1 | YES | YES |
| TABLE | db1 | t2 | NO | NO |
| TABLE | db2 | % | YES | YES |
| TABLE | db3 | % | NO | NO |
| TABLE | % | % | YES | YES |
+-------------+---------------+-------------+---------+-------+
如果 setup_instruments
中与对象相关的仪器具有 ENABLED
值为 NO
,则不会监视对象的事件。 如果 ENABLED
值为 YES
,则根据相关 setup_objects
行中的 ENABLED
值进行事件监视:
-
db1.t1
事件被监视 -
db1.t2
事件不被监视 -
db2.t3
事件被监视 -
db3.t4
事件不被监视 -
db4.t5
事件被监视
类似的逻辑也适用于从 setup_instruments
和 setup_objects
表中合并 TIMED
列以确定是否收集事件时间信息。
如果一个持久表和一个临时表具有相同的名称,则对 setup_objects
行进行匹配的方式对两者都是相同的。 不可能为一个表启用监视而不为另一个表启用。 但是,每个表都是单独进行仪器化的。
29.4.6 通过线程进行预过滤
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-thread-filtering.html
threads
表包含每个服务器线程的一行。每行包含有关线程的信息,并指示是否为其启用了监视。要使性能模式监视线程,必须满足以下条件:
-
setup_consumers
表中的thread_instrumentation
消费者必须为YES
。 -
threads.INSTRUMENTED
列必须为YES
。 -
仅对在
setup_instruments
表中启用的工具产生的线程事件进行监视。
threads
表还指示每个服务器线程是否执行历史事件记录。这包括等待、阶段、语句和事务事件,并影响到这些表的记录:
events_waits_history
events_waits_history_long
events_stages_history
events_stages_history_long
events_statements_history
events_statements_history_long
events_transactions_history
events_transactions_history_long
要发生历史事件记录,必须满足以下条件:
-
必须启用
setup_consumers
表中适当的与历史相关的消费者。例如,在events_waits_history
和events_waits_history_long
表中等待事件记录需要相应的events_waits_history
和events_waits_history_long
消费者为YES
。 -
threads.HISTORY
列必须为YES
。 -
仅对在
setup_instruments
表中启用的工具产生的线程事件进行记录。
对于前台线程(由客户端连接产生),threads
表行中INSTRUMENTED
和HISTORY
列的初始值取决于与线程关联的用户帐户是否与setup_actors
表中的任何行匹配。这些值来自匹配的setup_actors
表行的ENABLED
和HISTORY
列。
对于后台线程,没有关联的用户。INSTRUMENTED
和HISTORY
默认为YES
,不会查询setup_actors
。
初始setup_actors
内容如下所示:
mysql> SELECT * FROM performance_schema.setup_actors;
+------+------+------+---------+---------+
| HOST | USER | ROLE | ENABLED | HISTORY |
+------+------+------+---------+---------+
| % | % | % | YES | YES |
+------+------+------+---------+---------+
HOST
和USER
列应包含文字主机或用户名,或'%'
以匹配任何名称。
ENABLED
和HISTORY
列指示是否为匹配的线程启用仪表化和历史事件记录,受先前描述的其他条件的约束。
当性能模式在setup_actors
中为每个新前台线程检查匹配时,首先尝试找到更具体的匹配,使用USER
和HOST
列(ROLE
未使用):
-
具有
USER='*
literal*'
和HOST='*
literal*'
的行。 -
具有
USER='*
literal*'
和HOST='%'
的行。 -
具有
USER='%'
和HOST='*
literal*'
的行。 -
具有
USER='%'
和HOST='%'
的行。
匹配顺序很重要,因为不同匹配的setup_actors
行可以具有不同的USER
和HOST
值。这使得可以根据ENABLED
和HISTORY
列的值,基于主机、用户或帐户(用户和主机组合)有选择地应用仪表化和历史事件记录:
-
当最佳匹配是
ENABLED=YES
的行时,线程的INSTRUMENTED
值变为YES
。当最佳匹配是HISTORY=YES
的行时,线程的HISTORY
值变为YES
。 -
当最佳匹配是
ENABLED=NO
的行时,线程的INSTRUMENTED
值变为NO
。当最佳匹配是HISTORY=NO
的行时,线程的HISTORY
值变为NO
。 -
当找不到匹配时,线程的
INSTRUMENTED
和HISTORY
值变为NO
。
在setup_actors
行中,ENABLED
和HISTORY
列可以独立设置为YES
或NO
。这意味着您可以单独启用仪表化,而不考虑是否收集历史事件。
默认情况下,对所有新前台线程启用监视和历史事件收集,因为setup_actors
表最初包含HOST
和USER
都为'%'
的行。要执行更有限的匹配,例如仅为某些前台线程启用监视,必须更改此行,因为它匹配任何连接,并添加更具体的HOST
/USER
组合的行。
假设您修改setup_actors
如下:
UPDATE performance_schema.setup_actors
SET ENABLED = 'NO', HISTORY = 'NO'
WHERE HOST = '%' AND USER = '%';
INSERT INTO performance_schema.setup_actors
(HOST,USER,ROLE,ENABLED,HISTORY)
VALUES('localhost','joe','%','YES','YES');
INSERT INTO performance_schema.setup_actors
(HOST,USER,ROLE,ENABLED,HISTORY)
VALUES('hosta.example.com','joe','%','YES','NO');
INSERT INTO performance_schema.setup_actors
(HOST,USER,ROLE,ENABLED,HISTORY)
VALUES('%','sam','%','NO','YES');
UPDATE
语句更改默认匹配以禁用仪表化和历史事件收集。INSERT
语句为更具体的匹配添加行。
现在性能模式确定如何设置新连接线程的INSTRUMENTED
和HISTORY
值如下:
-
如果
joe
从本地主机连接,则连接与第一行插入的行匹配。线程的INSTRUMENTED
和HISTORY
值变为YES
。 -
如果
joe
从hosta.example.com
连接,则连接与第二行插入的行匹配。线程的INSTRUMENTED
值变为YES
,HISTORY
值变为NO
。 -
如果
joe
从任何其他主机连接,则没有匹配。线程的INSTRUMENTED
和HISTORY
值变为NO
。 -
如果
sam
从任何主机连接,则连接与第三行插入的行匹配。线程的INSTRUMENTED
值变为NO
,HISTORY
值变为YES
。 -
对于任何其他连接,
HOST
和USER
设置为'%'
的行匹配。此行现在的ENABLED
和HISTORY
设置为NO
,因此线程的INSTRUMENTED
和HISTORY
值变为NO
。
对setup_actors
表的修改仅影响在修改后创建的前台线程,而不影响现有线程。要影响现有线程,请修改threads
表行的INSTRUMENTED
和HISTORY
列。
29.4.7 按消费者进行预过滤
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-consumer-filtering.html
setup_consumers
表列出了可用的消费者类型以及哪些已启用:
mysql> SELECT * FROM performance_schema.setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
| events_statements_cpu | NO |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| events_transactions_current | YES |
| events_transactions_history | YES |
| events_transactions_history_long | NO |
| events_waits_current | NO |
| events_waits_history | NO |
| events_waits_history_long | NO |
| global_instrumentation | YES |
| thread_instrumentation | YES |
| statements_digest | YES |
+----------------------------------+---------+
修改setup_consumers
表以影响消费者阶段的预过滤,并确定事件发送的目的地。要启用或禁用一个消费者,将其ENABLED
值设置为YES
或NO
。
对setup_consumers
表的修改会立即影响监控。
如果禁用一个消费者,服务器将不再花时间维护该消费者的目的地。例如,如果你不关心历史事件信息,可以禁用历史消费者:
UPDATE performance_schema.setup_consumers
SET ENABLED = 'NO'
WHERE NAME LIKE '%history%';
setup_consumers
表中的消费者设置形成从高级到低级的层次结构。以下原则适用:
-
与消费者关联的目的地只有在性能模式检查了消费者并且消费者已启用时才会接收事件。
-
一个消费者只有在它所依赖的所有消费者(如果有的话)都启用时才会被选中。
-
如果一个消费者未被选中,或者被选中但被禁用,依赖它的其他消费者也不会被选中。
-
依赖消费者可能有自己的依赖消费者。
-
如果一个事件不会被发送到任何目的地,性能模式就不会产生它。
以下列表描述了可用的消费者值。有关几种代表性消费者配置及其对仪表化的影响的讨论,请参见第 29.4.8 节,“示例消费者配置”。
-
全局和线程消费者
-
等待事件消费者
-
阶段事件消费者
-
语句事件消费者
-
事务事件消费者
-
语句摘要消费者
全局和线程消费者
-
global_instrumentation
是最高级别的消费者。如果global_instrumentation
为NO
,它会禁用全局仪器。所有其他设置都是较低级别的,不会被检查;它们设置为什么并不重要。不会维护全局或每个线程的信息,也不会在当前事件或事件历史表中收集任何个别事件。如果global_instrumentation
为YES
,性能模式会维护全局状态的信息,并且还会检查thread_instrumentation
消费者。 -
thread_instrumentation
只有在global_instrumentation
为YES
时才会被检查。否则,如果thread_instrumentation
为NO
,它会禁用线程特定的仪器,并且所有更低级别的设置都会被忽略。不会为每个线程维护任何信息,也不会在当前事件或事件历史表中收集任何个别事件。如果thread_instrumentation
为YES
,性能模式会维护线程特定信息,并且还会检查events_*
xxx*_current
消费者。
等待事件消费者
这些消费者要求 global_instrumentation
和 thread_instrumentation
都为 YES
,否则不会被检查。如果被检查,它们的作用如下:
-
如果
events_waits_current
为NO
,则会禁用在events_waits_current
表中个别等待事件的收集。如果YES
,则会启用等待事件的收集,并且性能模式��检查events_waits_history
和events_waits_history_long
消费者。 -
如果
event_waits_current
为NO
,则不会检查events_waits_history
。否则,events_waits_history
的值为NO
或YES
会禁用或启用在events_waits_history
表中等待事件的收集。 -
如果
event_waits_current
为NO
,则不会检查events_waits_history_long
。否则,events_waits_history_long
的值为NO
或YES
会禁用或启用在events_waits_history_long
表中等待事件的收集。
阶段事件消费者
这些消费者要求 global_instrumentation
和 thread_instrumentation
都为 YES
,否则不会被检查。如果被检查,它们的作用如下:
-
如果
events_stages_current
为NO
,则会禁用在events_stages_current
表中个别阶段事件的收集。如果YES
,则会启用阶段事件的收集,并且性能模式会检查events_stages_history
和events_stages_history_long
消费者。 -
如果
event_stages_current
为NO
,则不会检查events_stages_history
。否则,events_stages_history
的值为NO
或YES
将禁用或启用在events_stages_history
表中阶段事件的收集。 -
如果
event_stages_current
为NO
,则不会检查events_stages_history_long
。否则,events_stages_history_long
的值为NO
或YES
将禁用或启用在events_stages_history_long
表中阶段事件的收集。
语句事件消费者
这些消费者需要global_instrumentation
和thread_instrumentation
都设置为YES
,否则将不会被检查。如果被选中,它们的作用如下:
-
如果
events_statements_cpu
为NO
,则禁用CPU_TIME
的测量。如果为YES
,并且启用了仪器和计时,将测量CPU_TIME
。 -
如果
events_statements_current
为NO
,则禁用在events_statements_current
表中收集单个语句事件。如果为YES
,则启用语句事件收集,并且性能模式将检查events_statements_history
和events_statements_history_long
消费者。 -
如果
events_statements_current
为NO
,则不会检查events_statements_history
。否则,events_statements_history
的值为NO
或YES
将禁用或启用在events_statements_history
表中语句事件的收集。 -
如果
events_statements_current
为NO
,则不会检查events_statements_history_long
。否则,events_statements_history_long
的值为NO
或YES
将禁用或启用在events_statements_history_long
表中语句事件的收集。
事务事件消费者
这些消费者需要global_instrumentation
和thread_instrumentation
都设置为YES
,否则将不会被检查。如果被选中,它们的作用如下:
-
如果
events_transactions_current
为NO
,则禁用在events_transactions_current
表中收集单个事务事件。如果为YES
,则启用事务事件收集,并且性能模式将检查events_transactions_history
和events_transactions_history_long
消费者。 -
如果
events_transactions_current
为NO
,则不会检查events_transactions_history
。否则,events_transactions_history
的值为NO
或YES
会禁用或启用events_transactions_history
表中事务事件的收集。 -
如果
events_transactions_current
为NO
,则不会检查events_transactions_history_long
。否则,events_transactions_history_long
的值为NO
或YES
会禁用或启用events_transactions_history_long
表中事务事件的收集。
语句摘要消费者
statements_digest
消费者要求global_instrumentation
为YES
,否则不会进行检查。对语句事件消费者没有依赖,因此您可以在不必在events_statements_current
中收集统计信息的情况下,获得每个摘要的统计信息,这在开销方面是有利的。相反,您可以在events_statements_current
中获取详细的语句,而不需要摘要(在这种情况下,DIGEST
和DIGEST_TEXT
列为NULL
)。
关于语句摘要的更多信息,请参见第 29.10 节,“性能模式语句摘要和抽样”。
29.4.8 示例消费者配置
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-consumer-configurations.html
setup_consumers
表中的消费者设置形成从高级到低级的层次结构。以下讨论描述了消费者如何工作,展示了特定配置及其效果,随着从高到低逐渐启用消费者设置。所示的消费者值是代表性的。这里描述的一般原则适用于可能可用的其他消费者值。
配置描述按功能和开销递增的顺序出现。如果不需要启用较低级别设置提供的信息,则禁用它们,以便性能模式在您的代表执行更少的代码,并且需要筛选的信息更少。
setup_consumers
表包含以下值的层次结构:
global_instrumentation
thread_instrumentation
events_waits_current
events_waits_history
events_waits_history_long
events_stages_current
events_stages_history
events_stages_history_long
events_statements_current
events_statements_history
events_statements_history_long
events_transactions_current
events_transactions_history
events_transactions_history_long
statements_digest
注意
在消费者层次结构中,等待、阶段、语句和事务的消费者都处于同一级别。这与事件嵌套层次结构不同,等待事件嵌套在阶段事件内,阶段事件嵌套在语句事件内,语句事件嵌套在事务事件内。
如果给定的消费者设置为NO
,性能模式将禁用与该消费者相关联的仪器,并忽略所有较低级别的设置。如果给定的设置为YES
,性能模式将启用与之相关联的仪器,并检查下一个较低级别的设置。有关每个消费者的规则描述,请参见第 29.4.7 节“按消费者进行预过滤”。
例如,如果启用了global_instrumentation
,则会检查thread_instrumentation
。如果启用了thread_instrumentation
,则会检查events_*
xxx*_current
消费者。如果其中的events_waits_current
已启用,则会检查events_waits_history
和events_waits_history_long
。
以下每个配置描述指示性能模式检查哪些设置元素,并维护哪些输出表(即,为哪些表收集信息)。
-
无仪器
-
仅全局仪器
-
仅全局和线程仪器
-
全局、线程和当前事件仪器
-
全局、线程、当前事件和事件历史仪器
无仪器
服务器配置状态:
mysql> SELECT * FROM performance_schema.setup_consumers;
+---------------------------+---------+
| NAME | ENABLED |
+---------------------------+---------+
| global_instrumentation | NO |
...
+---------------------------+---------+
在这种配置中,没有任何仪器。
检查的设置元素:
- 表
setup_consumers
, 消费者global_instrumentation
维护的输出表:
- 无
仅全局仪器
服务器配置状态:
mysql> SELECT * FROM performance_schema.setup_consumers;
+---------------------------+---------+
| NAME | ENABLED |
+---------------------------+---------+
| global_instrumentation | YES |
| thread_instrumentation | NO |
...
+---------------------------+---------+
在这种配置中,仪器仅用于全局状态。每个线程的仪器被禁用。
相对于前述配置,检查的额外设置元素:
-
表
setup_consumers
, 消费者thread_instrumentation
-
表
setup_instruments
-
表
setup_objects
相对于前述配置,维护的额外输出表:
-
mutex_instances
-
rwlock_instances
-
cond_instances
-
file_instances
-
users
-
hosts
-
accounts
-
socket_summary_by_event_name
-
file_summary_by_instance
-
file_summary_by_event_name
-
objects_summary_global_by_type
-
memory_summary_global_by_event_name
-
table_lock_waits_summary_by_table
-
table_io_waits_summary_by_index_usage
-
table_io_waits_summary_by_table
-
events_waits_summary_by_instance
-
events_waits_summary_global_by_event_name
-
events_stages_summary_global_by_event_name
-
events_statements_summary_global_by_event_name
-
events_transactions_summary_global_by_event_name
仅全局和线程仪器
服务器配置状态:
mysql> SELECT * FROM performance_schema.setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| global_instrumentation | YES |
| thread_instrumentation | YES |
| events_waits_current | NO |
...
| events_stages_current | NO |
...
| events_statements_current | NO |
...
| events_transactions_current | NO |
...
+----------------------------------+---------+
在这种配置下,仪器仪表是全局和每个线程都维护的。当前事件或事件历史表中不收集任何个别事件。
相对于前述配置,检查了额外的设置元素:
-
表
setup_consumers
,消费者events_*
xxx*_current
,其中*xxx
*是waits
、stages
、statements
、transactions
-
表
setup_actors
-
列
threads.instrumented
相对于前述配置,维护了额外的输出表:
events_*
xxx*_summary_by_*
yyy*_by_event_name
,其中*xxx
是waits
、stages
、statements
、transactions
;yyy
*是thread
、user
、host
、account
全局、线程和当前事件仪器
服务器配置状态:
mysql> SELECT * FROM performance_schema.setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| global_instrumentation | YES |
| thread_instrumentation | YES |
| events_waits_current | YES |
| events_waits_history | NO |
| events_waits_history_long | NO |
| events_stages_current | YES |
| events_stages_history | NO |
| events_stages_history_long | NO |
| events_statements_current | YES |
| events_statements_history | NO |
| events_statements_history_long | NO |
| events_transactions_current | YES |
| events_transactions_history | NO |
| events_transactions_history_long | NO |
...
+----------------------------------+---------+
在这种配置下,仪器仪表是全局和每个线程都维护的。个别事件在当前事件表中收集,但不在事件历史表中。
相对于前述配置,检查了额外的设置元素:
-
消费者
events_*
xxx*_history
,其中*xxx
*是waits
、stages
、statements
、transactions
-
消费者
events_*
xxx*_history_long
,其中*xxx
*是waits
、stages
、statements
、transactions
相对于前述配置,维护了额外的输出表:
events_*
xxx*_current
,其中*xxx
*是waits
、stages
、statements
、transactions
全局、线程、当前事件和事件历史仪器
前述配置未收集任何事件历史,因为events_*
xxx*_history
和events_*
xxx*_history_long
消费者已禁用。这些消费者可以单独或一起启用,以便按线程、全局或两者同时收集事件历史。
此配置按线程收集事件历史,但不全局:
mysql> SELECT * FROM performance_schema.setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| global_instrumentation | YES |
| thread_instrumentation | YES |
| events_waits_current | YES |
| events_waits_history | YES |
| events_waits_history_long | NO |
| events_stages_current | YES |
| events_stages_history | YES |
| events_stages_history_long | NO |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| events_transactions_current | YES |
| events_transactions_history | YES |
| events_transactions_history_long | NO |
...
+----------------------------------+---------+
为此配置维护的事件历史表:
events_*
xxx*_history
,其中*xxx
*是waits
、stages
、statements
、transactions
此配置全局收集事件历史,但不按线程:
mysql> SELECT * FROM performance_schema.setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| global_instrumentation | YES |
| thread_instrumentation | YES |
| events_waits_current | YES |
| events_waits_history | NO |
| events_waits_history_long | YES |
| events_stages_current | YES |
| events_stages_history | NO |
| events_stages_history_long | YES |
| events_statements_current | YES |
| events_statements_history | NO |
| events_statements_history_long | YES |
| events_transactions_current | YES |
| events_transactions_history | NO |
| events_transactions_history_long | YES |
...
+----------------------------------+---------+
为此配置维护的事件历史表:
events_*
xxx*_history_long
,其中*xxx
*是waits
、stages
、statements
、transactions
此配置按线程和全局收集事件历史:
mysql> SELECT * FROM performance_schema.setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| global_instrumentation | YES |
| thread_instrumentation | YES |
| events_waits_current | YES |
| events_waits_history | YES |
| events_waits_history_long | YES |
| events_stages_current | YES |
| events_stages_history | YES |
| events_stages_history_long | YES |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | YES |
| events_transactions_current | YES |
| events_transactions_history | YES |
| events_transactions_history_long | YES |
...
+----------------------------------+---------+
为此配置维护的事件历史表:
-
events_*
xxx*_history
,其中*xxx
*是waits
、stages
、statements
、transactions
-
events_*
xxx*_history_long
,其中*xxx
*是waits
、stages
、statements
、transactions
29.4.9 为过滤操作命名仪表或消费者
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-filtering-names.html
为过滤操作提供的名称可以根据需要具体或一般。要指示单个仪表或消费者,请完整指定其名称:
UPDATE performance_schema.setup_instruments
SET ENABLED = 'NO'
WHERE NAME = 'wait/synch/mutex/myisammrg/MYRG_INFO::mutex';
UPDATE performance_schema.setup_consumers
SET ENABLED = 'NO'
WHERE NAME = 'events_waits_current';
要指定一组仪表或消费者,请使用匹配组成员的模式:
UPDATE performance_schema.setup_instruments
SET ENABLED = 'NO'
WHERE NAME LIKE 'wait/synch/mutex/%';
UPDATE performance_schema.setup_consumers
SET ENABLED = 'NO'
WHERE NAME LIKE '%history%';
如果使用模式,应选择能够匹配所有感兴趣的项目但不匹配其他项目的模式。例如,要选择所有文件 I/O 仪表,最好使用包含整个仪表名称前缀的模式:
... WHERE NAME LIKE 'wait/io/file/%';
'%/file/%'
的模式匹配其他仪表中名称中任何位置包含'/file/'
的元素。更不合适的是'%file%'
这种模式,因为它匹配名称中任何位置包含'file'
的仪表,比如wait/synch/mutex/innodb/file_open_mutex
。
要检查模式匹配的仪表或消费者名称,请执行简单测试:
SELECT NAME FROM performance_schema.setup_instruments
WHERE NAME LIKE '*pattern*';
SELECT NAME FROM performance_schema.setup_consumers
WHERE NAME LIKE '*pattern*';
有关支持的名称类型的信息,请参阅第 29.6 节,“性能模式仪表命名约定”。
29.4.10 确定仪器化的内容
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-instrumentation-checking.html
通过检查setup_instruments
表,始终可以确定性能模式包含哪些仪器。例如,要查看为InnoDB
存储引擎仪器化的文件相关事件,请使用以下查询:
mysql> SELECT NAME, ENABLED, TIMED
FROM performance_schema.setup_instruments
WHERE NAME LIKE 'wait/io/file/innodb/%';
+-------------------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+-------------------------------------------------+---------+-------+
| wait/io/file/innodb/innodb_tablespace_open_file | YES | YES |
| wait/io/file/innodb/innodb_data_file | YES | YES |
| wait/io/file/innodb/innodb_log_file | YES | YES |
| wait/io/file/innodb/innodb_temp_file | YES | YES |
| wait/io/file/innodb/innodb_arch_file | YES | YES |
| wait/io/file/innodb/innodb_clone_file | YES | YES |
+-------------------------------------------------+---------+-------+
此文档未详细描述仪器化的内容,原因有几个:
-
仪器化的是服务器代码。对这些代码的更改经常发生,这也会影响仪器的集合。
-
不可能列出所有的仪器,因为它们有数百个。
-
如前所述,可以通过查询
setup_instruments
表来找到。这些信息始终是针对您的 MySQL 版本最新的,还包括您可能安装的不属于核心服务器的仪器化插件的仪器化,并可被自动化工具使用。
29.5 性能模式查询
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-queries.html
预过滤限制了收集的事件信息,与任何特定用户无关。相比之下,后过滤是由个别用户通过使用带有适当WHERE
子句的查询执行的,这些子句限制了在应用预过滤后可用的事件中选择哪些事件信息。
在第 29.4.3 节,“事件预过滤”中,一个示例展示了如何为文件工具进行预过滤。如果事件表中既包含文件信息又包含非文件信息,后过滤是另一种仅查看文件事件信息的方法。向查询添加WHERE
子句以适当限制事件选择:
mysql> SELECT THREAD_ID, NUMBER_OF_BYTES
FROM performance_schema.events_waits_history
WHERE EVENT_NAME LIKE 'wait/io/file/%'
AND NUMBER_OF_BYTES IS NOT NULL;
+-----------+-----------------+
| THREAD_ID | NUMBER_OF_BYTES |
+-----------+-----------------+
| 11 | 66 |
| 11 | 47 |
| 11 | 139 |
| 5 | 24 |
| 5 | 834 |
+-----------+-----------------+
大多数性能模式表都有索引,这使得优化器可以访问除全表扫描之外的执行计划。这些索引还提高了与使用这些表的sys
模式视图等相关对象的性能。有关更多信息,请参见第 10.2.4 节,“优化性能模式查询”。
29.6 性能模式仪器命名约定
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-instrument-naming.html
一个仪器名称由一系列由 '/'
字符分隔的元素组成。示例名称:
wait/io/file/myisam/log
wait/io/file/mysys/charset
wait/lock/table/sql/handler
wait/synch/cond/mysys/COND_alarm
wait/synch/cond/sql/BINLOG::update_cond
wait/synch/mutex/mysys/BITMAP_mutex
wait/synch/mutex/sql/LOCK_delete
wait/synch/rwlock/sql/Query_cache_query::lock
stage/sql/closing tables
stage/sql/Sorting result
statement/com/Execute
statement/com/Query
statement/sql/create_table
statement/sql/lock_tables
errors
仪器名称空间具有类似树状结构。仪器名称中的元素从左到右提供了从更一般到更具体的进展。名称中的元素数量取决于仪器的类型。
在名称中给定元素的解释取决于其左侧的元素。例如,myisam
出现在以下两个名称中,但第一个名称中的 myisam
与文件 I/O 有关,而第二个名称中的 myisam
与同步仪器有关:
wait/io/file/myisam/log
wait/synch/cond/myisam/MI_SORT_INFO::cond
仪器名称由性能模式实现定义的前缀结构和由实现仪器代码的开发人员定义的后缀组成。仪器前缀的顶层元素指示仪器的类型。此元素还确定performance_timers
表中的哪个事件计时器适用于该仪器。对于仪器名称的前缀部分,顶层元素指示仪器的类型。
仪器名称的后缀部分来自仪器本身的代码。后缀可能包括以下级别:
-
主要元素的名称(服务器模块,如
myisam
,innodb
,mysys
或sql
)或插件名称。 -
代码中变量的名称,形式为
XXX
(全局变量)或*
CCC*::*
MMM*
(类CCC
中的成员MMM
)。示例:COND_thread_cache
,THR_LOCK_myisam
,BINLOG::LOCK_index
。 -
顶层仪器元素
-
空闲仪器元素
-
错误仪器元素
-
内存仪器元素
-
阶段仪器元素
-
语句仪器元素
-
线程仪器元素
-
等待仪器元素
顶层仪器元素
-
idle
: 一个被检测的空闲事件。这个仪器没有进一步的元素。 -
error
: 一个被检测的错误事件。这个仪器没有进一步的元素。 -
memory
: 一个被检测的内存事件。 -
stage
: 一个被检测的阶段事件。 -
statement
: 一个被检测的语句事件。 -
transaction
: 一个被检测的事务事件。这个仪器没有进一步的元素。 -
wait
: 一个被检测的等待事件。
空闲仪器元素
idle
仪器用于空闲事件,性能模式生成这些事件,如第 29.12.3.5 节中socket_instances.STATE
列的描述所述。
错误仪器元素
error
仪器指示是否收集有关服务器错误和警告的信息。这个仪器默认启用。setup_instruments
表中error
行的TIMED
列不适用,因为不收集时间信息。
内存仪器元素
内存仪器默认情况下是启用的。内存仪器可以在启动时启用或禁用,或者通过更新setup_instruments
表中相关仪器的ENABLED
列来在运行时动态启用或禁用。内存仪器的名称形式为memory/*
code_area*/*
instrument_name*
,其中*code_area
是一个值,例如sql
或myisam
,而instrument_name
*是仪器的详细信息。
以memory/performance_schema/
前缀命名的仪器公开了性能模式中内部缓冲区分配了多少内存。memory/performance_schema/
仪器是内置的,始终启用,并且无法在启动时或运行时禁用。内置内存仪器仅在memory_summary_global_by_event_name
表中显示。有关更多信息,请参见第 29.17 节,“性能模式内存分配模型”。
阶段仪器元素
阶段工具的名称形式为stage/*
code_area*/*
stage_name*
,其中*code_area
是诸如sql
或myisam
之类的值,stage_name
*表示语句处理阶段,例如Sorting result
或Sending data
。阶段对应于SHOW PROCESSLIST
显示的线程状态或在信息模式PROCESSLIST
表中可见的状态。
语句工具元素
-
statement/abstract/*
:用于语句操作的抽象工具。在确切语句类型未知的语句分类早期阶段使用抽象工具,然后在了解类型后将其更改为更具体的语句工具。有关此过程的描述,请参阅 Section 29.12.6, “Performance Schema Statement Event Tables”。 -
statement/com
:一个被检测的命令操作。这些名称对应于COM_*
xxx*
操作(请参阅mysql_com.h
头文件和sql/sql_parse.cc
。例如,statement/com/Connect
和statement/com/Init DB
工具对应于COM_CONNECT
和COM_INIT_DB
命令。 -
statement/scheduler/event
:用于跟踪事件调度器执行的所有事件的单个工具。当计划事件开始执行时,此工具开始发挥作用。 -
statement/sp
:由存储程序执行的一个被检测的内部指令。例如,statement/sp/cfetch
和statement/sp/freturn
工具用于游标获取和函数返回指令。 -
statement/sql
:一个被检测的 SQL 语句操作。例如,statement/sql/create_db
和statement/sql/select
工具用于CREATE DATABASE
和SELECT
语句。
线程工具元素
被检测的线程显示在setup_threads
表中,该表公开线程类名称和属性。
线程工具以thread
开头(例如,thread/sql/parser_service
或thread/performance_schema/setup
)。
ndbcluster
插件线程的线程工具名称以thread/ndbcluster/
开头;有关更多信息,请参阅 ndbcluster Plugin Threads。
等待工具元素
-
wait/io
一个被检测的 I/O 操作。
-
wait/io/file
一个被检测的文件 I/O 操作。对于文件,等待是等待文件操作完成的时间(例如,调用
fwrite()
)。由于缓存,磁盘上的物理文件 I/O 可能不会在此调用中发生。 -
wait/io/socket
一个被检测的套接字操作。套接字工具的名称形式为
wait/io/socket/sql/*
socket_type*
。服务器为它支持的每种网络协议都有一个监听套接字。与 TCP/IP 或 Unix 套接字文件连接的监听套接字相关的工具具有server_tcpip_socket
或server_unix_socket
的*socket_type
值。当一个监听套接字检测到一个连接时,服务器将连接传输给由单独线程管理的新套接字。新连接线程的工具具有client_connection
的socket_type
*值。 -
wait/io/table
一个被检测的表 I/O 操作。这些包括对持久基表或临时表的行级访问。影响行的操作包括获取、插入、更新和删除。对于视图,等待与视图引用的基表相关联。
与大多数等待不同,表 I/O 等待可能包括其他等待。例如,表 I/O 可能包括文件 I/O 或内存操作。因此,表 I/O 等待的
events_waits_current
通常有两行。有关更多信息,请参见第 29.8 节,“性能模式原子和分子事件”。一些行操作可能导致多个表 I/O 等待。例如,插入可能激活触发器导致更新。
-
-
wait/lock
一个被检测的锁操作。
-
wait/lock/table
一个被检测的表锁操作。
-
wait/lock/metadata/sql/mdl
一个被检测的元数据锁操作。
-
-
wait/synch
一个被检测的同步对象。对于同步对象,
TIMER_WAIT
时间包括在尝试获取对象锁时被阻塞的时间。-
wait/synch/cond
一个条件被一个线程用来通知其他线程他们等待的事情已经发生。如果一个线程在等待一个条件,它可以唤醒并继续执行。如果有多个线程在等待,它们都可以被唤醒并竞争它们等待的资源。
-
wait/synch/mutex
一个用于允许访问资源(如可执行代码段)并防止其他线程访问资源的互斥对象。
-
wait/synch/prlock
一个优先级读/写锁锁对象。
-
wait/synch/rwlock
用于锁定特定变量以防止其他线程使用的普通读/写锁对象。多个线程可以同时获取共享读锁。独占写锁一次只能被一个线程获取。
-
wait/synch/sxlock
一个共享-独占(SX)锁是一种类型的 rwlock 锁对象,它允许其他线程进行不一致的读取,同时提供对共享资源的写访问。
sxlocks
优化并发性,提高读写工作负载的可伸缩性。
-
29.7 性能模式状态监控
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-status-monitoring.html
与性能模式相关的几个状态变量有:
mysql> SHOW STATUS LIKE 'perf%';
+-----------------------------------------------+-------+
| Variable_name | Value |
+-----------------------------------------------+-------+
| Performance_schema_accounts_lost | 0 |
| Performance_schema_cond_classes_lost | 0 |
| Performance_schema_cond_instances_lost | 0 |
| Performance_schema_digest_lost | 0 |
| Performance_schema_file_classes_lost | 0 |
| Performance_schema_file_handles_lost | 0 |
| Performance_schema_file_instances_lost | 0 |
| Performance_schema_hosts_lost | 0 |
| Performance_schema_locker_lost | 0 |
| Performance_schema_memory_classes_lost | 0 |
| Performance_schema_metadata_lock_lost | 0 |
| Performance_schema_mutex_classes_lost | 0 |
| Performance_schema_mutex_instances_lost | 0 |
| Performance_schema_nested_statement_lost | 0 |
| Performance_schema_program_lost | 0 |
| Performance_schema_rwlock_classes_lost | 0 |
| Performance_schema_rwlock_instances_lost | 0 |
| Performance_schema_session_connect_attrs_lost | 0 |
| Performance_schema_socket_classes_lost | 0 |
| Performance_schema_socket_instances_lost | 0 |
| Performance_schema_stage_classes_lost | 0 |
| Performance_schema_statement_classes_lost | 0 |
| Performance_schema_table_handles_lost | 0 |
| Performance_schema_table_instances_lost | 0 |
| Performance_schema_thread_classes_lost | 0 |
| Performance_schema_thread_instances_lost | 0 |
| Performance_schema_users_lost | 0 |
+-----------------------------------------------+-------+
性能模式状态变量提供了有关由于内存限制而无法加载或创建的仪器化信息。这些变量的名称有几种形式:
-
Performance_schema_*
xxx*_classes_lost
表示无法加载类型为xxx
的仪器数量。 -
Performance_schema_*
xxx*_instances_lost
表示无法创建对象类型为xxx
的实例数量。 -
Performance_schema_*
xxx*_handles_lost
表示无法打开对象类型为xxx
的实例数量。 -
Performance_schema_locker_lost
表示有多少事件“丢失”或未记录。
例如,如果在服务器源代码中为互斥仪器进行了仪器化,但服务器在运行时无法为仪器分配内存,则会增加 Performance_schema_mutex_classes_lost
。互斥仍然作为同步对象运行(即,服务器继续正常运行),但不会收集其性能数据。如果可以分配仪器,则可以用于初始化仪器化的互斥实例。对于全局互斥体这样的单例互斥体,只有一个实例。其他互斥体每个连接或每个页面在各种缓存和数据缓冲区中有一个实例,因此实例数量随时间变化。增加最大连接数或某些缓冲区的最大大小会增加一次可能分配的实例的最大数量。如果服务器无法创建给定的仪器化互斥实例,则会增加 Performance_schema_mutex_instances_lost
。
假设以下条件成立:
-
服务器使用
--performance_schema_max_mutex_classes=200
选项启动,因此有 200 个互斥仪器的空间。 -
已加载了 150 个互斥仪器。
-
名为
plugin_a
的插件包含 40 个互斥仪器。 -
名为
plugin_b
的插件包含 20 个互斥仪器。
服务器根据插件需要的数量和可用数量为插件分配互斥仪器,如下面的语句序列所示:
INSTALL PLUGIN plugin_a
服务器现在有 150+40 = 190 个互斥仪器。
UNINSTALL PLUGIN plugin_a;
服务器仍然有 190 个仪器。插件代码生成的所有历史数据仍然可用,但不会收集仪器的新事件。
INSTALL PLUGIN plugin_a;
服务器检测到已经定义了 40 个仪器,因此不会创建新的仪器,并且先前分配的内部内存缓冲区将被重用。服务器仍然有 190 个仪器。
INSTALL PLUGIN plugin_b;
服务器有 200-190 = 10 个仪器的空间(在本例中是互斥类),并且发现插件包含 20 个新仪器。加载了 10 个仪器,而 10 个被丢弃或“丢失”。Performance_schema_mutex_classes_lost
指示了丢失的仪器(互斥类)的数量:
mysql> SHOW STATUS LIKE "perf%mutex_classes_lost";
+---------------------------------------+-------+
| Variable_name | Value |
+---------------------------------------+-------+
| Performance_schema_mutex_classes_lost | 10 |
+---------------------------------------+-------+
1 row in set (0.10 sec)
仪器仍在工作并为 plugin_b
收集(部分)数据。
当服务器无法创建互斥仪器时,会出现以下结果:
-
仪器未插入
setup_instruments
表中。 -
Performance_schema_mutex_classes_lost
增加了 1。 -
Performance_schema_mutex_instances_lost
不会改变。(当互斥仪器未创建时,无法用于稍后创建仪器化的互斥实例。)
刚才描述的模式适用于所有类型的仪器,而不仅仅是互斥体。
Performance_schema_mutex_classes_lost
大于 0 的值可能出现在两种情况下:
-
为了节省一些内存空间,您可以使用
--performance_schema_max_mutex_classes=*
N*
启动服务器,其中N
小于默认值。默认值被选择为足以加载 MySQL 发行版中提供的所有插件,但如果某些插件从未加载,则可以减少此值。例如,您可能选择不加载发行版中的某些存储引擎。 -
您加载了一个为性能模式进行了仪器化的第三方插件,但在启动服务器时未考虑插件的仪器化内存需求。由于来自第三方,因此此引擎的仪器内存消耗不计入为
performance_schema_max_mutex_classes
选择的默认值。如果服务器对插件的仪器资源不足,并且您未明确使用
--performance_schema_max_mutex_classes=*
N*
分配更多资源,则加载插件会导致仪器资源匮乏。
如果为performance_schema_max_mutex_classes
选择的值太小,错误日志中不会报告任何错误,并且在运行时不会出现故障。然而,performance_schema
数据库中的表内容会缺少事件。Performance_schema_mutex_classes_lost
状态变量是唯一可见的迹象,表明由于无法创建仪器而导致一些事件被丢弃。
如果一个仪器没有丢失,那么性能模式就会知道它,并在实例化时使用。例如,wait/synch/mutex/sql/LOCK_delete
是setup_instruments
表中一个互斥体仪器的名称。这个单一仪器在代码中创建互斥体时使用(在THD::LOCK_delete
中),然而服务器运行时需要多个互斥体实例。在这种情况下,LOCK_delete
是一个每个连接(THD
)的互斥体,所以如果服务器有 1000 个连接,就有 1000 个线程,以及 1000 个被标记的LOCK_delete
互斥体实例(THD::LOCK_delete
)。
如果服务器没有足够的空间来容纳这 1000 个被标记的互斥体(实例),一些互斥体会被创建并标记,而另一些则会被创建但不被标记。如果服务器只能创建 800 个实例,那么就会丢失 200 个实例。服务器继续运行,但会将Performance_schema_mutex_instances_lost
增加 200,以表示无法创建实例。
如果Performance_schema_mutex_instances_lost
的值大于 0,可能是因为代码在运行时初始化的互斥体比为--performance_schema_max_mutex_instances=*
N*
分配的数量多。
关键是,如果SHOW STATUS LIKE 'perf%'
显示没有丢失任何内容(所有值都为零),那么性能模式数据是准确的,可以信赖。如果有内容丢失,数据就是不完整的,性能模式无法记录所有内容,因为给定的内存量不足。在这种情况下,特定的Performance_schema_*
xxx*_lost
变量指示了问题区域。
在某些情况下,有意造成仪器匮乏可能是合适的。例如,如果您不关心文件 I/O 的性能数据,可以将服务器启动时与文件 I/O 相关的所有性能模式参数设置为 0。不会为与文件相关的类、实例或句柄分配任何内存,并且所有文件事件都会丢失。
使用SHOW ENGINE PERFORMANCE_SCHEMA STATUS
来检查性能模式代码的内部操作:
mysql> SHOW ENGINE PERFORMANCE_SCHEMA STATUS\G
...
*************************** 3\. row ***************************
Type: performance_schema
Name: events_waits_history.size
Status: 76
*************************** 4\. row ***************************
Type: performance_schema
Name: events_waits_history.count
Status: 10000
*************************** 5\. row ***************************
Type: performance_schema
Name: events_waits_history.memory
Status: 760000
...
*************************** 57\. row ***************************
Type: performance_schema
Name: performance_schema.memory
Status: 26459600
...
这个语句旨在帮助数据库管理员理解不同性能模式选项对内存需求的影响。有关字段含义的描述,请参阅第 15.7.7.15 节,“SHOW ENGINE Statement”。
29.8 性能模式原子和分子事件
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-atom-molecule-events.html
对于表 I/O 事件,在events_waits_current
中通常有两行,而不是一行。例如,行提取可能导致类似以下的行:
Row# EVENT_NAME TIMER_START TIMER_END
---- ---------- ----------- ---------
1 wait/io/file/myisam/dfile 10001 10002
2 wait/io/table/sql/handler 10000 NULL
行提取导致文件读取。在这个例子中,表 I/O 提取事件在文件 I/O 事件之前开始,但尚未完成(其TIMER_END
值为NULL
)。文件 I/O 事件“嵌套”在表 I/O 事件中。
这是因为,与其他“原子”等待事件(如互斥或文件 I/O)不同,表 I/O 事件是“分子”事件,并包括(重叠)其他事件。在events_waits_current
中,表 I/O 事件通常有两行:
-
最近的表 I/O 等待事件的一行
-
任何类型的最新等待事件的一行
通常情况下,“任何类型”的等待事件与表 I/O 事件不同。随着每个子事件的完成,它会从events_waits_current
中消失。在此时,直到下一个子事件开始之前,表 I/O 等待也是任何类型的最新等待。
29.9 性能模式表用于当前和历史事件
原文:
dev.mysql.com/doc/refman/8.0/en/performance-schema-event-tables.html
对于等待、阶段、语句和事务事件,性能模式可以监视和存储当前事件。此外,当事件结束时,性能模式可以将它们存储在历史表中。对于每种事件类型,性能模式使用三个表来存储当前和历史事件。这些表的名称采用以下形式,其中*xxx
*表示事件类型(waits
、stages
、statements
、transactions
):
-
events_*
xxx*_current
: “当前事件”表为每个线程存储当前监视的事件(每个线程一行)。 -
events_*
xxx*_history
: “最近历史”表存储每个线程中已结束的最新事件(每个线程最多一定数量的行)。 -
events_*
xxx*_history_long
: “长历史”表存储全局结束的最新事件(跨所有线程,每个表最多一定数量的行)。
每种事件类型的_current
表每个线程包含一行,因此没有用于配置其最大大小的系统变量。性能模式自动调整历史表的大小,或者可以在服务器启动时使用特定于表的系统变量显式配置大小,如在描述各个历史表的部分中所示。典型的自动调整值为_history
表每个线程 10 行,_history_long
表总共 10,000 行。
对于每种事件类型,_current
、_history
和_history_long
表具有相同的列。_current
和_history
表具有相同的索引。_history_long
表没有索引。
_current
表显示服务器当前正在发生的情况。当当前事件结束时,它将从其_current
表中移除。
_history
和_history_long
表显示最近发生的事件。当历史表变满时,旧事件将被丢弃,新事件将被添加。行从_history
和_history_long
表中以不同的方式过期,因为这些表有不同的用途:
-
_history
用于独立于全局服务器负载调查单个线程。 -
_history_long
用于全局调查服务器,而不是每个线程。
两种历史表之间的区别与数据保留政策有关。当事件首次出现时,两个表包含相同的数据。然而,随着时间的推移,每个表中的数据会以不同的方式过期,因此在每个表中可能会保留更长或更短的时间:
-
对于
_history
,当表对于给定线程包含最大数量的行时,当为该线程添加新行时,最旧的线程行将被丢弃。 -
对于
_history_long
,当表变满时,无论哪个线程生成了这两行,当添加新行时,最老的行都会被丢弃。
当一个线程结束时,它的所有行都会从_history
表中丢弃,但不会从_history_long
表中丢弃。
以下示例说明了如何向这两种类型的历史表中添加和丢弃事件的差异。这些原则同样适用于所有事件类型。该示例基于以下假设:
-
性能模式被配置为在
_history
表中保留每个线程的 10 行,在_history_long
表中总共保留 10,000 行。 -
线程 A 每秒生成 1 个事件。
线程 B 每秒生成 100 个事件。
-
没有其他线程在运行。
执行 5 秒后:
-
A 和 B 分别生成了 5 和 500 个事件。
-
_history
包含了 A 的 5 行和 B 的 10 行。因为每个线程的存储限制为 10 行,所以对于 A 没有丢弃行,而对于 B 已经丢弃了 490 行。 -
_history_long
包含了 A 的 5 行和 B 的 500 行。因为表的最大行数为 10,000 行,所以对于任何一个线程都没有丢弃行。
执行 5 分钟(300 秒)后:
-
A 和 B 分别生成了 300 和 30,000 个事件。
-
_history
包含了 A 的 10 行和 B 的 10 行。因为每个线程的存储限制为 10 行,对于 A 已经丢弃了 290 行,而对于 B 已经丢弃了 29,990 行。A 的行包含了 10 秒前的数据,而 B 的行只包含了 0.1 秒前的数据。 -
_history_long
包含了 10,000 行。因为 A 和 B 一起每秒生成 101 个事件,所以表中的数据大约是 10,000/101 = 99 秒前的数据,其中 B 的行数大约是 A 的 100 倍。
文章评论