1. 程式人生 > >資料庫物件事件與屬性統計 | performance_schema全方位介紹

資料庫物件事件與屬性統計 | performance_schema全方位介紹

上一篇 《事件統計 | performance_schema全方位介紹》 詳細介紹了performance_schema的事件統計表,但這些統計資料粒度太粗,僅僅按照事件的5大類別+使用者、執行緒等維度進行分類統計,但有時候我們需要從更細粒度的維度進行分類統計,例如:某個表的IO開銷多少、鎖開銷多少、以及使用者連線的一些屬性統計資訊等。此時就需要檢視資料庫物件事件統計表與屬性統計表了。今天將帶領大家一起踏上系列第五篇的征程(全系共7個篇章),本期將為大家全面講解performance_schema中物件事件統計表與屬性統計表。下面,請跟隨我們一起開始performance_schema系統的學習之旅吧~

友情提示:下文中的統計表中大部分欄位含義與上一篇 《事件統計 | performance_schema全方位介紹》 中提到的統計表欄位含義相同,下文中不再贅述。此外,由於部分統計表中的記錄內容過長,限於篇幅會省略部分文字,如有需要請自行安裝MySQL 5.7.11以上版本跟隨本文進行同步操作檢視。

一、資料庫物件統計表

1.資料庫表級別物件等待事件統計

按照資料庫物件名稱(庫級別物件和表級別物件,如:庫名和表名)進行統計的等待事件。按照OBJECT_TYPE、OBJECT_SCHEMA、OBJECT_NAME列進行分組,按照COUNT_STAR、xxx_TIMER_WAIT欄位進行統計。包含一張objects_summary_global_by_type表。

我們先來看看錶中記錄的統計資訊是什麼樣子的。

[email protected] : performance_schema 11:10:42> select * from objects_summary_global_by_type where SUM_TIMER_WAIT!=0\G;
*************************** 1. row ***************************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: xiaoboluo
OBJECT_NAME: test
COUNT_STAR: 56
SUM_TIMER_WAIT: 195829830101250
MIN_TIMER_
WAIT: 2971125
AVG_TIMER_WAIT: 3496961251500
MAX_TIMER_WAIT: 121025235946125
1 row in set (0.00 sec)

從表中的記錄內容可以看到,按照庫xiaoboluo下的表test進行分組,統計了表相關的等待事件呼叫次數,總計、最小、平均、最大延遲時間資訊,利用這些資訊,我們可以大致瞭解InnoDB中表的訪問效率排行統計情況,一定程度上反應了對儲存引擎介面呼叫的效率。

2.表I/O等待和鎖等待事件統計

與objects_summary_global_by_type 表統計資訊類似,表I/O等待和鎖等待事件統計資訊更為精細,細分了每個表的增刪改查的執行次數,總等待時間,最小、最大、平均等待時間,甚至精細到某個索引的增刪改查的等待時間,表IO等待和鎖等待事件instruments(wait/io/table/sql/handler和wait/lock/table/sql/handler )預設開啟,在setup_consumers表中無具體的對應配置,預設表IO等待和鎖等待事件統計表中就會統計相關事件資訊。包含如下幾張表:

[email protected] : performance_schema 06:50:03> show tables like '%table%summary%';
+------------------------------------------------+
| Tables_in_performance_schema (%table%summary%) |
+------------------------------------------------+
| table_io_waits_summary_by_index_usage | # 按照每個索引進行統計的表I/O等待事件
| table_io_waits_summary_by_table | # 按照每個表進行統計的表I/O等待事件
| table_lock_waits_summary_by_table | # 按照每個表進行統計的表鎖等待事件
+------------------------------------------------+
3 rows in set (0.00 sec)

我們先來看看錶中記錄的統計資訊是什麼樣子的。

# table_io_waits_summary_by_index_usage表
[email protected] : performance_schema 01:55:49> select * from table_io_waits_summary_by_index_usage where SUM_TIMER_WAIT!=0\G;
*************************** 1. row ***************************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: xiaoboluo
OBJECT_NAME: test
 INDEX_NAME: PRIMARY
 COUNT_STAR: 1
SUM_TIMER_WAIT: 56688392
MIN_TIMER_WAIT: 56688392
AVG_TIMER_WAIT: 56688392
MAX_TIMER_WAIT: 56688392
 COUNT_READ: 1
