23 MySQL Performance Schema.. 1
23.1 性能框架快速啟動... 3
23.2 性能框架配置... 5
23.2.1 性能框架編譯時配置... 5
23.2.2 性能框架啟動配置... 6
23.2.3 啟動時性能框架配置... 8
23.2.3.1 性能架構事件定時... 8
23.2.3.2 性能框架事件過濾... 9
23.2.3.3 事件預過濾... 10
23.2.3.4命名記錄點或者消費者的過濾... 12
23.2.3.5 識別哪些已經被記錄... 12
23.3 性能框架查詢... 13
23.4 性能框架記錄點命名約定... 13
23.5 性能框架和狀態監控... 15
23.6 性能框架和分子原子性事件... 17
23.7 性能框架statement digests17
23.8 性能框架常用表特性... 19
23.9 性能框架表描述... 19
23.9.1 性能框架表索引... 19
23.9.2 性能框架setup表... 19
23.9.2.1 setup_actors表... 19
23.9.2.2 setup_consumers表... 20
23.9.2.3 setup_instruments表... 20
23.9.2.4 setup_objects表... 21
23.9.2.5 setup_timers表... 22
23.9.3 性能框架實例表... 22
23.9.3.1 cond_instances表... 22
23.9.3.2 file_instances表... 22
23.9.3.3 mutex_instances表... 22
23.9.3.4 Rwlock_instances表... 23
23.9.3.5 socket_instance表... 23
23.9.4 性能框架事件等待表... 25
23.9.4.1 events_waits_current表... 26
23.9.4.2 Events_waits_history表... 28
23.9.4.3 events_waits_history_long 表... 28
23.9.5 性能框架Stage事件表... 28
23.9.5.1 events_stages_current表... 30
23.9.5.2 events_stage_history表... 30
23.9.5.3 events_stage_history_long表... 31
23.9.6 性能框架語句事件表... 31
23.9.7 性能框架事務表... 32
23.9.8 性能框架連接表... 35
23.9.9 性能框架連接屬性表... 35
23.9.10 性能框架用戶變量表... 35
23.9.11 性能框架復制表... 36
23.9.11.1 replication_connection_configure表... 38
23.9.11.2 replication_connection_status38
23.9.11.3 replication_applier_configure. 39
23.9.11.4 replication_applier_status39
23.9.11.5 replication_applier_status_by_coordinator39
23.9.11.6 replication_applier_statys_by_worker40
23.9.11.7 replication_group_members40
23.9.11.8 replication_group_member_status40
23.9.12 性能框架鎖相關表... 41
23.9.12.1 metadata_locks41
23.9.12.2 table_handles42
23.9.13 性能框架系統變量表... 42
23.9.14 性能框架系統狀態變量表... 43
23.9.15 性能框架統計表... 43
23.9.16 性能框架其他表... 44
23.10 性能框架選項和變量... 45
23.11 性能框架命令選項... 45
23.12 性能框架系統變量... 45
23.13 性能框架狀態變量... 45
23.14 性能框架內存分配模型... 45
23.15 性能框架和... 46
23.16 使用性能框架診斷... 47
23.17 遷移到性能框架系統和狀態變量表... 47
MySQL Performance Schema用來監控MySQL Server的運行運行在底層。性能框架有這些特性:
· 性能框架提供了一種方法檢查內部的服務運行。通過PERFORMANCE_SCHEMA存儲引擎和performance_schema實現。性能框架主要關注於數據性能。和INFORMANCE_SCHEMA不同,INFORMACE_SCHEMA主要檢查元數據。
· 性能框架監控服務事件,事件是服務需要花時間的任何東西,並且已經被記錄這樣時間信息可以被收集。通常一個事件可以是一個函數調用,一個操作系統等待,SQL語句執行的階段比如解析或者排序,或者整個語句或者一組語句。時間收集提供。時間收集提供了同步調用文件和表IO,表鎖等信息。
· 性能框架事件的事件和binlog的事件,事件調度的事件不同。
· 性能框架事件被指定到某個MySQL服務。性能框架表別人我是本地服務,他們的修改不會被寫入到binary log,也不會被復制。
· 當前事件,歷史事件和事件總結是可用的,那麼就可以確定記錄被啟動了多少次,用了多少時間。事件信息可以查看指定線程的活動或者指定對象的活動,比如文件和信號量。
· PERFORMANCE_SCHEMA存儲引擎使用代碼中的記錄點來收集信息。
· 收集的信息被保存在performance_schema數據庫中。可以用select查詢。
· 性能框架配置可以動態的被修改,通過修改performance_schema數據庫配置數據收集。
· Performance_schema上的表是視圖或者臨時表,不會保存到磁盤中。
· MySQL支持所有平台的監控。
· 通過在源代碼中加入記錄點實現數據收集。沒有特定線程使用相關的性能框架。
對於性能框架要啟用,必須要在MySQL編譯的時候配置好。可以通過mysqld的幫助驗證。如果性能框架可用輸出就會帶—performance_schema參數。
如果這些參數沒有出現,那麼代碼在編譯時就不支持性能框架。
假設性能框架可用,默認是可用的。可以通過配置文件配置:
[mysqld]
performance_schema=ON
當服務啟動,發現performance_schema就會試圖初始化性能框架,可以查看performance_schema變量檢查初始化是否成功。
mysql> SHOW VARIABLES LIKE 'performance_schema';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| performance_schema | ON |
+--------------------+-------+
這個值表示,性能框架已經可用,如果為off表示發生錯誤,檢查錯誤日志。
性能框架實現和存儲引擎類似。如果引擎可用可以在show engine查看是否支持PERFORMANCE_SCHEMA存儲引擎。
Performance_schema中的數據庫可以被劃分為幾塊,當前時間,歷史事件,總結,對象實例和安裝信息。
原本,其實並不是所有的記錄點和收集器都是可用。所以性能框架不會收集所有的數據。可以通過以下語句打開所有的積累點和收集器:
mysql> UPDATE setup_instruments SET ENABLED = 'YES', TIMED = 'YES';
Query OK, 560 rows affected (0.04 sec)
mysql> UPDATE setup_consumers SET ENABLED = 'YES';
Query OK, 10 rows affected (0.00 sec)
當前事件表,可以通過events_waits_current查看當前服務在做什麼。每個線程都有一行。
歷史表,表結構和當前事件一樣,event_waits_history和event_waits_history_long表包含了每個線程最近10個event和每個線程最近10000個events。
一個新的事件被加入,老的事件就會刪除。
總結表提供了所有事件的聚合的信息。這個表通過分組一不同方式計算事件數據。為了查看那個記錄點呗執行的次數最多或者等待事件最長,通過對表上的count_star或者sum_timer_wait列進行排序:
mysql> SELECT EVENT_NAME, COUNT_STAR
-> FROM 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 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信號量是熱點,2個語句分別表示執行的熱度和等待事件長度。
實例表,記錄了對象類型被記錄了。當服務使用了一個記錄對象,那麼會產生一個事件。這些表提供了事件名,解釋性的注釋或者狀態。比如file_instances表,記錄了文件io操作和他們對應的文件。
mysql> SELECT * FROM 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表用來配置和監控特點的,比如setup_timers表:
mysql> SELECT * FROM setup_timers;
+-------------+-------------+
| NAME | TIMER_NAME |
+-------------+-------------+
| idle | MICROSECOND |
| wait | CYCLE |
| stage | NANOSECOND |
| statement | NANOSECOND |
| transaction | NANOSECOND |
+-------------+-------------+
Setup_instruments列了哪些可以被記錄的事件。然後通過修改這個表開控制是否啟動這個記錄。
mysql> UPDATE setup_instruments SET ENABLED = 'NO'
-> WHERE NAME = 'wait/synch/mutex/sql/LOCK_mysql_create_db';
性能框架使用,收集來的事件來更新到performance_schema數據庫,數據庫作為事件信息的消費者。Setup_consumers表列出了可用的消費者。
控制是否性能框架維護一個消費者作為事件信息的目標。可以設置為enabled值。
為了讓性能框架啟用必須在編譯時被配置,由官方提供的MySQL是支持性能框架的,如果是其他發布方發布的,那麼要先檢查是否支持。
如果是從源代碼發布的,那麼在發布的時候要先設置:
shell> cmake . -DWITH_PERFSCHEMA_STORAGE_ENGINE=1
在MySQL 5.7.3之後,也可以支持啟動性能框架,但是不包含所有的記錄點,比如:
shell> cmake . -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DDISABLE_PSI_STAGE=1 \
-DDISABLE_PSI_STATEMENT=1
如果你安裝MySQL到一個老的安裝上,並且沒有配置過性能框架,當確保performance_schema數據庫包含了所有的當前表後,可以使用mysql_upgrade啟動服務。然後重啟,有個跡象要特別留意:
[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是否支持性能框架:
shell> mysqld --verbose --help
...
--performance_schema
Enable the performance schema.
--performance_schema_events_waits_history_long_size=#
Number of rows in events_waits_history_long.
...
也可以通過連接到服務之後使用show engine查看是否存在PERFORMANCE_SCHEMA存儲引擎。如果在build的時候沒有被配置那麼show engines不會顯示PERFORMANCE_SCHEMA存儲引擎。
假設性能框架是可用的,那麼默認是啟動的也可以在配置文件中配置:
[mysqld]
performance_schema=ON
如果服務不能在初始化性能框架的時候分配內部緩存,那麼性能框架自己關閉並且設置performance_schema為off,服務在沒有記錄點狀況下運行。
性能框架可以以命令行參數方式配置。
--performance-schema-instrument='instrument_name=value'
關閉所有記錄點:
--performance-schema-instrument='%=OFF'
比較長的記錄點名會比短的積累點名要優先於短的模式名,不管順序。
具體可以看後面章節:23.2.3.4命名記錄點或者消費者的過濾
一個無法別識別的記錄點名會被忽略。為了控制消費者,可以使用以下選項:
--performance-schema-consumer-consumer_name=value
consumer_name
是一個消費者名比如events_waits_history,value是以下一個值:
l OFF,False或者0:不收集這個消費者的事件
l ON,True或者1:收集消費者的事件
比如消費者名是events_waits_history:
--performance-schema-consumer-events-waits-history=ON
被允許的消費者名可以在setup_consumers表上找到。在表中消費者名字都是下劃線,在選項配置的時候,下劃線和減號沒有區別。
性能框架提供了很多系統變量可以用來配置:
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表示了性能框架是否啟動,別的參數表示表的大小伙子內存分配的值。
可以使用配置文件開設置這些變量:
[mysqld]
performance_schema
performance_schema_events_waits_history_size=20
performance_schema_events_waits_history_long_size=15000
如果沒有指定值,那麼默認這些變量會有一個默認值。在MySQL 5.7.6,性能框架分配內存會根據服務符合增加伙子減少,而不是在服務啟動的時候一次性分配完成。所以很多參數並不需要在啟動的時候都分配好,更多內容可以看23.12 性能框架系統變量。
每個自動分配的參數不是在啟動時設置或者設置為-1,性能框架決定如何根據以下的參數來設置這些值:
max_connections
open_files_limit
table_definition_cache
table_open_cache
如果要覆蓋自動設置的值或者自動范圍的值,就在啟動的時候設置一個給定的值而不是給-1這樣性能框架就會設置一個給定的值。
在運行時,show variables會顯示自動設置的值,自動范圍設置的會給-1.如果性能框架被禁用,自動設置和自動范圍參數都會被設置為-1,並且顯示為-1.
事件被收集也就是說記錄點被加到了服務源代碼中。記錄點時間事件,是性能框架如何提供一個事件持續多久的方案。也可以配置記錄點收集定時信息。
性能框架定時器
2個性能框架表提供了定時器信息:
l Performance_timers,保存了可用的timers和它們的特點。
l Setup_timers,表明了哪些記錄點使用了哪個timers。
每個setup_timers使用的計時器躲在performance_timers表中。
mysql> SELECT * FROM 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 |
+-------------+-----------------+------------------+----------------+
TIMER_NAME:表示可用timer的名字,CYCLE表示給予cpu計數器
TIMER_FREQUENCY:表示每秒的timer個數。對於cycle timer,頻率和cpu事件相關,其他timer是秒的若干分。
TIMER_RESOLUTION:表示每次增加的單位
TIMER_OVERHEAD:指定周期獲取一個定時需要的最小cycles個數。每個事件都會在開始和結束的時候調用timer,因此是顯示的負荷的2倍。
修改setup_timer表的timer_name:
mysql> UPDATE setup_timers SET TIMER_NAME = 'MICROSECOND'
-> WHERE NAME = 'idle';
mysql> SELECT * FROM setup_timers;
+-------------+-------------+
| NAME | TIMER_NAME |
+-------------+-------------+
| idle | MICROSECOND |
| wait | CYCLE |
| stage | NANOSECOND |
| statement | NANOSECOND |
| transaction | NANOSECOND |
+-------------+-------------+
默認性能框架會為每個記錄點類型設置timer,也可以修改。
對於記錄等待事件的時間,最重要的是在時間精度上減少負荷,所以使用cycle timer最合適。
對於語句或者stage的執行比執行一個簡單的等待要大的多,並且需要一個精確的量,並且和處理器無關,所以最好不要使用cycle。默認使用NANOSECOND。盡管負荷比cycle要大,但是不重要,因為調用2次計數器的數量級遠遠比執行語句本身的cpu時間要小。
Cycle提供的精度和cpu有關,如果處理器是1Gh或者更高,cycle可以提供比納秒還小的進度。使用cycle計數器比獲取一個一天的實際事件開銷小。
Cycle的缺點:
l 從cycles轉化為時間單位是比較費事的。為了更快,這個轉化操作知識很粗糙的乘法計算。
l 處理器cycle,可能會遍,比如筆記本進入省電模式,那麼cpu cycle會下降如果cpu cycle有波動,那麼轉化就會出錯。
l Cycle 計數器可能是不靠譜的或者不可用的,和處理器或者操作系統有關。
l 一些處理器,亂序執行或者多處理器同步,可能會導致計數器忽高忽低。
性能框架計數器在事件中的表現
存儲在性能框架表的當前事件,有3個列表示事件,TIMER_START,TIMER_END表示事件啟動和結束,TIMER_WAIT表示事件的時間。
Set_instruments表有ENABLED字段來表示,事件是否要收集。TIMED字段表示記錄點是否被時間標記。如果記錄點沒有啟動,那麼就不會生成事件。如果不是timed,那麼生成的事件,中TIMER_START,TIME_END,TIMER_WAIT是null。那麼在統計表計算最大時間,最小時間的時候會被忽略。
內部,事件啟動的時候,timer以給定的單位保存在事件裡面,當要顯示的時候,timers被顯示為標准的事件單位,不管選了什麼timer都會顯示為,皮秒。
Setup_timers的修改會馬上生效。已經在處理的會使用老的timer。為了不導致無法預期的結果出現,最好先把統計表使用truncate table進行重置。
Timer的基線,在服務啟動的時候被初始化。TIMER_START,TIMER_END表示從基線以來的皮秒數。TIMER_WAIT表示占用的皮秒。
事件是以生產者消費者模式處理的:
l 記錄點代碼是事件的源,產生事件被用來收集,setup_instruments表列出了可以被收集的記錄點。Setup_instruments表提供了很多event的產生。
l 性能框架表示事件的目的地。Setup_consumers,列出了所有消費者類型。
l 預過濾,通過修改性能框架配置完成,可以通過啟用或者禁用記錄點和消費者完成。使用預過濾的目的:
n 減少負荷。性能框架運行需要消耗資源,雖然很少。
n 不關心的事件可以不寫入消費者中。
n 避免維護多個類型的事件表。
· 事後過濾,可以使用where語句在查詢性能框架的時候過濾。
預過濾有性能框架完成並且會全局的影響所有用戶。預過濾可以在生產者或者消費者的處理階段上:
· 幾個表可以用來配置生產者的預過濾:
§ Setup_instruments說明哪個記錄點是可用的,如果這個表上一個記錄點被禁用,不管其他表怎麼配置,都不會再產生事件。
§ Setup_objects控制了性能框架特定表和存儲過程對象。
§ Threads表示是不是每個服務線程都有監控
§ Setup_actors新的後台進程的初始監控狀態
· 要配置預過濾在消費者階段,那麼要修改setup_comsumers表。setup_comsumers也會影響事件的產生。如果指定的事件不會發送給任何地方,那麼性能框架不會產生
修改任意表都會馬上影響監控,但是有些例外:
· 修改某些setup_instruments表只有的服務啟動的時候生效。在運行時修改不會生效。
· 修改setup_actors表,只會影響後台線程。
當修改監控配置,性能框架不會刷新歷史表。歷史表和當前表的事件不會被替換,除非又新的事件。如果禁用一個記錄點的時候,需要等待一段時間,來替換老的事件。也可以用truncate table清空。
在修改完記錄點之後,可能下那個藥傷處summary表清理統計信息對於events_statements_summary_by_digest或者內存統計表。Truncate table只會重置值為0,並不會刪除行。
控制記錄點的過濾,是過濾setup_instruments表設置enables字段。修改setup_instruments大多數會馬上生效。對於某些記錄點,修改只會在服務器啟動才會生效。setup_instruments提供了最基本的記錄點控制。
Setup_objects表控制了性能框架部分表和存儲過程。修改Setup_objects會馬上相應。
mysql> SELECT * FROM setup_objects;
+-------------+--------------------+-------------+---------+-------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | ENABLED | TIMED |
+-------------+--------------------+-------------+---------+-------+
OBJECT_TYPE:表示對象類型,比如表或者事件,存儲過程等。
OBJECT_SCHEMA和OBJECT_NAME包含了schema或者對象名的字符串,也可以是通配符
ENABLED列表示對象是否被監控,TIMED列表示是否收集timing信息。
默認會收集除了mysql,information_schema,performance_schema外所有的的數據庫對象。
threads表為每個線程保存了一行數據。每行數據都包含了線程的信息並且表明是否被監控。對於性能框架監控一個線程必須滿足一下他條件:
· 表sestup_consumers表中的thread_instrumentation必須為yes
· Threads.instrumented列必須為yes
· 只監控setup_instruments表中的記錄點
threads表也說明了每個服務線程是否執行歷史事件記錄。如果要記錄歷史事件以下條件都必須為真:
· 對應的消費者配置,setup_consumers表必須為yes。
· Threads.HISTORY列必須為yes。
· 只監控setup_instruments表中的記錄點
對於後台線程,instrumented和history的初始數據,取決於setup_action中的配置。
mysql> SELECT * FROM setup_actors;
+------+------+------+---------+---------+
| HOST | USER | ROLE | ENABLED | HISTORY |
+------+------+------+---------+---------+
| % | % | % | YES | YES |
+------+------+------+---------+---------+
thread表的instrumented和history的規則如下:
· 如果最佳匹配,enabled=yes,那麼instrumented=yes,最佳匹配history=yes,那麼threads表的history=yes
· 如果最佳匹配,enabled=no,那麼instrumented=no,最佳匹配history=no,那麼threads表的history=no
· 如果無法匹配,那麼instrumented,history都為no
在mysql 5.7.6 之前,沒有enabled字段,只要有匹配,那麼instrumented=yes
在mysql5.7.8,之前,沒有history字段,線程要不全部可以進入history要不都不能,取決於setup_consumer的配置。
默認,後台的所有線程都是會被記錄的,因為setup_actors有一行都是‘%’。
Setup_cunsumers表包含了所有的消費者。修改這個表來過濾那些event會被發送。
Setup_consumers表中設置消費者,從高級到低級。主要的原則如下:
· 除非性能框架檢查消費者,並且消費者是可用的,不然不會受到消息。
· 只有當消費者依賴的所有的消費者都可用了,才會被檢查
· 被依賴的消費者,有自己的依賴消費者。
· 如果一個事件沒有目的,那麼性能框架不會被產生。
全局和線程消費者
· Global_instrumentation是高級消費者,如果global_instrumentation為no,那麼所有的的全局記錄點都被禁用。所有其他低級的都不會被檢查。當global_instrumentation啟動了,才會去檢查thread_instrumentation
· Thread_instrumentation,如果是no,那麼這個級別下面的級別都不會被檢查,如果是yes,性能框架就會維護線程指定信息,並且檢查events_xxx_current消費者。
Wait Event消費者
這些消費者,需要global_instrumentation,thread_instrumention為yes。如果被檢查行為如下:
· Events_waits_current,如果為no,禁用對各個wait event收集。如果為yes檢查history消費者和history_long消費者。
· Events_waits_history,如果上級為no不檢查,為yes,收集各個等待事件。
· Events_waits_history_long,和上面類似
Stage event,statement event和上面類似。
可以對指定記錄名或者消費者進行過濾:
mysql> UPDATE setup_instruments
-> SET ENABLED = 'NO'
-> WHERE NAME = 'wait/synch/mutex/myisammrg/MYRG_INFO::mutex';
mysql> UPDATE setup_consumers
-> SET ENABLED = 'NO' WHERE NAME = 'events_waits_current';
指定一組記錄點或者消費者:
mysql> UPDATE setup_instruments
-> SET ENABLED = 'NO'
-> WHERE NAME LIKE 'wait/synch/mutex/%';
mysql> UPDATE setup_consumers
-> SET ENABLED = 'NO' WHERE NAME LIKE '%history%';
通過檢查setup_instruments表,你可以得知包含了哪些記錄點被記錄:
mysql> SELECT * FROM setup_instruments WHERE NAME LIKE 'wait/io/file/innodb/%';
+--------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+--------------------------------------+---------+-------+
| 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 |
+--------------------------------------+---------+-------+
預過濾限制了哪些事件信息被收集,很多用戶都不同。可以通過select過濾event。
mysql> SELECT THREAD_ID, NUMBER_OF_BYTES
-> FROM 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 |
+-----------+-----------------+
記錄點命名是一串組件然後用‘/’分割:
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
記錄點命名類似於樹形結構。從左到右越來越詳細,組件的名稱以來與計數器類型。
名字由2部分組成:
· 組件名,比如mysiam
· 變量名,一種是全局變量,還有一種是class::value。值class類中的變量。
頂級記錄點組件
· Idle:表示idle事件的記錄點。
· Memory:memory事件記錄點
· Stage:階段事件記錄點
· Statement:語句事件記錄點
· Transaction:事務事件記錄點
· Wait:等待事件記錄點
Idle記錄點組件
Idle記錄點用於idle事件,具體看:23.9.3.5 socket_instance表
內存記錄點組件
很多內存記錄點默認是不可用的,可以手動啟動,修改setup_instruments表。記錄點前綴,memory/performance_schema/表示有多少性能框架內部的內存分配。memory/performance_schema/總是啟用的,並且不能被禁用。這件記錄點被收集在 memory_summary_global_by_event_name
表。
Stage記錄點組件
Stage表示語句階段性處理的比如sorting result或者sending data。
語句記錄點組件
· Statement/abstract/*: 抽象語句操作記錄點。抽象記錄點在語句早期使用。
· Statement/com :是記錄點命令操作。並且有名字對應到com_xxx操作,比如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,用於創建數據庫和select語句。
等待記錄點指令
· Wait/io,io操作記錄點
§ Wait/io/file:文件io操作記錄點,對於文件,等待是等待文件操作文件完成。因為緩存的關系,物理文件io可能在這個操作上不會執行
§ Wait/io/socket:socket操作記錄點,socket記錄點有以下命名格式:wait/io/socket/sql/socket_type。服務有一個監聽socket用來支持每個網絡協議。這個記錄點支持監聽socket是tcpip或者unix socket文件。socket_type的值為server_tcpip_socket或者server_unix_socket。當監聽socket發現一個連接,服務把這個連接轉換到獨立的線程。那麼新的連接線程的socket_type為client_connection。
§ Wait/io/table: 表io操作記錄點。包含持久性表或者臨時表的行級別訪問。對行的影響就是fetch,insert,update,delete。對於視圖,是被視圖引用的基表。和其他等待不同,表的io等待報貨其他等待。比如表io可能包含,文件io或者內存操作。因此events_waits_current中對於行的等待可能有2行。
· Wait/lock ,鎖操作的記錄點
§ Wait/lock/table,表鎖記錄點操作
§ Wait/lock/metadata/sql/mdl,元數據所操作
· Wait/synch,同步對象記錄點
§ Wait/synch/cond,條件被用來一個線程通知另外一個線程,某些它們等待的東西已經完成。如果一個線程等待一個條件,那麼會醒來並且處理。如果多個線程等待那麼會都新來並且完成它們等待的資源。
§ Wait/synch/mutex,多排他對象用來訪問一個資源,防止其他線程訪問資源。
§ Wait/synch/rwlock,一個讀寫鎖對象用來鎖定特定的變量,防止其他線程使用。一個共享讀所可以多個線程同時獲取。一個排他寫鎖只能由一個線程獲取。
§ Wait/synch/sxlock,共享排他鎖是讀寫鎖的rwlock的一種,提供當一個線程寫時,其他線程可以非一致性讀。Sxlock在mysql 5.7中使用為了優化rwlock的或展現。
可以使用show status like ‘%perf%’查看性能框架的狀態。
性能框架狀態變量提供了關於記錄點因為內存的原因沒有被創建或者加載的信息。根據狀態命名有幾類:
· Performance_Schema_xxx_class_lost,表示有多少xxx類型的記錄點不能被加載。
· Performance_schema_xxx_instance_lost,表示有多少xxx類型的記錄點不能被創建。
· Performance_schema_xxx_handlees_lost,表示有多少xxx類型的記錄點不能被打開。
· Performance_schema_locker_lost,表示有多少時間都是或者沒有被記錄。
比如,一個信號量是記錄點,但是服務不能為記錄點分配內存。那麼會增加performnace_schema_mutex_classes_lost。但是信號量還是以用於對象同步。但是性能數據就無法被收集,如果記錄點被分配,用來初始化記錄點信號量實體。對於單獨的信號量比如全局信號量,只有一個實例。有些信號量的實例個數會變化,比如每個連接的信號量。如果服務不能創建一個指定記錄點信號量實體,就會增加,performance_schema_mutex_instance_lost。
假設有以下條件:
· 服務啟動參數,--performance_schema_max_mutex_classes=200,因此有200個信號量空間。
· 150信號量已經被加載
· 插件plugin_a有40個信號量
· 插件plugin_b有20個信號量
服務為插件,分配信號量記錄點依賴於已經分配了多少,比如以下語句:
INSTALL PLUGIN plugin_a
那麼服務已經有了150+40個信號量。
UNINSTALL PLUGIN plugin_a;
雖然插件已經卸載,但是還是有190個信號量。所有插件代碼生成的歷史數據還是有效。但是新的記錄點事件不會被分配。
INSTALL PLUGIN plugin_a;
服務發現40個記錄點已經被分配,因此新的記錄點不會被創建,並且之前分配的內部buffer會被重新使用,信號量還是190個。
INSTALL PLUGIN plugin_b;
這個使用可用信號量已經只有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_instance_lost,不會改變。
上面描述的適用於所有記錄點,不單單是信號量。
當Performance_Schema_mutex_classes_lost大於0那麼有2種情況:
· 為了保存一些內存,你可以啟動,Performance_Schema_mutex_classes=N,N小於默認值。默認值是滿足加載所有插件的mysql發布。但是一些插件如果不加載可能會少一點。比如你可以不加載默寫存儲引擎。
·
你加載一個第三方插件,是性能框架的記錄點,但是在服務啟動的時候,不允許插件記錄點內存獲取。因為來自第三方,這個引擎的記錄點內存並不會被記錄在performance_schema_max_mutex_classes.
如果服務不能滿足插件記錄點的資源,沒有顯示的分配更多的 performance_schema_max_mutex_classes,那麼久會出現記錄點的饑餓。
如果performance_schema_max_mutex_classes.太小,沒有錯誤會被寫入到錯誤日志,並且在運行時沒有錯誤。然而performance_schema上的表會丟失事件。performance_schema_max_mutex_classes_lost狀態變量只是標記一些事件因為創建記錄點失敗被刪除。
如果記錄點沒有丟失,那麼就會通知性能框架,當在代碼中(THD::LOCK_delete)創建了信號量,單個記錄點就會被使用。那麼就需要很多信號量實體。這個時候,每個線程都有lock_delete,比如有1000個線程,1000個lock_delete信號量記錄點實例。
如果服務沒有空間存放所有1000個信號量記錄點實體,一些信號量會被創建記錄點,一些就不會被創建。如果服務職能創建800個,那麼另外200個會丟失,Performance_schema_mutex_instances_lost會增加200個。
Performance_schema_mutex_instances_lost,可能在要初始化的信號量記錄點大於配置的Performance_schema_mutex_instances=N那麼久會發生。
如果SHOW STATUS LIKE 'perf%'沒有丟失任何東西,那麼新能框架數據是可以被依賴的。如果有一些都是了,那麼數據是不完整的,並且性能框架不會記錄所有。這樣Performance_schema_xxx_lost就說明了問題范圍。
有些時候饑餓時可以均衡的,比如你可能不需要文件io的數據,那麼可以把所有性能框架參數,和文件io相關的都設置為0,那麼久不會把內存分配到和文件相關的類,對象實例或者句柄中。
對於一個表的io事件,通常有2行在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
行獲取會導致文件讀取。比如,表io獲取事件在文件io事件之前,但是還沒有完成。那麼文件io嵌入在表io事件。
和其他原子性等待事件不同,表io事件是分子,包含其他事件。Events_waits_current中,表io事件通常有2行:
· 一行是當前表io等待事件
· 一行是其他任何類型的等待事件。
通常,其他類型的等待事件不是表io事件。當副事件完成,會從events_waits_current中消失。
MySQL服務有能力維護statement digest信息。Digest進程把一個sql語句轉化為標准的格式並且計算一個hash結果。標准化允許相似的語句分組並且總結暴露一些語句的類型和發生的頻率。
在性能框架,語句digest涉及這些組件:
· Setup_comsumers的statement_digset控制了,性能框架如何維護digest信息。
· 語句事件表有列包含digest和相關的值的列:
§ DIGEST_TEXT,標准化的語句。
§ DIGEST,是digest MD5 hash值。
Digest計算,最大的可用空間1024B。MySQL 5.7.8後這個值可以通過參數,performance_schema_max_digest_length修改。之前使用max_digest_length。
· 語句事件表也有sql_text列包含了原始的sql語句。語句顯示的最大為1024B,可以通過performance_schema_max_sql_text_length字段修改。
· events_statements_summary_by_digest,提供綜合的語句digset信息。
標准化一個語句轉化,會保留語句結構,刪除不必要的信息:
· 對象標識符,比如表或者數據庫名會被保留。
· 文本值會被替換成變量。
· 注釋會被刪除,空格會被調整。
比如如下2個語句:
SELECT * FROM orders WHERE customer_id=10 AND quantity>20
SELECT * FROM orders WHERE customer_id = 20 AND quantity > 100
替換後會變成:
SELECT * FROM orders WHERE customer_id = ? AND quantity > ?
對於每個標准化的語句提供一個DIGEST_TEXT和DIGEST一個hash值。語句Digest總結表,提供了語句的profile信息,顯示語句運行頻率運行次數等。
events_statements_summary_by_digest大小固定的,所以如果滿了,如果在表上沒有匹配的,那麼所有的語句都會被計算在schema_name和digest為null的記錄裡面,當然可以增加digest大小,performance_schema_digests_size,如果沒有指定,那麼性能框架會自己評估一個值。
performance_schema_max_digest_length系統變量決定digest buffer最大可用字節。但是現實的語句digest的長度往往比buffer長,那是因為關鍵字和文本值的關系。也就是說digest_text的長度可能超過performance_schema_max_digest_length。
對於應用程序生成了很長的語句,只有結尾不同,增加performance_schema_max_digest_length可以讓digest得以計算,識別語句。反過來減少performance_schema_max_digest_length會導致服務犧牲很少的內存來保存語句的digest,但是增加了語句的相似度,被當成同一個digest。如果長度要求長,那麼保存的也要更多。
可以通過show engine performance_schema status語句,或者監控以下語句查看sql語句保存使用的內存量。
mysql> SELECT NAME FROM setup_instruments
-> WHERE NAME LIKE '%.sqltext';
+------------------------------------------------------------------+
| NAME |
+------------------------------------------------------------------+
| memory/performance_schema/events_statements_history.sqltext |
| memory/performance_schema/events_statements_current.sqltext |
| memory/performance_schema/events_statements_history_long.sqltext |
+------------------------------------------------------------------+
mysql> SELECT NAME FROM setup_instruments
-> WHERE NAME LIKE 'memory/performance_schema/%.tokens';
+----------------------------------------------------------------------+
| NAME |
+----------------------------------------------------------------------+
| memory/performance_schema/events_statements_history.tokens |
| memory/performance_schema/events_statements_current.tokens |
| memory/performance_schema/events_statements_summary_by_digest.tokens |
| memory/performance_schema/events_statements_history_long.tokens |
+----------------------------------------------------------------------+
Performance_schema數據庫是小寫的,數據庫裡面的表名也是小寫的。查詢要使用小寫。
很多表在performance_schema數據庫是只讀的不能被修改。一些setup表的某些列可以被修改。一些也可以被插入和刪除。事務可以被允許清理收集的事件,所以truncate table可以用來清理信息。
Truncate table可以在總結表上使用,但是不能再events_statements_summary_by_digest和內存總結表上使用,效果只是把總計列清理為0.
具體看:http://dev.mysql.com/doc/refman/5.7/en/performance-schema-table-index.html
Setup表提供關於當前收集點啟用信息。使用表而不是全局變量提供了更高級別的性能框架配置。比如你可以使用一個sql語句配置多個記錄點。
這些setup表示可用的:
· Setup_actors:如何初始化後台線程
· Setup_consumers:決定哪些信息會被發送和存儲。
· Setup_instruments:記錄點對象,哪些事件要被收集。
· Setup_objects:哪些對象要被監控
· Setup_timers:當前事件定時器。
setup_actors表包含了信息決定是否監控或者對新的後台線程進行歷史數據記錄。這個表默認最多100行,可以通過修改參數performance_schema_setup_actors_size修改大小。
對於新的後台線程,在setup_actors中,性能框架滿足的用戶和host。如果一個行負荷enabled,histroy列,對應到threads表上的instrumented和history列。如果找不到匹配那麼instrumented和history列就為no。
對於後台線程, Instrumented和history默認都是yes,setup_actors默認沒有限制。
Setup_actors初始化內容,不過濾任何數據:
mysql> SELECT * FROM setup_actors;
+------+------+------+---------+---------+
| HOST | USER | ROLE | ENABLED | HISTORY |
+------+------+------+---------+---------+
| % | % | % | YES | YES |
+------+------+------+---------+---------+
修改setup_actors表只會影響後台線程,不會影響已經存在的線程。為了影響已經存在的threads表,修改instrumented和history列。
Setup_consumers表列了各個類型的消費者:
mysql> SELECT * FROM setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| events_transactions_current | NO |
| events_transactions_history | NO |
| 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設置形成從高到低的級別。形成依賴,如果高級別的設置了低級別才會有機會被檢查。
Setup_consumers表列了所有記錄點對象:
mysql> SELECT * FROM setup_instruments;
每個記錄點被增加到源代碼中,都會在這個表上有一行,即使記錄點代碼沒有被指定。當一個記錄點啟動了或者執行了,記錄點實例就會被創建會顯示在*_instrances表。
修改setup_instruments行會馬上影響監控。對於一些記錄點,修改只會在下次啟動才會生效。在指定時修改並不會生效。
Setup_objects表控制了哪些對象的性能框架會被監控。這個對象默認為100行可以通過修改變量來控制,performance_schema_setup_objects_size。
初始化的setup_objects如下:
mysql> SELECT * FROM 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表會馬上影響監控。
對於setup_objects,object_type表示監控了哪些對象類型。如果沒有匹配的object_schema,object_name。那麼就不會有對象沒監控。
Setup_times表如下:
mysql> SELECT * FROM setup_timers;
+-------------+-------------+
| NAME | TIMER_NAME |
+-------------+-------------+
| idle | MICROSECOND |
| wait | CYCLE |
| stage | NANOSECOND |
| statement | NANOSECOND |
| transaction | NANOSECOND |
+-------------+-------------+
Timer_name是,performance_timers中的一行。表示某個事件類型使用了什麼計時器
Cond_instance表列出了所有性能框架可以查看的條件。條件是同步機制,用來通知一個指定的事件已經產生完畢。所以一個線程等待這個條件的會馬上恢復工作。
當一個線程等待的東西已經變化,條件名值說明線程在等待條件名。
當指定文件io記錄點的時候,File_instances表列出了所有性能框架能看到的所有文件。如果文件在disk但是沒有被打開不會出現在file_instrances中。當文件在次磁盤中被刪除,那麼file_instances中也會刪除。
Mutex_instances顯示了所有可以被性能框架查看到的信號量。信號量是同步機制用來保護資源。當2個線程運行需要放問相同的資源,2個線程會互相爭用,一個線程獲取了mutex上的鎖,那麼另外一個只能等待上一個完成。
當任務執行獲取信號量,稱為臨界區域,區域內執行都是順序的,可能有潛在瓶頸問題。
表中有3個字段:
Name:記錄點的名字
OBJECT_INSTANCE_BEGIN:被記錄的信號量在內存中的地址。
LOCKED_BY_THREAD_ID:擁有mutex的線程id,否則為null。
對於每個記錄的信號量,性能框架提供一下信息:
· Setup_instruments表列出了記錄點名,以wait/synch/mutex/為前綴。
· 當有代碼創建了信號量,那麼就有一行被加入到mutex_instrances表中,OBJECT_INSTANCE_BEGIN列是mutex的唯一列。
· 當一個線程視圖鎖定信號量,events_waits_current表為線程顯示一行,說明在等待信號量,通過object_instance_begin。
· 當線程成功鎖定了一個信號量:
§ Events_waits_current,顯示等待信號量就會完成
§ 完成的事件會被添加到歷史表中
§ Mutex_instances顯示信號量現在屬於一個thread
· 當thread unlock一個信號量,mutex_instances顯示信號量現在沒有owner,thread_id為null。
· 當信號量對象被銷毀,對應的行也會被刪除。
查以下2個表,可以診斷瓶頸或者死鎖:
§ Events_waits_current,查看線程等待的信號量。
§ Mutex_instrances,查看其它線程的所有的信號量。
Rwlock_instances表列出了所有rwlock的實例。Rwlock是同步機制用來強制在一定規則下,在給定的事件裡面能訪問一些資源。這些資源被rwlock保護。訪問要不是共享方式要不是排他方式,如果允許非一致性訪問,還可以共享排他方式訪問。Sxlock只有在,mysql 5.7之後才能被使用,用來優化並發性。
根據訪問的需求,所的請求要不是,共享,排他,共享排他或者不授權,等待其他線程完成。
表列如下:
· NAME:記錄點名相關的lock
· OBJECT_INSTANCE_BEGIN:被記錄的鎖在內存中的地址。
· WRITE_LOCKED_BY_THREAD_ID:當一個線程有一個rwlock,排他模式,WRITE_LOCKED_BY_THREAD_ID,就是鎖定線程的thread_id。
· READ_LOCKED_BY_COUNT:當線程當前有一個rwlock共享模式,那麼read_locked_by_count增加1。只是個計數,所以找不到那個線程擁有了讀鎖,但是可以用來查看是否有讀鎖,有多少讀是活動的。
通過執行查詢一下表,何以知道瓶頸和死鎖:
· Events_waits_current,查看等待哪些rwlock
· Rwlock_instrances,查看其它線程是否擁有這個鎖。
只能知道那個線程有了write lock但是不知道哪個線程有read lock。
Socket_instancees表提供了一個實時的連接活動快照。每個tcp/ip連接有一行,或者每個unix socket file連接有一行。
mysql> SELECT * FROM socket_instances\G
*************************** 1. row ***************************
EVENT_NAME: wait/io/socket/sql/server_unix_socket
OBJECT_INSTANCE_BEGIN: 4316619408
THREAD_ID: 1
SOCKET_ID: 16
IP:
PORT: 0
STATE: ACTIVE
*************************** 2. row ***************************
EVENT_NAME: wait/io/socket/sql/client_connection
OBJECT_INSTANCE_BEGIN: 4316644608
THREAD_ID: 21
SOCKET_ID: 39
IP: 127.0.0.1
PORT: 55233
STATE: ACTIVE
*************************** 3. row ***************************
EVENT_NAME: wait/io/socket/sql/server_tcpip_socket
OBJECT_INSTANCE_BEGIN: 4316699040
THREAD_ID: 1
SOCKET_ID: 14
IP: 0.0.0.0
PORT: 50603
STATE: ACTIVE
socket記錄點名字格式,wait/io/socket/sql/socket_type:
1.
服務有一個監聽socket,記錄點那麼socket_type的值為server_tcpip_socket
或者server_unix_socket
。
2. 當有一個監聽socket發現一個連接,那麼服務會轉化到一個新的socket來管理,server_type類型為client_connection。
3. 當一個連接中斷,那麼行會在socket_instances中刪除。
Socket_instances表類如下:
· EVENT_NAME: wait/io/socket/*,具體的名字來至於setup_instruments表
· OBJECT_INSTANCE_BEGIN:socket的唯一標記,值為對象在內存中的值。
· THREAD_ID:內部線程表示。每個socket由線程管理,所以每個socket被映射到一個線程。
· SOCKET_ID:socket內部的分配的文件句柄
· IP:客戶端ip地址
· PORT:客戶端端口地址
· STATE:socket狀態要不是idle要不是active。如果線程等待client的請求,那麼狀態就是idle。當socket變成idle,表中的STATE也會變成IDLE,socket的記錄點中斷。當請求出現idle中斷,變成ACTIVE。Socket的記錄點timing恢復。
IP:PORT組合來表示一個有效的連接。組合值被用於events_waits_xxx表的object_name,來標記連接來至於哪裡:
· 來至於unix域監聽socket,端口是0,ip為‘’
· 對於通過unix域監聽的socket,端口是0,ip為‘’
· 對於tcp/ip的監聽,端口是服務的端口,默認為3306,ip為0.0.0.0
· 對於通過tcp/ip連接的客戶端接口,端口不為0,ip是客戶端的ip。
事件等待表有3個:
· Events_waits_current:當前事件等待表
· Events_waits_history:歷史等待歷史表,最近的等待事件表
· Events_waits_history_long:很多事件等待歷史的表。
等待歷史配置
為了收集等待事件,啟動相應的記錄點和消費者。
mysql> SELECT * FROM setup_instruments
-> WHERE NAME LIKE 'wait/io/file/innodb%';
+--------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+--------------------------------------+---------+-------+
| 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 |
+--------------------------------------+---------+-------+
mysql> SELECT * FROM setup_instruments WHERE
-> NAME LIKE 'wait/io/socket/%';
+----------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+----------------------------------------+---------+-------+
| wait/io/socket/sql/server_tcpip_socket | NO | NO |
| wait/io/socket/sql/server_unix_socket | NO | NO |
| wait/io/socket/sql/client_connection | NO | NO |
+----------------------------------------+---------+-------+
修改enabled和timing列:
mysql> UPDATE setup_instruments SET ENABLED = 'YES', TIMED = 'YES'
-> WHERE NAME LIKE 'wait/io/socket/sql/%';
Setup_consumers包含消費者對應到剛剛的事件表。這些消費者用來過濾等待事件的收集,默認被禁用:
mysql> SELECT * FROM setup_consumers WHERE NAME LIKE '%waits%';
+---------------------------+---------+
| NAME | ENABLED |
+---------------------------+---------+
| events_waits_current | NO |
| events_waits_history | NO |
| events_waits_history_long | NO |
+---------------------------+---------+
啟動所有的等待事件:
mysql> UPDATE setup_consumers SET ENABLED = 'YES'
-> WHERE NAME LIKE '%waits%';
Setup_timers表包含了一行name為wait,表示等待事件的定時的單位,默認是cycle:
mysql> SELECT * FROM setup_timers WHERE NAME = 'wait';
+------+------------+
| NAME | TIMER_NAME |
+------+------------+
| wait | CYCLE |
+------+------------+
修改定時單位時間:
mysql> UPDATE setup_timers SET TIMER_NAME = 'NANOSECOND'
-> WHERE NAME = 'wait';
Events_waits_current表包含了當前的等待時間,每個thread都有一行顯示當前thread的等待時間。Events_waits_current表可以使用truncate table。
Events_waits_current表列:
· THREAD_ID,EVENT_ID
線程相關的事件和線程當前事件號。這2個字段形成主鍵來標示一行。
·
END_EVENT_ID
當事件啟動,這個列為null,如果時間結束分配一個事件號。
·
EVENT_NAME
生成事件的記錄點名。
·
SOURCE
源代碼文件名包含產生事件的記錄點代碼位置。可以幫助用來檢查源代碼。
·
TIMER_START,TIMER_END,TIMER_WAIT
事件的timing信息。時間單位為皮秒。TIMER_START,TIMER_END表示事件的開始和結束。TIMER_WAIT是事件的持續時間。如果事件沒有完成TIMER_END,TIMER_WAIT為null。如果記錄點的timed=no那麼這3個列都是null。
·
SPINS
對於信號量,是只自旋次數。如果為null,表示代碼不使用自旋或者自旋沒有被記錄。
·
OBJECT_SCHEMA,OBJECT_NAME,OBJECT_TYPE_OBJECT_INSTANCE_BEGIN
這些列表示對象被啟動的位置,根據對象類型不同意義不同:
對於同步對象:(cond,mutex,rwlock)
§ OBJECT_SCHEMA,OBJECT_NAME,OBJECT_TYPE為null
§ OBJECT_INSTANCE_BEGIN為同步對象在內存中的地址。
對於文件io對象
§ OBJECT_SCHEMA為null
§ OBJECT_NAME為文件名
§ OBJECT_TYPE為file
§ OBJECT_INSTANCE_BEGIN為內存地址
對於socket對象
§ OBJECT_NAME為IP:PORT
§ OBJECT_INSTANCE_BEGIN為內存地址
對於表io對象
§ OBJECT_SCHEMA是表所在schema的名字
§ OBJECT_NAME表名
§ OBJECT_TYPE為table或者temporary table
§ OBJECT_INSTANCE_BEGIN是內存地址
OBJECT_INSTANCE_BEGIN本身是沒有意義的,除非不同的值表示不同的對象。OBJECT_INSTANCE_BEGIN可以用來調試。比如group by這個字段查看是否有1000個信號量,造成一點瓶頸。
·
INDEX_NAME
使用的index名字,primary表示表的主鍵索引,null表示沒有索引
·
NESTING_EVENT_ID
event_id表示那個event被嵌套
·
NESTING_EVENT_TYPE
嵌套的事件培訓,可能是以下一種,TRANSACTION,STATEMENT,STAGE,WAIT
·
OPERATION
執行操作的類型,lock,read,write中一個。
·
NUMBER_OF_BYTES
讀寫操作的字節個數。對於表io等待,MySQL 5.7.5之前值為null,之後為行數。如果值大於1,是批量io操作。MySQL執行join是nested-loop機制。性能框架可以提供行數和每個表執行join准確的時間。假設一個join查詢,執行如下:
SELECT ... FROM t1 JOIN t2 ON ... JOIN t3 ON ...
在join操作的時候表的表行的增加減少(扇出)。如果t3的扇出大於1,那麼大多數行獲取操作就來自於這個表。假設t1 10行,t2 20行對應到t1一行,t3 30行對應t2 1行。那麼一共會有被記錄的操作是:
10 + (10 * 20) + (10 * 20 * 30) = 6210
為了減少被記錄操作,可以通過每次掃描實現聚合的方式(聚合t1,t2的唯一值)。記錄點計數減少為:
10 + (10 * 20) + (10 * 20) = 410
對於上面的情況使用環境:
§ 查詢訪問的表基本上都是inner join的
§ 查詢執行不需要表內的單個記錄
§ 查詢執行不需要評估子查詢訪問了表。
·
FLAGS
保留
Events_waits_history表每個線程包含了最近N條數據。表結構和events_waits_current一行,也可以被truncate table,N是服務啟動自動設置的,也可以從參數設置: performance_schema_events_waits_history_size。
Events_waits_history_long表每個線程包含了最近N條數據。表結構和events_waits_current一行,也可以被truncate table,N是服務啟動自動設置的,也可以從參數設置: performance_schema_events_waits_history_long_size。
性能框架stage記錄,是語句執行的階段,比如解析語句,打開表或者執行filesort操作。Stage關聯到的了show processlist中的線程狀態。
因為事件等級,等待事件穿插在stage事件,stage事件穿插在語句事件,事務事件。
Stage事件配置
啟動stage事件的收集,啟動相應的記錄點和消費者。
Setup_instruments表包含以stage開頭的記錄點名。這些記錄點除了語句處理的信息,默認是禁用的:
mysql> SELECT * FROM setup_instruments WHERE NAME RLIKE 'stage/sql/[a-c]';
+----------------------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+----------------------------------------------------+---------+-------+
| stage/sql/After create | NO | NO |
| stage/sql/allocating local table | NO | NO |
| stage/sql/altering table | NO | NO |
| stage/sql/committing alter table to storage engine | NO | NO |
| stage/sql/Changing master | NO | NO |
| stage/sql/Checking master version | NO | NO |
| stage/sql/checking permissions | NO | NO |
| stage/sql/checking privileges on cached query | NO | NO |
| stage/sql/checking query cache for query | NO | NO |
| stage/sql/cleaning up | NO | NO |
| stage/sql/closing tables | NO | NO |
| stage/sql/Connecting to master | NO | NO |
| stage/sql/converting HEAP to MyISAM | NO | NO |
| stage/sql/Copying to group table | NO | NO |
| stage/sql/Copying to tmp table | NO | NO |
| stage/sql/copy to tmp table | NO | NO |
| stage/sql/Creating sort index | NO | NO |
| stage/sql/creating table | NO | NO |
| stage/sql/Creating tmp table | NO | NO |
+----------------------------------------------------+---------+-------+
修改stage事件,修改enabled和timing列:
mysql> UPDATE setup_instruments SET ENABLED = 'YES', TIMED = 'YES'
-> WHERE NAME = 'stage/sql/altering table';
Setup_consumers表包含消費者只關聯的事件表名。消費者可能用來過濾收集器stage事件。Stage消費者默認禁用:
mysql> SELECT * FROM setup_consumers WHERE NAME LIKE '%stages%';
+----------------------------+---------+
| NAME | ENABLED |
+----------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
+----------------------------+---------+
啟動所有的stage事件:
mysql> UPDATE setup_consumers SET ENABLED = 'YES'
-> WHERE NAME LIKE '%stages%';
Setup_timers包含name=‘stage’,說明stage事件timing:
mysql> SELECT * FROM setup_timers WHERE NAME = 'stage';
+-------+------------+
| NAME | TIMER_NAME |
+-------+------------+
| stage | NANOSECOND |
+-------+------------+
修改timing值:
mysql> UPDATE setup_timers SET TIMER_NAME = 'MICROSECOND'
-> WHERE NAME = 'stage';
Stage事件進程信息
MySQL 5.7.5,性能架構stage事件表包含2列,每行提供stage進程標示:
· WORK_COMPLETED:stage工作單元完成個數。
· WORK_ESTIMATED:預期的stage工作單元完成個數。
如果沒有進度信息,每列都是null。性能框架提供一個容器來存放這些進度數據:
· 工作單元,是一個量,隨著執行時間的增加變大。
· WORK_COMPLETED,一個或者多個單元增加一次,依賴於被記錄代碼
· WORK_ESTIMATED,可以在stage司改,根據,被記錄代碼。
對於stage事件的進度的記錄可以實現以下任何行為:
· 沒有進度記錄點
這個是最常出現的,因為沒有進度數據被提供,WORK_COMPLETED和WORKESTIMATED都為bull
·
沒有被綁定記錄點
只有WORK_COMPLETED列有意義,WORK_ESTIMATED列沒有值,顯示為0。
打開events_stages_current表監控回話,監控程序可以報告有多少work已經被執行,但是不知道什麼時候可以結束,因為記錄點沒有提供。
·
綁定進度記錄點
WORK_COMPLETED和WORK_ESTIMATED列都是有意義的。
進度標識符的類型適合於已經定義了完成臨界的操作,比如表復制記錄點。通過查詢events_stages_current表來監控會話,監控程序可以監控所有完成比例的stage,通過計算WORK_COMPLETED
/ WORK_ESTIMATED的比率。
stage/sql/copy to tmp table演示,進度標識符如何工作。在執行alter table語句,這個記錄點就很有用,並且會執行很長一段時間。
Events_stages_current表包含當前stage事件,每行一個線程線程當前狀態監控到的stage事件。
Events_stages_current表可以truncate table。
表events_stages_current是events_stages_history和events_stages_history_long的基礎。
Events_Stages_current列:
·
THREAD_ID,EVENT_ID
線程相關的事件和線程當前事件號。這2個字段形成主鍵來標示一行。
·
END_EVENT_ID
當事件啟動,這個列為null,如果時間結束分配一個事件號。
·
EVENT_NAME
生成事件的記錄點名。
·
SOURCE
源代碼文件名包含產生事件的記錄點代碼位置。可以幫助用來檢查源代碼。
·
TIMER_START,TIMER_END,TIMER_WAIT
事件的timing信息。時間單位為皮秒。TIMER_START,TIMER_END表示事件的開始和結束。TIMER_WAIT是事件的持續時間。如果事件沒有完成TIMER_END,TIMER_WAIT為null。如果記錄點的timed=no那麼這3個列都是null。
·
WORK_COMPLETED,WORK_ESTIMATED
這些列提供了stage進度信息,對於記錄點已經用來生成這些信息。WORK_COMPLETED表示有多少工作單元已經被完成,WORK_ESTIMATED表示有多少工作單元預計的stage。
·
NESTING_EVENT_ID
EVENT_ID nested生成的事件。嵌套的event的stage事件通常是語句事件。
·
NESTING_EVENT_TYPE
嵌套事件類型,TRANSACTION,STATEMENT,STAGE,WAIT其中一個。
Events_stages_history為每個線程保留了N個記錄,具體可以通過配置參數修改:
performance_schema_events_stages_history_size
Events_stages_history_long為每個線程保留了N個記錄,具體可以通過配置參數修改:
performance_schema_events_stages_history_long_size
性能框架記錄點語句執行。語句事件發生在高級別的事件,等待事件嵌套在stage事件中,stage事件嵌套在語句事件中,語句事件嵌套在事務事件中。
語句事件配置
Setup_instruments表包含記錄點,以statement前綴的記錄點。這些記錄點的默認值可以使用語句:
mysql> SELECT * FROM setup_instruments WHERE NAME LIKE 'statement/%';
可以通過以下語句修改:
mysql> UPDATE setup_instruments SET ENABLED = 'NO'
-> WHERE NAME LIKE 'statement/com/%';
查看和修改timer:
mysql> SELECT * FROM setup_timers WHERE NAME = 'statement';
+-----------+------------+
| NAME | TIMER_NAME |
+-----------+------------+
| statement | NANOSECOND |
+-----------+------------+
修改timer:
mysql> UPDATE setup_timers SET TIMER_NAME = 'MICROSECOND'
-> WHERE NAME = 'statement';
語句監視
語句監視開始於被請求的活動到所有活動停止。也就是服務受到客戶端的第一個包,到完成返回響應。在MySQL 5.7.2之前,語句只會是高級別的,比如在存儲過程或者子查詢不會被分離出來。
最終記錄點名和服務命令和sql語句有關:
· 關聯到COM_xxx定義在mysql_com.h頭文件和在sql/sql_parse.cc中處理,比如COM_PING和COM_QUIT,那麼記錄點名以statement/com開頭,比如statement/com/ping和statement/com/ping。
· SQL語句是用文本表示的。那麼相關的命令行以statement/sql開頭,比如statement/sql/delete和statement/sql/select。
一些記錄點名表示特殊的錯誤處理:
· Statement/com/error,記錄了服務收集到的未綁定的信息。無法判斷從客戶端發送到服務端的命令。
· Statement/sql/error,記錄了sql語句分析錯誤。用來診斷查詢發送到客戶端的異常。一個查詢分析錯誤和查詢執行錯誤不同
請求可以通過以下渠道獲得:
· 一個命令或者語句從客戶端獲取並發送
· 在replication slave,語句字符串從relay log讀取。
· 從event scheduler獲取事件。
請求的詳細原來是不知道的,並且性能框架從請求的順序獲取特定的記錄點名。
從客戶端收集的請求:
1. 當服務發現一個新的包在socket級別,一個新的的語句以抽象的記錄點名statement/abstract/new_packet開始。
2. 當服務讀取包序號,獲取接受的請求類型,性能框架獲取記錄點名。比如,請求是COM_PING包,那麼記錄點名會變成statement/com/ping。如果請求是COM_QUERY包,知道是一個sql語句,但是不知道具體的類型。這個時候會給一個抽象的記錄點名statement/abstract/query。
3. 如果請求的語句,文本已經讀入到分析器。分析之後,那麼准確的語句類型已經知道了,如果請求是一個插入語句,性能框架會重新定位記錄點名statement/abstract/Query to statement/sql/insert。
對於從復制的relay log上讀取語句:
1. 語句在relay log中是以文本存儲的。沒有網絡協議,所以statement/abstract /new_packet不會被使用,而是使用statement/abstract/realy_log。
2. 當語句被解析,准確的語句類型被得知。比如insert語句,那麼性能框架會重新查找記錄點名,statement/abstract/Query to statement/sql/insert。
上面介紹的,只是基於語句的復制,對於基於行的復制,訂閱表行處理可以被記錄,但是relay log中的行事件描述語句的並不會出現。
對於從事件調度器來的請求:
事件執行的記錄點名為statement/scheduler/event。
事件體重的事件執行記錄點名使用statement/sql/*,不適用其他抽象記錄點名。事件是一個存儲過程,並且存儲過程是預編譯在內存中的。那麼在執行時就不會有解析,但是類型在執行時就知道了。
在事件體內的語句都是子句。比如一個事件執行了一個insert語句,執行的事件是上級。記錄點使用statement/scheduler/event,並且insert是下級,使用statement/sql/insert記錄點。
這樣不單單是要啟動statement/sql/*記錄點,還要啟動statement/abstract/*記錄點。
在之前的5.7版本的,抽象記錄點名用其他記錄點代替的:
· Statement/abstract/new_packet之前為statement/com/
· Statement/abstract/query之前為statement/com/Query
· Statement/abstract/relay_log之前為statement/rpl/relay_log
性能框架事務記錄點。在事件級別,等待事件嵌套stage事件,stage事件嵌套語句事件,語句事件嵌套事務事件。
事務事件配置
Setup_instruments包含的transaction的記錄點:
mysql> SELECT * FROM setup_instruments WHERE NAME = 'transaction';
+-------------+---------+-------+
| NAME | ENABLED | TIMED |
+-------------+---------+-------+
| transaction | NO | NO |
+-------------+---------+-------+
啟動收集事務事件:
mysql> UPDATE setup_instruments SET ENABLED = 'YES', TIMED = 'YES'
-> WHERE NAME = 'transaction';
Setup_consumers表包含transaction的消費者:
mysql> SELECT * FROM setup_consumers WHERE NAME LIKE '%transactions%';
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_transactions_current | NO |
| events_transactions_history | NO |
| events_transactions_history_long | NO |
+----------------------------------+---------+
啟動消費者:
mysql> UPDATE setup_consumers SET ENABLED = 'YES'
-> WHERE NAME LIKE '%transactions%';
設置相關記錄點:
mysql> SELECT * FROM setup_timers WHERE NAME = 'transaction';
+-------------+------------+
| NAME | TIMER_NAME |
+-------------+------------+
| transaction | NANOSECOND |
+-------------+------------+
修改timer_name的值:
mysql> UPDATE setup_timers SET TIMER_NAME = 'MICROSECOND'
-> WHERE NAME = 'transaction';
事務綁定
在MySQL Server,使用以下語句顯示啟動事務:
START TRANSACTION | BEGIN | XA START | XA BEGIN
事務也可以隱式啟動,當autocommit系統變量啟動。當autocommit禁用,在啟動新事務錢要顯示的結束上面一個事務。
COMMIT | ROLLBACK | XA COMMIT | XA ROLLBACK
執行DDL語句,事務會隱式提交
性能框架定義的事務綁定和服務的很相似。事務的啟動和解釋也和服務的事務狀態匹配:
· 對於顯示啟動的事務,事務events在start transaction後啟動。
· 對於隱式啟動的事務,事務事件在第一個語句執行的時候啟動。
· 對於任何事務,當執行commit,rollback事務結束。
微妙的不同點:
· 性能框架中的事務事件,沒有完全包含語句事件比如START TRANSACTION,COMMIT,ROLLBACK語句。
· 語句如果運行在非實物引擎,那麼連接的事務狀態不會影響。
事務記錄點
3個定義的事務屬性:
· 訪問模式(read only,read write)
· 隔離級別
· 隱式或者顯示
為了減少事務記錄點並且保證收集事務數據是完成的,有意義的結果,所有事務都有訪問模式,隔離級別,自動提交模式。
事務事件表使用3列來ACCESS_MODE,ISOLATION_LEVEL,AUTOCOMMIT記錄。
事務記錄點消費可以有很多種方式減少,比如根據用戶,賬號,host,thread啟動或者禁用事務減了點。
線程和嵌套事件
事務事件的上級事件是初始化事務的事件。對於顯示事務啟動,包含START_TRANSACTION和commit and china,如果是隱式事務,第一個語句啟動事務。
顯示的結束事務,COMMIT,ROLLBACK,或者DDL語句,隱式的提交事務。
事務和存儲過程
事務和存儲過程事件關聯如下:
· 存儲過程
存儲過程操作獨立的事務,一個存儲過程可以啟動一個事務,並且一個事務可以在存儲過程中啟動和結束。如果在一個事務中調用,一個存儲過程可以語句強制提交事務並且啟動一個新的事務。
·
存儲函數
存儲函數可以限制顯示或者隱式的事務提交和回滾。
·
觸發器
觸發器活動是語句的活動訪問相關的表,所以觸發器事件的上級事件激活它。
·
調度事件
事件體的語句調度事件發生一個新連接。
事務和savepoint
Savepoint語句以獨立的語句事件被記錄。語句事件包括SAVEPOINT,ROLLBACK TO SAVEPOINT和RELEASE SAVEPOINT語句。
事務和錯誤
事務中的錯誤和警告被記錄在語句事件中,但是不在相關的事務事件。
性能框架提供了連接的統計信息。當客戶端連接,在一個特定的用戶名和host下。性能框架為每個賬號跟蹤連接。
· Accounts:每個客戶端賬號的連接統計信息。
· Hosts:每個客戶端hostname 的連接統計信息。
· Users:每個客戶端用戶名的連接統計信息。
賬號這裡的意思是用戶加上host。連接表有CURRENT_CONNECTIONS和TOTAL_CONNECTIONS列跟蹤所有的連接。Accounts表有USER和HOST列跟蹤用戶和host。Users和hosts表有USER和HOST列,跟蹤用戶或者host。
假設客戶端名user1,user2從hosta,hostb連接過來。性能框架跟蹤連接入選:
· Accounts會有4條記錄,user1/hosta,user1/hostb,user2/hosta,user2/host2.
· Users表有2條記錄,user1,user2
· Host表有2條記錄,hosta,hostb
當客戶端連接,連接表中如果不存在這樣的用戶或者host,那麼就增加一行否則就修改CURRENT_CONNECTIONS和TOTAL_CONNECTIONS列。
當客戶端斷開連接,性能框架減少current_connecitons列。
性能框架也計數內部線程和用戶會話線程驗證錯誤。對應的user和host為null。
每個連接表都可以truncate:
· 行如果是CURRENT_CONNECTIONS=0的就刪除
· 如果>0,TOTAL_CONNECTIONS設置為CURRENT_CONNECTIONS。
· 連接合計表依賴於連接表的值會被設為0.
具體看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-connection-attribute-tables.html
具體看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-user-variable-tables.html
MySQL 5.7.2,性能框架提供了關於復制信息的表。和show slave status的信息類似:
· Show slave status輸出可以閱讀進行檢查,但是不能用來編程使用。
· 查詢結果可以保存到表中,用於分析,設置變量,或者在存儲過程上使用。
· 復制表提供了更好的診斷信息,對於多線程slave操作,show slave status使用last_SQL_Errorno和last_sql_error字段報告所有的協調器和工作線程的錯誤。所以只有最近的錯誤才能可見。復制表會為每個線程上的錯誤保存信息不會丟失。
· 每個工作線程的最新的事務在在復制表是可見的。但是show_slave_status。不可見。
· 開發熟悉的性能框架接口可以擴展復制表提供更多的信息。
復制表描述
性能框架提供一下和復制有關的表:
· 關於Slave連接到master的連接信息表:
§ Replication_connection_configuration:配置連接到master的參數。
§ Replication_connection_status:當前連接到master的狀態。
· 關於slave事務應用的表
§ replication_applier_configuration:slave中事務應用的配置信息。
§ replication_applier_status:當前事務應用的狀態。
· 關於指定線程應用從master獲取事務並執行的信息:
§ Replication_applier_status_by_coordinator:applier線程狀態,之前叫replication_execute_status_by_coordinator。對於有多個work thread的復制有多個work thread和一個協調線程,對於單線程的這個表為空。
§ Replication_applier_status_by_worker:工作線程應用狀態。同上單線程復制表為空。
· 包含復制組成員信息的表:
§ Replication_group_members:提供網絡和組成員狀態。
§ Replication_group_member_status:提供組成員的統計信息和參與的事務。
復制表生命周期
性能框架在以下狀態下寫入復制表:
· 在執行change master to之前表為空。
· 在執行change master to之後。配置闡述可以在表上發現。如果這個時候沒有活動的slave 線程,那麼thread_id列為null,serivce_state的狀態為off。
· Start slave之後,沒有thread_id字段不為空。線程為空閒或者活動service_status狀態為on。線程連接到master server,如果連接建立有個connecting值。
· Stop slave之後,thread_id為null,並且service_State列值為off。
· Stop slave或者thread碰到錯誤,表信息會被保留。
· Replication_applier_Status_by_worker表只有當slave操作在多線程模式下為非空。如果slave_parallel_workers變量大於0,那麼start slave之後,行數和線程個數一樣多。
SHOW SLAVE STATUS不再復制表中的信息
Show slave status的信息和復制表中的信息不同,因為這些表主要是面向GTID的復制。不是基於文件名和位置:
· 以下字段關於文件名和位置的沒有保存:
Master_Log_File
Read_Master_Log_Pos
Relay_Log_File
Relay_Log_Pos
Relay_Master_Log_File
Exec_Master_Log_Pos
Until_Condition
Until_Log_File
Until_Log_Pos
· Master_info_file字段沒有保存。參照master.info文件。
· 以下字段基於server_id,不是server_uuid,沒有被保存:
Master_Server_Id
Replicate_Ignore_Server_Ids
· Skip_counter列基於事件個數,不是gtid沒有被保存。
· 錯誤列是last_sql_errno,last_sql_error的別名,因此不被保存
Last_Errno
Last_Error
在性能框架中,replication_applier_status_by_coodinator和表replication _applier_status_by_worker中的last_error_number和last_error_message列保存了錯誤信息。
· 命令行過濾操作的信息不被保存:
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
· Slave_io_State和slave_sql_running_state列沒有保存。如果需要可以通過thread_id關聯上perocesslist表獲取表中的status值。
· Executed_gtid_set字段可以顯示大量的文字。和性能框架表中顯示已經被slave應用的事務的GTID。已經被執行的GTID可以通過gtid_executed系統變量獲取。
· Seconds_behind_master和relay_log_spae用來將要被決定的狀態不保留。
狀態變量移動到了復制表
從mysql 5.7.5,以下狀態被移動到了性能框架復制表:
Slave_retried_transactions
Slave_last_heartbeat
Slave_received_heartbeats
Slave_heartbeat_period
Slave_running
這些變量用於單源復制,因為只能匯報默認源復制。當有多個復制源,可以使用性能復制表,匯報每個復制渠道的狀態。
多源復制
性能框架表的第一列是channel_name.可以看到每個復制源。
表顯示了連接到slave服務的連接配置。參數被保存在表中,在change master執行的時候會被修改。
replication_connection_configuration表包含以下列:
· CHANNEL_NAME:復制源名。
· HOST:master的host名。
· PORT:master的端口
· USER:連接用戶
· NETWORK_INTERFACE:slave綁定的network接口。
· AUTO_POSITION:如果自定定位被使用了就是1,否則是0
· SSL_ALLOWED, SSL_CA_FILE, SSL_CA_PATH, SSL_CERTIFICATE, SSL_CIPHER, SSL_KEY, SSL_VERIFY_SERVER_CERTIFICATE, SSL_CRL_FILE, SSL_CRL_PATH
這些列顯示了slave連接到master的SSL的參數SSL_ALLOWED的值如下:
§ Yes,如果SSL連接到master被允許。
§ No,如果SSL連接到master不被允許。
§ Ignored,如果SSL被允許,但是slave不支持SSL。
Change master to選項還有其他ssl選項:MASTER_SSL_CA, MASTER_SSL_CAPATH, MASTER_SSL_CERT, MASTER_SSL_CIPHER, MASTER_SSL_CRL, MASTER_SSL_CRLPATH, MASTER_SSL_KEY, MASTER_SSL_VERIFY_SERVER_CERT。
· CONNECTION_RETRY_INTERVAL:重試的秒數。
· CONNECTION_RETRY_COUNT:失誤連接之後重試的次數。
· HEARTBEAT_INTERVAL:復制心跳間隔。
表保存了io線程的狀態,io線程連接到master服務獲取binary log信息。
Replication_connection_status相關列:
· CHANNEL_NAME:來源名。
· GOURP_NAME:保留
· SOURCE_UUID:master的server_uuid
· THREAD_ID:io 線程id
· SERVICE_STATE:服務狀態
· RECEIVED_TRANSACTION_SET:GTID集合反應已經被slave收到的GTID。
· LAST_ERROR_NUMBER,LAST_ERROR_MESSAGE:錯誤好和錯誤信息。
· LAST_ERROR_TIMESTAMP:錯誤的事件格式為YYMMDD HH:MM:SS。
· LAST_HEARTBEAT_TIMESTAMP:最近一次心跳事件的事件。
· COUNT_RECEIVED_HEARTBEATS:收到的心跳次數。
這個表顯示了影響事務應用的配置參數。參數保存在表可以通過change master to修改。
Replication_applier_configure表有以下列:
· CHANNEL_NAME:復制來源名。
· DIESIRED_DELAY:master到slave的延遲。
表保存了slave通常事務執行的狀態。
replication_aplier_status列名:
· CHANNEL_NAME:復制來源名。
· SERVICE_STATE:顯示on表示復制渠道活動或者空閒,如果為off表示應用線程沒有活動。
· REMAINING_DELAY:如果slave等待DESIRED_DELAY直到master應用事件。列顯示剩下的秒數。
· COUNT_TRANSACTIONS_RETRIES:顯示了sql thread應用事務錯誤,導致重試的次數。
對於多線程的slave,slave使用多個工作線程和一個協調線程,協調線程用來管理工作線程,表顯示了協調線程的狀態。如果是單線程slave,表為空。
Replication_applier_status_by_coordinator列:
· CHANNEL_NAME:復制來源名。
· THREAD_ID:SQL/協調線程id。
· LAST_ERROR_NUMBER,LAST_ERROR_MESSAGE:最後一次錯誤號和錯誤信息。
· LAST_ERROR_TIMESTRAMP:時間戳格式為YYMMDD HH:MM:SS。
對於多線程的slave,slave使用多個工作線程和一個協調線程,協調線程用來管理工作線程,表顯示了協調線程的狀態。如果是單線程slave,表為空。
Replication_applier_status_by_worker:
· CHANNEL_NAME:復制來源名。
· WORKER_ID:worker標識符。Stop slave之後線程id會變成null,workerid會保留。
· THREAD_ID:線程id
· SERVICE_STATE:on,表示活動或者空閒,off表示不存在。
· 表示worker發現的最新的事務,如果gtid_mode=off列的值為ANONYMOUS。如果為on:
§ 如果沒有事務被執行,那麼就是空。
§ 當有一個事務被執行了列設置成gtid_next。
§ GTID會被保留,知道下一個事務運行完成。
§ 當下一個GTID被其他線程獲取,從gtid_next上獲得。
· LAST_ERROR_NUMBER,LAST_ERROR_MESSAGE:最後一次錯誤號和錯誤信息。
· LAST_ERROR_TIMESTRAMP:時間戳格式為YYMMDD HH:MM:SS。
表保存了網絡和復制成員組的狀態信息。Replication_group_members列:
· CHANNEL_NAME:復制來源名。
· MEMBER_ID:member標示,和uuid一樣。
· MEMBER_HOST:host地址或者主機名。
· MEMBER_PORT:端口。
· MEMBER_STATE:
§ OFFLINE:group replication插件已經安裝但是沒有啟動。
§ RECOVERING:服務已經加入到一個group,正在獲取數據。
§ ONLINE:成員在全功能狀態。
表保存了replication group成員的狀態,replication_group_member_status:
· CHANNEL_NAME:復制來源名。
· VIEW_ID:該group的當前的view標示符。
· MEMBER_ID:member標示,和uuid一樣。
· COUNT_TRANSACTIONS_IN_QUEUE:pending事務的個數。
· COUNT_TRANSACTIONS_CHECKED:已經被成員認證的事務個數。
· COUNT_CONFLICTS_DETECTED:沖突發現個數。
· COUNT_TRANSACTIONS_VALIDATING:事務可以執行檢查,但是沒有被回收的個數。
· TRANSACTIONS_COMMITTED_ALL_MEMBERS:固化的group事務集合。
· LAST_CONFLICT_FREE_TRANSACTION:最後一個沒有沖突的被認證的事務。
性能框架把元數據鎖通過metadata_locks顯示。顯示一下信息:
· 鎖已經被分配
· 鎖被請求但是沒有被分配。
· 鎖請求但是被死鎖kill或者鎖等待超時而被取消。
這些信息可以了解元數據鎖和會話之間的關系。可以查看等待的鎖,也可以查看已經獲取的鎖。
Metadata_locks表只讀,不能寫入。默認是自動大小的,也可以通過啟動參數配置大小:performance_schema_max_metadata_locks。
表默認是被禁用的,拖過設置setup_instruments的/locl/metadata/sql/mdl來啟動。
性能框架維護內容,使用lock_status表示鎖的狀態:
· 當元數據鎖被請求並且馬上獲取,行的狀態的是GRANTED。
· 當元數據鎖被請求但是沒有馬上獲得,行的狀態為pending。
· 當之前請求的元數據鎖獲取了,行的狀態改為granted。
· 當元數據鎖被釋放,行被刪除。
· 當pending的鎖請求被死鎖發現器取消,狀態改為victim。
· 當pending的鎖超時,狀態變為pending to timeout。
· 當分配的鎖或者pending的鎖被kill,狀態變為killed。
· 當VICTIM,TIMEOUT,KILLED被通知之後行會被刪除。
· PRE_ACQUIRE_NOTIFY,POST_RELEASE_NOTIFY狀態,當獲取鎖或者釋放鎖時,lock子系統通知所在的存儲引擎的狀態。
Metadata_locks列:
·
OBJECT_TYPE:可以是這些值的其中一個. GLOBAL, SCHEMA,
TABLE, FUNCTION, PROCEDURE, TRIGGER (currently unused), EVENT, COMMIT, USER
LEVEL LOCK, TABLESPACE, LOCKING SERVICE。
如果值為USER LEVEL LOCK表示從get_lock()獲取鎖,如果是LOCKING SERVICE表示使用lock
service獲取說。
· OBJECT_SCHEMA:對象所在的schema
· OBJECT_NAME:對象名
· OBJECT_INSTANCE_BEGIN:記錄點對象在內存中的地址。
· LOCK_TYPE:鎖的類型,INTENTION_EXCLUSIVE, SHARED, SHARED_HIGH_PRIO, SHARED_READ, SHARED_WRITE, SHARED_UPGRADABLE, SHARED_NO_WRITE, SHARED_NO_READ_WRITE, or EXCLUSIVE.
· LOCK_DURATION:lock持續的期限。可以是這些值STATEMENT, TRANSACTION, EXPLICIT. STATEMENT 和TRANSACTION從語句或者事務的開始直到語句或者事務的結束。
· LOCK_STATUS:鎖的狀態,PENDING, GRANTED, VICTIM, TIMEOUT, KILLED, PRE_ACQUIRE_NOTIFY, POST_RELEASE_NOTIFY.
· SOUCE:源代碼文件中的文件名和位置。
· OWNER_THREAD_ID:請求元數據的線程。
· OWNER_EVENT_ID:請求鎖的事件id。
通過表table_handles返回表鎖信息。Table_handle顯示了每個打開表的handle的鎖信息。那個表被打開了,如何被鎖定的,是哪個線程鎖的。
Table_handles是只讀表,不能修改,表列如下:
· OBJECT_TYPE:被table handle打開的表。
· OBJECT_SCHEMA:表所在的schema。
· OBJECT_NAME:記錄點對象名。
· OBJECT_INSTANCE_BEGIN:記錄點對象在內存中的地址。
· OWNER_THREAD_ID:請求元數據的線程。
· OWNER_EVENT_ID:請求鎖的事件id。
· INTERNAL_LOCK:SQL級別使用的表鎖。值如下: READ, READ WITH SHARED LOCKS, READ HIGH PRIORITY, READ NO INSERT, WRITE ALLOW WRITE, WRITE CONCURRENT INSERT, WRITE LOW PRIORITY, WRITE。
· EXTERNAL_LOCK:存儲引擎級別使用的表鎖,READ EXTERNAL ,WRITE EXTERNAL
MySQL維護了很多系統變量,系統變量在這些表是可用的:
· Global_variables:全局系統變量。如果應用程序只要全局值可以使用這個表。
· Session_variables:當前會話的系統變量。還有沒有session變量部分的global變量
· Variables_by_thread:每個會話的系統變量。
這些會話級別的變量只包含了活動會話的變量。這些表不支持truncate table。
Global_variablees和session_variables表有這些列:
· VARIABLES_NAME:變量名
· VARIABLES_VALUE:變量的值。
Variables_by_thread的列:
· Thread_id:線程id
· VARIABLES_NAME:變量名
· VARIABLES_VALUE:變量的值。
Variables_by_thread表包含了後台線程的系統變量信息。如果不是所有的線程記錄,那麼表內有些行會小時。這個時候Performance_schema_thread_instance_lost狀態變量大於0 。
和系統變量表類似,具體看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-status-variable-tables.html
等待事件統計表:
· Events_waits_summary_global_by_event_name:等待事件根據每個事件進行合計。
· Events_waits_summary_by_instance:等待事件根據每個instance進行統計。
· Events_waits_summary_by_thread_by_event_name:根據線程和事件名合計的表。
Stage統計表:
· Events_stages_summary_by_thread_by_event_name:stage等待和線程id統計的表。
· Events_stages_summary_global_by_eevnt_name:stage等待中每個事件名的統計表。
語句統計表:
· Events_statements_summary_by_digest:每個schema和digest後的統計表。
· Events_statements_summary_by_thread_by_event_name:語句事件名和線程的統計表。
· Events_statements_summary_global_by_event_name:每個語句事件名的統計表。
· Events_statements_summary_by_program:每個存儲程序的統計(存儲過程和存儲函數)。
· Prepared_statements_instances:預備的語句實例和統計信息。
事務統計表:
· Events_transactions_summary_by_account_by_event_name:每個賬號發起的事件統計。
· Events_transactions_summary_by_host_by_event_name:每個host發起的事務事件統計。
· Events_transactions_summary_by_thread_by_event_name:每個線程發起的事務事件統計。
· Events_transactions_summary_by_user_by_event_name:每個用戶發起的事務事件統計。
· Events_transactions_summary_global_by_event_name:事務事件名統計。
對象等待統計:
· Objects_summary_global_by_type:對象合計。
文件IO統計:
· File_summary_by_event_name:合計所有文件io事件名。
· File_summary_by_instance:每個文件實例的合計。
表IO和鎖等待統計:
· Table_io_waits_summary_by_index_usage:每個所有的表io等待。
· Table_io_waits_summary_by_table:每個表的io等待。
· Table_io_waits_summary_by_table:每個表的鎖等待。
連接統計:
· Events_waits_summary_by_account_by_event_name:每個賬號發起的等待事件統計。
· Events_waits_summary_by_user_by_event_name:每個用戶發起的等待事件統計。
· Events_waits_summary_by_host_by_event_name:每個host發起的等待事件合計。
· Events_stages_summary_by_account_by_event_name:每個賬號stage事件統計。
· Events_stages_summary_by_user_by_event_nam:每個用戶發起的stage事件統計。
· Events_stages_summary_by_ host_by_event_name:每個host發起的stage事件合計。
· Events_statements_summary_by_digest:每個schema下的所有digest。
· Events_statements_summary_account_by_event_name:每個賬號發起的語句事件。
· Events_statements_summary_by_user_by_event_name:每個用戶發起的語句事件。
· Events_statements_summary_host_by_event_name:每個host發起的語句事件。
Socket統計:
· Socket_summary_by_instance:每個實例的socket等待和io合計。
· Socket_summary_by_event_name:socket等待和io合計。
內存統計:
· Memory_summary_global_by_event_name:內存操作事件合計。
· Memory_summary_by_thead_by_event_name:每個線程內存操作合計。
· Memory_summary_by_account_by_event_name:每個賬號內存操作合計。
· Memory_summary_by_user_by_event_name:每個用戶內存操作合計。
· Memory_summary_by_host_by_event_name:每個host內存操作合計。
狀態變量統計:
· Status_by_account:狀態變量賬號合計。
· Status_by_host:狀態變量host合計
· Status_by_user:狀態變量用戶合計
除了上面你的表還有3個表:
· Host_cache:內部host cache信息。
· Performance_timers:事件可用定時器。
· Threads:服務的線程表。
具體看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-option-variable-reference.html
具體看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-options.html
具體看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-system-variables.html
具體看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-status-variables.html
在mysql 5.7.6之前,性能框架使用以下內存分配模型:
· 所有的內存在啟動時分配。
· 服務操作的時候不分配內存。
· 服務操作的時候不釋放內存。
· 在服務關閉的時候釋放內存。
使用這個模型,性能框架會分配大量的內存,除非顯示的配置。Mysql 5.7.6之後的分配模型:
· 可以在服務啟動的時候分配。
· 可以在服務操作的時候額外分配。
· 在服務操作的時候不釋放。
· 在服務關閉的時候釋放內存。
這樣可以根據負荷來調整內存使用,不是現實配置。
有一些性能框架配置參數是自動分配,也可以手動分配:
performance_schema_accounts_size
performance_schema_hosts_size
performance_schema_max_cond_instances
performance_schema_max_file_instances
performance_schema_max_index_stat
performance_schema_max_metadata_locks
performance_schema_max_mutex_instances
performance_schema_max_prepared_statements_instances
performance_schema_max_program_instances
performance_schema_max_rwlock_instances
performance_schema_max_socket_instances
performance_schema_max_table_handles
performance_schema_max_table_instances
performance_schema_max_table_lock_stat
performance_schema_max_thread_instances
performance_schema_users_size
對於自動配置的參數,配置基本如下:
· 如果為-1,默認,參數是自動配置的。
§ 初始對應的內部buffer為空,沒有內存。
§ 當性能框架開始收集數據,沒存被分配到想要的buffer。buffer大小沒有上限,隨著負荷上升上漲。
· 如果設置為0:
§ 初始內部buffer為空,也不會分配內存。
· 如果設置的N>0:
§ 對象的內部buffer為空,並且不分配內存。
§ 當數據開始收集,內存開始分配,直到設置的大小。
§ 一旦buffer大小到達N,內存就不再分配。性能框架收集的數據會丟失,對應的狀態變量的lost instance會增加。
為了查看性能框架使用了多少內存,檢查記錄點。性能框架收集了每個buffer的內存使用信息。這樣可以跟蹤每個buffer的內存使用情況。記錄點,memory/performance _schema/。因為這些buffer是全局的,所以只在memory_summary_global_by_event_ name上顯示。查詢如下:
SELECT * FROM memory_summary_global_by_event_name WHERE EVENT_NAME LIKE 'memory/performance_schema/%';
具體看:
http://dev.mysql.com/doc/refman/5.7/en/performance-schema-and-plugins.html
性能框架可以讓dba來做一些性能調整,比如一個重復出現的性能問題:
1.運行用例
2.使用性能框架表,分析根本的性能問題。分析嚴重依賴於post過濾。
3.問題區域已經劃出,禁用對應的記錄點。比如如果分析出和文件io不相關,禁用io的記錄點。
4.重復 步驟1-3,這樣可以減少干擾找出真正的問題。
5.明確了性能瓶頸的原因:
§ 調整服務參數
§ 調整查詢。
§ 調整數據庫結構
§ 調整代碼。
6.重復步驟1,查看對性能的影響。
在性能調優的時候,mutex_instances.locked_by_thread_id,rwlock_instances. write_locked_by_thread_id列十分重要。比如:
1.線程1,在等待一個信號量。
2.可以使用以下語句查看等待的信號量:
SELECT * FROM events_waits_current WHERE THREAD_ID = thread_1;
3.然後查看那個線程持有著這個信號量:
SELECT * FROM mutex_instances WHERE OBJECT_INSTANCE_BEGIN = mutex_A;
4.查看線程2在做什麼:
SELECT * FROM events_waits_current WHERE THREAD_ID = thread_2;
Information_schema有表包含了系統和狀態變量信息,MySQL 5.7.6之後,性能框架也包含了系統變量和狀態變量信息。性能框架的表會取代information_schema上的表。
在mysql 5.6查看狀態變量和系統變量來自於:
SHOW VARIABLES
SHOW STATUS
INFORMATION_SCHEMA.GLOBAL_VARIABLES
INFORMATION_SCHEMA.SESSION_VARIABLES
INFORMATION_SCHEMA.GLOBAL_STATUS
INFORMATION_SCHEMA.SESSION_STATUS
Mysql 5.7.6,性能框架也包含了系統變量和狀態變量:
performance_schema.global_variables
performance_schema.session_variables
performance_schema.variables_by_thread
performance_schema.global_status
performance_schema.session_status
performance_schema.status_by_thread
performance_schema.status_by_account
performance_schema.status_by_host
performance_schema.status_by_user
MySQL 5.7.6增加了show_compatibility_56系統變量,如果為on:
· 當從information_schema中輸出,會出現警告。
· 在mysql 5.7.6,使用show的where語句就會警告。MySQL 5.7.8之後就不會。
當變量為off,不啟動兼容模式:
· 搜索information_schema表會報錯。
· Show語句輸出的數據來至於性能框架表。
· 這些slave_XXX的狀態變量不可用:
Slave_heartbeat_period
Slave_last_heartbeat
Slave_received_heartbeats
Slave_retried_transactions
Slave_running
應該從性能框架的復制相關的表中獲取數據。
遷移和權限
訪問性能框架中的系統變量和狀態變量需要select權限。如果show_compatibility_56為off,那麼show variables和show status也需要select權限,如果兼容性關閉,這些語句輸出來至於性能框架的global_variables,session_variables,global_status, session_status表。
在mysql 5.7.9,這些表在性能礦建中訪問不需要select權限。對應的show variables和show status也不需要權限。
之後的發布,information_schema變量表和show_compatibility_56會被刪除,show輸出基於性能框架表。