# Performance Schema

**Performance Schema提供了有关MySQL服务器内部运行的操作上的底层指标**。为了解释清楚Performance Schema的工作机制，先介绍两个概念：

* <mark style="color:blue;">**程序插桩(instrument)**</mark>，指的是**在MySQL代码中插入探测代码**，以获取我们想了解的信息。
* <mark style="color:blue;">**消费者表(consumer)**</mark>，指的是**存储关于程序插桩代码信息的表**。如果我们为查询模块添加插桩，相应的消费者表将记录诸如执行总数、未使用索引的次数、花费的时间等信息。

启用插桩会调用额外的代码，这意味着插桩会消耗CPU资源。

## **程序插桩(instrument)**

在performance\_schema中，<mark style="color:blue;">**setup\_instruments表包含所有支持的插桩的列表**</mark>。所有插桩的名称都由用斜杠分隔的部件组成：

```sql
SELECT * FROM setup_instruments;

+-------------------------------------------------------+-------+-----+
|NAME                                                   |ENABLED|TIMED|
+-------------------------------------------------------+-------+-----+
|wait/synch/mutex/sql/TC_LOG_MMAP::LOCK_tc              |NO     |NO   |
|wait/synch/mutex/sql/LOCK_des_key_file                 |NO     |NO   |
|wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_commit        |NO     |NO   |
|wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_commit_queue  |NO     |NO   |
|wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_done          |NO     |NO   |
|wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_flush_queue   |NO     |NO   |
|wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index         |NO     |NO   |
|wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_log           |NO     |NO   |
|wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos|NO     |NO   |
|wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_sync          |NO     |NO   |
+-------------------------------------------------------+-------+-----+
```

## **消费者表(consumer)**

消费者表是插桩发送信息的目的地，**测量结果存储在Performance Schema数据库的多个表中**。基于它们的用途，可将表分为以下几个类别：

* <mark style="color:blue;">**当前和历史数据**</mark>

  * <mark style="color:blue;">**\*\_current**</mark>：当前服务器上进行中的事件。
  * *<mark style="color:blue;">**\*\_history**</mark>：每个线程最近完成的 10 个事件。*
  * <mark style="color:blue;">**\*\_history\_long**</mark>：从全局来看，每个线程最近完成的 10000 个事件。

  *\*\_history* 和 *\**\_history\_long 表的大小是可配置的。

  ```sql
  SELECT table_name
  FROM information_schema.tables
  WHERE table_schema = 'performance_schema'
    AND (
          table_name LIKE '%_current'
          OR table_name LIKE '%_history'
          OR table_name LIKE '%_history_long'
      );
      
  +--------------------------------+
  |table_name                      |
  +--------------------------------+
  |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|
  |events_waits_current            |
  |events_waits_history            |
  |events_waits_history_long       |
  +--------------------------------+
  ```
* <mark style="color:blue;">**汇总表**</mark>\
  汇总表保存有关该表所建议的内容的**聚合信息**。\
  例如，memory\_summary\_by\_thread\_by\_event\_name 表保存了用户连接或任何后台线程的每个MySQL线程的聚合内存使用情况。
* <mark style="color:blue;">**摘要**</mark>\
  摘要是一种通过**删除查询中的变量**来聚合查询的方法。

  ```sql
  SELECT * FROM sakila.rental WHERE rental_id = 1;
  SELECT * FROM sakila.rental WHERE rental_id = 2;
  SELECT * FROM sakila.rental WHERE rental_id = 3;
  ```

  上述查询的摘要是：

  ```sql
  SELECT * FROM sakila.rental WHERE rental_id = ?
  ```
* <mark style="color:blue;">**实例表(Instance)**</mark>

  实例是指对象实例，用于MySQL安装程序。例如，file\_instances表包含文件名和访问这些文件的线程数。

  ```sql
  SELECT
      table_name
  FROM information_schema.tables
  WHERE table_schema = 'performance_schema'
    AND table_name LIKE '%_instances';
  ```
* [<mark style="color:blue;">**设置表(Setup)**</mark>](https://bohans.gitbook.io/ji-chu/mysql/sql-you-hua/performance-schema/pei-zhi)\
  设置表用于performance\_schema的运行时设置。

  ```sql
  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_timers     |
  +-----------------+
  ```
* <mark style="color:blue;">**其他表**</mark>\
  还有一些表的名称没有遵循严格的模式。例如，metadata\_locks 表保存关于元数据锁的数据。

## <mark style="color:orange;">资源消耗</mark>

Performance Schema收集的数据保存在<mark style="color:blue;">**内存**</mark>中，可以通过设置消费者表的最大大小来限制其使用的内存量。performance\_schema中的一些表<mark style="color:blue;">**支持自动伸缩**</mark>，这意味着它们在启动时分配最小数量的内存，并根据需要调整其大小。然&#x800C;**，一旦分配了内存，即使禁用了特定的插桩并截断了表，也不会再释放该内存**。

每个插桩指令的调用都会添加两个宏调用，以将数据存储在performance\_schema中。这意味着<mark style="color:orange;">**插桩越多，CPU的使用率就越高。**</mark>

## **sys Schema**

自5.7版以来，标准MySQL发行版包括一个和performance\_schema配套使用的<mark style="color:blue;">**sys schema**</mark>，它全部基于performance\_schema上的视图和存储例程组成。它的<mark style="color:blue;">**设计目的是让performance\_schema体验更加流畅，它本身并不存储任何数据**</mark>。

```sql
SELECT
    table_name
FROM information_schema.tables
WHERE table_schema = 'sys';

+---------------------------------+
|table_name                       |
+---------------------------------+
|host_summary                     |
|host_summary_by_file_io          |
|host_summary_by_file_io_type     |
|host_summary_by_stages           |
|host_summary_by_statement_latency|
|host_summary_by_statement_type   |
|innodb_buffer_stats_by_schema    |
|innodb_buffer_stats_by_table     |
|innodb_lock_waits                |
|io_by_thread_by_latency          |
|...                              |
+---------------------------------+
```