SUM_TIMER_READ: 56688392
MIN_TIMER_READ: 56688392
AVG_TIMER_READ: 56688392
MAX_TIMER_READ: 56688392
......
1 row in set (0.00 sec)
# table_io_waits_summary_by_table表
[email protected] : performance_schema 01:56:16> select * from table_io_waits_summary_by_table where SUM_TIMER_WAIT!=0\G;
*************************** 1. row ***************************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: xiaoboluo
OBJECT_NAME: test
 COUNT_STAR: 1
............
1 row in set (0.00 sec)
# table_lock_waits_summary_by_table表
[email protected] : performance_schema 01:57:20> select * from table_lock_waits_summary_by_table where SUM_TIMER_WAIT!=0\G;
*************************** 1. row ***************************
                 OBJECT_TYPE: TABLE
               OBJECT_SCHEMA: xiaoboluo
                 OBJECT_NAME: test
............
           COUNT_READ_NORMAL: 0
       SUM_TIMER_READ_NORMAL: 0
       MIN_TIMER_READ_NORMAL: 0
       AVG_TIMER_READ_NORMAL: 0
       MAX_TIMER_READ_NORMAL: 0
COUNT_READ_WITH_SHARED_LOCKS: 0
SUM_TIMER_READ_WITH_SHARED_LOCKS: 0
MIN_TIMER_READ_WITH_SHARED_LOCKS: 0
AVG_TIMER_READ_WITH_SHARED_LOCKS: 0
MAX_TIMER_READ_WITH_SHARED_LOCKS: 0
......
1 row in set (0.00 sec)

從上面表中的記錄資訊我們可以看到,table_io_waits_summary_by_index_usage表和table_io_waits_summary_by_table有著類似的統計列,但table_io_waits_summary_by_table表是包含整個表的增刪改查等待事件分類統計,table_io_waits_summary_by_index_usage區分了每個表的索引的增刪改查等待事件分類統計,而table_lock_waits_summary_by_table表統計緯度類似,但它是用於統計增刪改查對應鎖等待時間,而不是IO等待時間,這些表的分組和統計列含義請大家自行舉一反三,這裡不再贅述,下面針對這三張表做一些必要的說明:

table_io_waits_summary_by_table表:

該表允許使用TRUNCATE TABLE語句。只將統計列重置為零,而不是刪除行。對該表執行truncate還會隱式truncate table_io_waits_summary_by_index_usage表

table_io_waits_summary_by_index_usage表:

按照與table_io_waits_summary_by_table的分組列+INDEX_NAME列進行分組,INDEX_NAME有如下幾種 : 

· 如果使用到了索引,則這裡顯示索引的名字,如果為PRIMARY,則表示表I/O使用到了主鍵索引 

· 如果值為NULL,則表示表I/O沒有使用到索引 

· 如果是插入操作,則無法使用到索引,此時的統計值是按照INDEX_NAME = NULL計算的

該表允許使用TRUNCATE TABLE語句。只將統計列重置為零,而不是刪除行。該表執行truncate時也會隱式觸發table_io_waits_summary_by_table表的truncate操作。另外使用DDL語句更改索引結構時,會導致該表的所有索引統計資訊被重置

table_lock_waits_summary_by_table表:

該表的分組列與table_io_waits_summary_by_table表相同

該表包含有關內部和外部鎖的資訊: 

· 內部鎖對應SQL層中的鎖。是通過呼叫thr_lock()函式來實現的。(官方手冊上說有一個OPERATION列來區分鎖型別,該列有效值為:read normal、read with shared locks、read high priority、read no insert、write allow write、write concurrent insert、write delayed、write low priority、write normal。但在該表的定義上並沒有看到該欄位) 

· 外部鎖對應儲存引擎層中的鎖。通過呼叫handler::external_lock()函式來實現。(官方手冊上說有一個OPERATION列來區分鎖型別,該列有效值為:read external、write external。但在該表的定義上並沒有看到該欄位)

該表允許使用TRUNCATE TABLE語句。只將統計列重置為零,而不是刪除行。

3.檔案I/O事件統計

檔案I/O事件統計表只記錄等待事件中的IO事件(不包含table和socket子類別),檔案I/O事件instruments預設開啟,在setup_consumers表中無具體的對應配置。它包含如下兩張表:

[email protected] : performance_schema 06:48:12> show tables like '%file_summary%';
+-----------------------------------------------+
| Tables_in_performance_schema (%file_summary%) |
+-----------------------------------------------+
| file_summary_by_event_name                    |
| file_summary_by_instance                      |
+-----------------------------------------------+
2 rows in set (0.00 sec)

兩張表中記錄的內容很相近:

· file_summary_by_event_name:按照每個事件名稱進行統計的檔案IO等待事件

· file_summary_by_instance:按照每個檔案例項(對應具體的每個磁碟檔案,例如:表sbtest1的表空間檔案sbtest1.ibd)進行統計的檔案IO等待事件

我們先來看看錶中記錄的統計資訊是什麼樣子的。

# file_summary_by_event_name表
[email protected] : performance_schema 11:00:44> select * from file_summary_by_event_name where SUM_TIMER_WAIT !=0 and EVENT_NAME like '%innodb%' limit 1\G;
*************************** 1. row ***************************
         EVENT_NAME: wait/io/file/innodb/innodb_data_file
         COUNT_STAR: 802
     SUM_TIMER_WAIT: 412754363625
     MIN_TIMER_WAIT: 0
     AVG_TIMER_WAIT: 514656000
     MAX_TIMER_WAIT: 9498247500
         COUNT_READ: 577
     SUM_TIMER_READ: 305970952875
     MIN_TIMER_READ: 15213375
     AVG_TIMER_READ: 530278875
     MAX_TIMER_READ: 9498247500
SUM_NUMBER_OF_BYTES_READ: 11567104
......
1 row in set (0.00 sec)
# file_summary_by_instance表
[email protected] : performance_schema 11:01:23> select * from file_summary_by_instance where SUM_TIMER_WAIT!=0 and EVENT_NAME like '%innodb%' limit 1\G;
*************************** 1. row ***************************
           FILE_NAME: /data/mysqldata1/innodb_ts/ibdata1
         EVENT_NAME: wait/io/file/innodb/innodb_data_file
OBJECT_INSTANCE_BEGIN: 139882156936704
         COUNT_STAR: 33
............
1 row in set (0.00 sec)

從上面表中的記錄資訊我們可以看到:

· 每個檔案I/O統計表都有一個或多個分組列,以表明如何統計這些事件資訊。這些表中的事件名稱來自setup_instruments表中的name欄位: 

* file_summary_by_event_name表:按照EVENT_NAME列進行分組 ;

* file_summary_by_instance表:有額外的FILE_NAME、OBJECT_INSTANCE_BEGIN列,按照FILE_NAME、EVENT_NAME列進行分組,與file_summary_by_event_name 表相比,file_summary_by_instance表多了FILE_NAME和OBJECT_INSTANCE_BEGIN欄位,用於記錄具體的磁碟檔案相關資訊。

· 每個檔案I/O事件統計表有如下統計欄位:

* COUNT_STAR,SUM_TIMER_WAIT,MIN_TIMER_WAIT,AVG_TIMER_WAIT,MAX_TIMER_WAIT:這些列統計所有I/O運算元量和操作時間 ;

* COUNT_READ,SUM_TIMER_READ,MIN_TIMER_READ,AVG_TIMER_READ,MAX_TIMER_READ,SUM_NUMBER_OF_BYTES_READ:這些列統計了所有檔案讀取操作,包括FGETS,FGETC,FREAD和READ系統呼叫,還包含了這些I/O操作的資料位元組數 ;

* COUNT_WRITE,SUM_TIMER_WRITE,MIN_TIMER_WRITE,AVG_TIMER_WRITE,MAX_TIMER_WRITE,SUM_NUMBER_OF_BYTES_WRITE:這些列統計了所有檔案寫操作,包括FPUTS,FPUTC,FPRINTF,VFPRINTF,FWRITE和PWRITE系統呼叫,還包含了這些I/O操作的資料位元組數 ;

* COUNT_MISC,SUM_TIMER_MISC,MIN_TIMER_MISC,AVG_TIMER_MISC,MAX_TIMER_MISC:這些列統計了所有其他檔案I/O操作,包括CREATE,DELETE,OPEN,CLOSE,STREAM_OPEN,STREAM_CLOSE,SEEK,TELL,FLUSH,STAT,FSTAT,CHSIZE,RENAME和SYNC系統呼叫。注意:這些檔案I/O操作沒有位元組計數資訊。

檔案I/O事件統計表允許使用TRUNCATE TABLE語句。但只將統計列重置為零,而不是刪除行。

PS:MySQL server使用幾種快取技術通過快取從檔案中讀取的資訊來避免檔案I/O操作。當然,如果記憶體不夠時或者記憶體競爭比較大時可能導致查詢效率低下,這個時候您可能需要通過重新整理快取或者重啟server來讓其資料通過檔案I/O返回而不是通過快取返回。

4.套接字事件統計

套接字事件統計了套接字的讀寫呼叫次數和傳送接收位元組計數資訊,socket事件instruments預設關閉,在setup_consumers表中無具體的對應配置,包含如下兩張表:

· socket_summary_by_instance:針對每個socket例項的所有 socket I/O操作,這些socket操作相關的操作次數、時間和傳送接收位元組資訊由wait/io/socket/* instruments產生。但當連線中斷時,在該表中對應socket連線的資訊行將被刪除(這裡的socket是指的當前活躍的連線建立的socket例項)

· socket_summary_by_event_name:針對每個socket I/O instruments,這些socket操作相關的操作次數、時間和傳送接收位元組資訊由wait/io/socket/* instruments產生(這裡的socket是指的當前活躍的連線建立的socket例項)

可通過如下語句檢視:

[email protected] : performance_schema 06:53:42> show tables like '%socket%summary%';
+-------------------------------------------------+
| Tables_in_performance_schema (%socket%summary%) |
+-------------------------------------------------+
| socket_summary_by_event_name                    |
| socket_summary_by_instance                      |
+-------------------------------------------------+
2 rows in set (0.00 sec)

我們先來看看錶中記錄的統計資訊是什麼樣子的。

# socket_summary_by_event_name表
[email protected] : performance_schema 04:44:00> select * from socket_summary_by_event_name\G;
*************************** 1. row ***************************
          EVENT_NAME: wait/io/socket/sql/server_tcpip_socket
          COUNT_STAR: 2560
      SUM_TIMER_WAIT: 62379854922
      MIN_TIMER_WAIT: 1905016
      AVG_TIMER_WAIT: 24366870
      MAX_TIMER_WAIT: 18446696808701862260
          COUNT_READ: 0
      SUM_TIMER_READ: 0
      MIN_TIMER_READ: 0
      AVG_TIMER_READ: 0
      MAX_TIMER_READ: 0
SUM_NUMBER_OF_BYTES_READ: 0
......
*************************** 2. row ***************************
          EVENT_NAME: wait/io/socket/sql/server_unix_socket
          COUNT_STAR: 24
......
*************************** 3. row ***************************
          EVENT_NAME: wait/io/socket/sql/client_connection
          COUNT_STAR: 213055844
......
3 rows in set (0.00 sec)
# socket_summary_by_instance表
[email protected] : performance_schema 05:11:45> select * from socket_summary_by_instance where COUNT_STAR!=0\G;
*************************** 1. row ***************************
          EVENT_NAME: wait/io/socket/sql/server_tcpip_socket
OBJECT_INSTANCE_BEGIN: 2655350784
......
*************************** 2. row ***************************
          EVENT_NAME: wait/io/socket/sql/server_unix_socket
OBJECT_INSTANCE_BEGIN: 2655351104
......
*************************** 3. row ***************************
          EVENT_NAME: wait/io/socket/sql/client_connection
OBJECT_INSTANCE_BEGIN: 2658003840
......
*************************** 4. row ***************************
          EVENT_NAME: wait/io/socket/sql/client_connection
OBJECT_INSTANCE_BEGIN: 2658004160
......
4 rows in set (0.00 sec)

從上面表中的記錄資訊我們可以看到(與檔案I/O事件統計類似,兩張表也分別按照socket事件型別統計與按照socket instance進行統計)

· socket_summary_by_event_name表:按照EVENT_NAME列進行分組

· socket_summary_by_instance表:按照EVENT_NAME(該列有效值為wait/io/socket/sql/client_connection、wait/io/socket/sql/server_tcpip_socket、wait/io/socket/sql/server_unix_socket:)、OBJECT_INSTANCE_BEGIN列進行分組

每個套接字統計表都包含如下統計列:

· COUNT_STAR,SUM_TIMER_WAIT,MIN_TIMER_WAIT,AVG_TIMER_WAIT,MAX_TIMER_WAIT:這些列統計所有socket讀寫操作的次數和時間資訊

· COUNT_READ,SUM_TIMER_READ,MIN_TIMER_READ,AVG_TIMER_READ,MAX_TIMER_READ,SUM_NUMBER_OF_BYTES_READ:這些列統計所有接收操作(socket的RECV、RECVFROM、RECVMS型別操作,即以server為參照的socket讀取資料的操作)相關的次數、時間、接收位元組數等資訊

· COUNT_WRITE,SUM_TIMER_WRITE,MIN_TIMER_WRITE,AVG_TIMER_WRITE,MAX_TIMER_WRITE,SUM_NUMBER_OF_BYTES_WRITE:這些列統計了所有傳送操作(socket的SEND、SENDTO、SENDMSG型別操作,即以server為參照的socket寫入資料的操作)相關的次數、時間、接收位元組數等資訊

· COUNT_MISC,SUM_TIMER_MISC,MIN_TIMER_MISC,AVG_TIMER_MISC,MAX_TIMER_MISC:這些列統計了所有其他套接字操作,如socket的CONNECT、LISTEN,ACCEPT、CLOSE、SHUTDOWN型別操作。注意:這些操作沒有位元組計數

套接字統計表允許使用TRUNCATE TABLE語句(除events_statements_summary_by_digest之外),只將統計列重置為零,而不是刪除行。

PS:socket統計表不會統計空閒事件生成的等待事件資訊,空閒事件的等待資訊是記錄在等待事件統計表中進行統計的。

5.prepare語句例項統計表

performance_schema提供了針對prepare語句的監控記錄,並按照如下方法對錶中的內容進行管理。

· prepare語句預編譯:COM_STMT_PREPARE或SQLCOM_PREPARE命令在server中建立一個prepare語句。如果語句檢測成功,則會在prepared_statements_instances表中新新增一行。如果prepare語句無法檢測,則會增加Performance_schema_prepared_statements_lost狀態變數的值。

· prepare語句執行:為已檢測的prepare語句例項執行COM_STMT_EXECUTE或SQLCOM_PREPARE命令,同時會更新prepare_statements_instances表中對應的行資訊。

· prepare語句解除資源分配:對已檢測的prepare語句例項執行COM_STMT_CLOSE或SQLCOM_DEALLOCATE_PREPARE命令,同時將刪除prepare_statements_instances表中對應的行資訊。為了避免資源洩漏,請務必在prepare語句不需要使用的時候執行此步驟釋放資源。

我們先來看看錶中記錄的統計資訊是什麼樣子的。

[email protected] : performance_schema 10:50:38> select * from prepared_statements_instances\G;
*************************** 1. row ***************************
 OBJECT_INSTANCE_BEGIN: 139968890586816
         STATEMENT_ID: 1
       STATEMENT_NAME: stmt
             SQL_TEXT: SELECT 1
       OWNER_THREAD_ID: 48
       OWNER_EVENT_ID: 54
     OWNER_OBJECT_TYPE: NULL
   OWNER_OBJECT_SCHEMA: NULL
     OWNER_OBJECT_NAME: NULL
         TIMER_PREPARE: 896167000
       COUNT_REPREPARE: 0
         COUNT_EXECUTE: 0
     SUM_TIMER_EXECUTE: 0
     MIN_TIMER_EXECUTE: 0
     AVG_TIMER_EXECUTE: 0
     MAX_TIMER_EXECUTE: 0
         SUM_LOCK_TIME: 0
           SUM_ERRORS: 0
         SUM_WARNINGS: 0
     SUM_ROWS_AFFECTED: 0
         SUM_ROWS_SENT: 0
......
1 row in set (0.00 sec)

prepared_statements_instances表字段含義如下:

· OBJECT_INSTANCE_BEGIN:prepare語句事件的instruments 例項記憶體地址。

· STATEMENT_ID:由server分配的語句內部ID。文字和二進位制協議都使用該語句ID。

· STATEMENT_NAME:對於二進位制協議的語句事件,此列值為NULL。對於文字協議的語句事件,此列值是使用者分配的外部語句名稱。例如:PREPARE stmt FROM'SELECT 1';,語句名稱為stmt。

· SQL_TEXT:prepare的語句文字,帶“?”的表示是佔位符標記,後續execute語句可以對該標記進行傳參。

· OWNER_THREAD_ID,OWNER_EVENT_ID:這些列表示建立prepare語句的執行緒ID和事件ID。

· OWNER_OBJECT_TYPE,OWNER_OBJECT_SCHEMA,OWNER_OBJECT_NAME:對於由客戶端會話使用SQL語句直接建立的prepare語句,這些列值為NULL。對於由儲存程式建立的prepare語句,這些列值顯示相關儲存程式的資訊。如果使用者在儲存程式中忘記釋放prepare語句,那麼這些列可用於查詢這些未釋放的prepare對應的儲存程式,使用語句查詢:SELECT OWNER_OBJECT_TYPE,OWNER_OBJECT_SCHEMA,OWNER_OBJECT_NAME,STATEMENT_NAME,SQL_TEXT FROM performance_schema.prepared_statemments_instances WHERE OWNER_OBJECT_TYPE IS NOT NULL;

· TIMER_PREPARE:執行prepare語句本身消耗的時間。

· COUNT_REPREPARE:該行資訊對應的prepare語句在內部被重新編譯的次數,重新編譯prepare語句之後,之前的相關統計資訊就不可用了,因為這些統計資訊是作為語句執行的一部分被聚合到表中的,而不是單獨維護的。

· COUNT_EXECUTE,SUM_TIMER_EXECUTE,MIN_TIMER_EXECUTE,AVG_TIMER_EXECUTE,MAX_TIMER_EXECUTE:執行prepare語句時的相關統計資料。

· SUM_xxx:其餘的SUM_xxx開頭的列與語句統計表中的資訊相同,語句統計表後續章節會詳細介紹。

允許執行TRUNCATE TABLE語句,但是TRUNCATE TABLE只是重置prepared_statements_instances表的統計資訊列,但是不會刪除該表中的記錄,該表中的記錄會在prepare物件被銷燬釋放的時候自動刪除。

PS:什麼是prepare語句?prepare語句實際上就是一個預編譯語句,先把SQL語句進行編譯,且可以設定引數佔位符(例如:?符號),然後呼叫時通過使用者變數傳入具體的引數值(叫做變數繫結),如果一個語句需要多次執行而僅僅只是where條件不同,那麼使用prepare語句可以大大減少硬解析的開銷,prepare語句有三個步驟,預編譯prepare語句,執行prepare語句,釋放銷燬prepare語句,prepare語句支援兩種協議,前面已經提到過了,binary協議一般是提供給應用程式的mysql c api介面方式訪問,而文字協議提供給通過客戶端連線到mysql server的方式訪問,下面以文字協議的方式訪問進行演示說明:

· prepare步驟:語法PREPARE stmt_name FROM preparable_stmt,示例:PREPARE stmt FROM'SELECT 1'; 執行了該語句之後,在prepared_statements_instances表中就可以查詢到一個prepare示例物件了;

· execute步驟:語法EXECUTE stmt_name[USING @var_name [, @var_name] …],示例:execute stmt; 返回執行結果為1,此時在prepared_statements_instances表中的統計資訊會進行更新;

· DEALLOCATE PREPARE步驟:語法 {DEALLOCATE | DROP} PREPARE stmt_name,示例:drop prepare stmt; ,此時在prepared_statements_instances表中對應的prepare示例記錄自動刪除。

6.instance 統計表

instance表記錄了哪些型別的物件被檢測。這些表中記錄了事件名稱(提供收集功能的instruments名稱)及其一些解釋性的狀態資訊(例如:file_instances表中的FILE_NAME檔名稱和OPEN_COUNT檔案開啟次數),instance表主要有如下幾個:

· cond_instances:wait sync相關的condition物件例項;

· file_instances:檔案物件例項;

· mutex_instances:wait sync相關的Mutex物件例項;

· rwlock_instances:wait sync相關的lock物件例項;

· socket_instances:活躍連線例項。

這些表列出了等待事件中的sync子類事件相關的物件、檔案、連線。其中wait sync相關的物件型別有三種:cond、mutex、rwlock。每個例項表都有一個EVENT_NAME或NAME列,用於顯示與每行記錄相關聯的instruments名稱。instruments名稱可能具有多個部分並形成層次結構,詳見 "配置詳解 | performance_schema全方位介紹"

mutex_instances.LOCKED_BY_THREAD_ID和rwlock_instances.WRITE_LOCKED_BY_THREAD_ID列對於排查效能瓶頸或死鎖問題至關重要。

PS:對於mutexes、conditions和rwlocks,在執行時雖然允許修改配置,且配置能夠修改成功,但是有一部分instruments不生效,需要在啟動時配置才會生效,如果你嘗試著使用一些應用場景來追蹤鎖資訊,你可能在這些instance表中無法查詢到相應的資訊。

下面對這些表分別進行說明。

(1)cond_instances表

cond_instances表列出了server執行condition instruments 時performance_schema所見的所有condition,condition表示在程式碼中特定事件發生時的同步訊號機制,使得等待該條件的執行緒在該condition滿足條件時可以恢復工作。

· 當一個執行緒正在等待某事發生時,condition NAME列顯示了執行緒正在等待什麼condition(但該表中並沒有其他列來顯示對應哪個執行緒等資訊),但是目前還沒有直接的方法來判斷某個執行緒或某些執行緒會導致condition發生改變。

我們先來看看錶中記錄的統計資訊是什麼樣子的。

[email protected] : performance_schema 02:50:02> select * from cond_instances limit 1;
+----------------------------------+-----------------------+
| NAME                             | OBJECT_INSTANCE_BEGIN |
+----------------------------------+-----------------------+
|
wait/synch/cond/sql/COND_manager |              31903008 |
+----------------------------------+-----------------------+
1 row in set (0.00 sec)

cond_instances表字段含義如下:

· NAME:與condition相關聯的instruments名稱;

· OBJECT_INSTANCE_BEGIN:instruments condition的記憶體地址;

· PS:cond_instances表不允許使用TRUNCATE TABLE語句。

 (2)file_instances表

file_instances表列出執行檔案I/O instruments時performance_schema所見的所有檔案。 如果磁碟上的檔案從未開啟,則不會在file_instances中記錄。當檔案從磁碟中刪除時,它也會從file_instances表中刪除對應的記錄。

我們先來看看錶中記錄的統計資訊是什麼樣子的。

[email protected] : performance_schema 02:53:40> select * from file_instances where OPEN_COUNT>0 limit 1;
+------------------------------------+--------------------------------------+------------+
| FILE_NAME                          | EVENT_NAME                          | OPEN_COUNT |
+------------------------------------+--------------------------------------+------------+
| /data/mysqldata1/innodb_ts/ibdata1 | wait/io/file/innodb/innodb_data_file |          3 |
+------------------------------------+--------------------------------------+------------+
1 row in set (0.00 sec)

file_instances表字段含義如下:

· FILE_NAME:磁碟檔名稱;

· EVENT_NAME:與檔案相關聯的instruments名稱;

OPEN_COUNT:檔案當前已開啟控制代碼的計數。如果檔案開啟然後關閉,則開啟1次,但OPEN_COUNT列將加一然後減一,因為OPEN_COUNT列只統計當前已開啟的檔案控制代碼數,已關閉的檔案控制代碼會從中減去。要列出server中當前開啟的所有檔案資訊,可以使用where WHERE OPEN_COUNT> 0子句進行檢視。

file_instances表不允許使用TRUNCATE TABLE語句。

(3)mutex_instances表

mutex_instances表列出了server執行mutex instruments時performance_schema所見的所有互斥量。互斥是在程式碼中使用的一種同步機制,以強制在給定時間內只有一個執行緒可以訪問某些公共資源。可以認為mutex保護著這些公共資源不被隨意搶佔。

當在server中同時執行的兩個執行緒(例如,同時執行查詢的兩個使用者會話)需要訪問相同的資源(例如:檔案、緩衝區或某些資料)時,這兩個執行緒相互競爭,因此第一個成功獲取到互斥體的查詢將會阻塞其他會話的查詢,直到成功獲取到互斥體的會話執行完成並釋放掉這個互斥體,其他會話的查詢才能夠被執行。

需要持有互斥體的工作負載可以被認為是處於一個關鍵位置的工作,多個查詢可能需要以序列化的方式(一次一個序列)執行這個關鍵部分,但這可能是一個潛在的效能瓶頸。

我們先來看看錶中記錄的統計資訊是什麼樣子的。

[email protected] : performance_schema 03:23:47> select * from mutex_instances limit 1;
+--------------------------------------+-----------------------+---------------------+
| NAME                                 | OBJECT_INSTANCE_BEGIN | LOCKED_BY_THREAD_ID |
+--------------------------------------+-----------------------+---------------------+
| wait/synch/mutex/mysys/THR_LOCK_heap |              32576832 |                NULL |
+--------------------------------------+-----------------------+---------------------+
1 row in set (0.00 sec)

mutex_instances表字段含義如下:

· NAME:與互斥體關聯的instruments名稱;

· OBJECT_INSTANCE_BEGIN:mute