當前位置:
首頁 > 最新 > performance_schema全方位介紹

performance_schema全方位介紹

作者羅小波·沃趣科技高級資料庫技術專家

出品 沃趣科技

| 導語

在上一篇《事件記錄 | performance_schema全方位介紹"》中,我們詳細介紹了performance_schema的事件記錄表,恭喜大家在學習performance_schema的路上度過了兩個最困難的時期。現在,相信大家已經比較清楚什麼是事件了,但有時候我們不需要知道每時每刻產生的每一條事件記錄信息, 例如:我們希望了解資料庫運行以來一段時間的事件統計數據,這個時候就需要查看事件統計表了。今天將帶領大家一起踏上系列第四篇的征程(全系共7個篇章),在這一期里,我們將為大家全面講解performance_schema中事件統計表。統計事件表分為5個類別,分別為等待事件、階段事件、語句事件、事務事件、內存事件。下面,請跟隨我們一起開始performance_schema系統的學習之旅吧。

| 等待事件統計表

performance_schema把等待事件統計表按照不同的分組列(不同緯度)對等待事件相關的數據進行聚合(聚合統計數據列包括:事件發生次數,總等待時間,最小、最大、平均等待時間),注意:等待事件的採集功能有一部分默認是禁用的,需要的時候可以通過setup_instruments和setup_objects表動態開啟,等待事件統計表包含如下幾張表:

我們先來看看這些表中記錄的統計信息是什麼樣子的。

從上面表中的示例記錄信息中,我們可以看到:

每個表都有各自的一個或多個分組列,以確定如何聚合事件信息(所有表都有EVENT_NAME列,列值與setup_instruments表中NAME列值對應),如下:

events_waits_summary_by_account_by_event_name表:按照列EVENT_NAME、USER、HOST進行分組事件信息

events_waits_summary_by_host_by_event_name表:按照列EVENT_NAME、HOST進行分組事件信息

events_waits_summary_by_instance表:按照列EVENT_NAME、OBJECT_INSTANCE_BEGIN進行分組事件信息。如果一個instruments(event_name)創建有多個實例,則每個實例都具有唯一的OBJECT_INSTANCE_BEGIN值,因此每個實例會進行單獨分組

events_waits_summary_by_thread_by_event_name表:按照列THREAD_ID、EVENT_NAME進行分組事件信息

events_waits_summary_by_user_by_event_name表:按照列EVENT_NAME、USER進行分組事件信息

events_waits_summary_global_by_event_name表:按照EVENT_NAME列進行分組事件信息

所有表的統計列(數值型)都為如下幾個:

COUNT_STAR:事件被執行的數量。此值包括所有事件的執行次數,需要啟用等待事件的instruments

SUM_TIMER_WAIT:統計給定計時事件的總等待時間。此值僅針對有計時功能的事件instruments或開啟了計時功能事件的instruments,如果某事件的instruments不支持計時或者沒有開啟計時功能,則該欄位為NULL。其他xxx_TIMER_WAIT欄位值類似

MIN_TIMER_WAIT:給定計時事件的最小等待時間

AVG_TIMER_WAIT:給定計時事件的平均等待時間

MAX_TIMER_WAIT:給定計時事件的最大等待時間

PS:等待事件統計表允許使用TRUNCATE TABLE語句。

執行該語句時有如下行為:

對於未按照帳戶、主機、用戶聚合的統計表,truncate語句會將統計列值重置為零,而不是刪除行。

對於按照帳戶、主機、用戶聚合的統計表,truncate語句會刪除已開端連接的帳戶,主機或用戶對應的行,並將其他有連接的行的統計列值重置為零(實測跟未按照帳號、主機、用戶聚合的統計表一樣,只會被重置不會被刪除)。

此外,按照帳戶、主機、用戶、線程聚合的每個等待事件統計表或者events_waits_summary_global_by_event_name表,如果依賴的連接表(accounts、hosts、users表)執行truncate時,那麼依賴的這些表中的統計數據也會同時被隱式truncate 。

注意:這些表只針對等待事件信息進行統計,即包含setup_instruments表中的wait/%開頭的採集器+ idle空閑採集器,每個等待事件在每個表中的統計記錄行數需要看如何分組(例如:按照用戶分組統計的表中,有多少個活躍用戶,表中就會有多少條相同採集器的記錄),另外,統計計數器是否生效還需要看setup_instruments表中相應的等待事件採集器是否啟用。

| 階段事件統計表

performance_schema把階段事件統計表也按照與等待事件統計表類似的規則進行分類聚合,階段事件也有一部分是默認禁用的,一部分是開啟的,階段事件統計表包含如下幾張表:

我們先來看看這些表中記錄的統計信息是什麼樣子的。

從上面表中的示例記錄信息中,我們可以看到,同樣與等待事件類似,按照用戶、主機、用戶+主機、線程等緯度進行分組與統計的列,這些列的含義與等待事件類似,這裡不再贅述。

注意:這些表只針對階段事件信息進行統計,即包含setup_instruments表中的stage/%開頭的採集器,每個階段事件在每個表中的統計記錄行數需要看如何分組(例如:按照用戶分組統計的表中,有多少個活躍用戶,表中就會有多少條相同採集器的記錄),另外,統計計數器是否生效還需要看setup_instruments表中相應的階段事件採集器是否啟用。

PS:對這些表使用truncate語句,影響與等待事件類似。

| 事務事件統計表

performance_schema把事務事件統計表也按照與等待事件統計表類似的規則進行分類統計,事務事件instruments只有一個transaction,默認禁用,事務事件統計表有如下幾張表:

我們先來看看這些表中記錄的統計信息是什麼樣子的(由於單行記錄較長,這裡只列出events_transactions_summary_by_account_by_event_name表中的示例數據,其餘表的示例數據省略掉部分相同欄位)。

從上面表中的示例記錄信息中,我們可以看到,同樣與等待事件類似,按照用戶、主機、用戶+主機、線程等緯度進行分組與統計的列,這些列的含義與等待事件類似,這裡不再贅述,但對於事務統計事件,針對讀寫事務和只讀事務還單獨做了統計(xx_READ_WRITE和xx_READ_ONLY列,只讀事務需要設置只讀事務變數transaction_read_only=on才會進行統計)。

注意:這些表只針對事務事件信息進行統計,即包含且僅包含setup_instruments表中的transaction採集器,每個事務事件在每個表中的統計記錄行數需要看如何分組(例如:按照用戶分組統計的表中,有多少個活躍用戶,表中就會有多少條相同採集器的記錄),另外,統計計數器是否生效還需要看transaction採集器是否啟用。

事務聚合統計規則

* 事務事件的收集不考慮隔離級別,訪問模式或自動提交模式

* 讀寫事務通常比只讀事務佔用更多資源,因此事務統計表包含了用於讀寫和只讀事務的單獨統計列

* 事務所佔用的資源需求多少也可能會因事務隔離級別有所差異(例如:鎖資源)。但是:每個server可能是使用相同的隔離級別,所以不單獨提供隔離級別相關的統計列

PS:對這些表使用truncate語句,影響與等待事件類似。

| 語句事件統計表

performance_schema把語句事件統計表也按照與等待事件統計表類似的規則進行分類統計,語句事件instruments默認全部開啟,所以,語句事件統計表中默認會記錄所有的語句事件統計信息,語句事件統計表包含如下幾張表:

events_statements_summary_by_account_by_event_name:按照每個帳戶和語句事件名稱進行統計

events_statements_summary_by_digest:按照每個庫級別對象和語句事件的原始語句文本統計值(md5 hash字元串)進行統計,該統計值是基於事件的原始語句文本進行精鍊(原始語句轉換為標準化語句),每行數據中的相關數值欄位是具有相同統計值的統計結果。

events_statements_summary_by_host_by_event_name:按照每個主機名和事件名稱進行統計的Statement事件

events_statements_summary_by_program:按照每個存儲程序(存儲過程和函數,觸發器和事件)的事件名稱進行統計的Statement事件

events_statements_summary_by_thread_by_event_name:按照每個線程和事件名稱進行統計的Statement事件

events_statements_summary_by_user_by_event_name:按照每個用戶名和事件名稱進行統計的Statement事件

events_statements_summary_global_by_event_name:按照每個事件名稱進行統計的Statement事件

prepared_statements_instances:按照每個prepare語句實例聚合的統計信息

可通過如下語句查看語句事件統計表:

我們先來看看這些表中記錄的統計信息是什麼樣子的(由於單行記錄較長,這裡只列出events_statements_summary_by_account_by_event_name 表中的示例數據,其餘表的示例數據省略掉部分相同欄位)。

從上面表中的示例記錄信息中,我們可以看到,同樣與等待事件類似,按照用戶、主機、用戶+主機、線程等緯度進行分組與統計的列,分組和部分時間統計列與等待事件類似,這裡不再贅述,但對於語句統計事件,有針對語句對象的額外的統計列,如下:

SUM_xxx:針對events_statements_*事件記錄表中相應的xxx列進行統計。例如:語句統計表中的SUM_LOCK_TIME和SUM_ERRORS列對events_statements_current事件記錄表中LOCK_TIME和ERRORS列進行統計

events_statements_summary_by_digest表有自己額外的統計列:

* FIRST_SEEN,LAST_SEEN:顯示某給定語句第一次插入 events_statements_summary_by_digest表和最後一次更新該表的時間戳

events_statements_summary_by_program表有自己額外的統計列:

* COUNT_STATEMENTS,SUM_STATEMENTS_WAIT,MIN_STATEMENTS_WAIT,AVG_STATEMENTS_WAIT,MAX_STATEMENTS_WAIT:關於存儲程序執行期間調用的嵌套語句的統計信息

prepared_statements_instances表有自己額外的統計列:

* COUNT_EXECUTE,SUM_TIMER_EXECUTE,MIN_TIMER_EXECUTE,AVG_TIMER_EXECUTE,MAX_TIMER_EXECUTE:執行prepare語句對象的統計信息

PS1:

關於events_statements_summary_by_digest表

如果setup_consumers配置表中statements_digest consumers啟用,則在語句執行完成時,將會把語句文本進行md5 hash計算之後 再發送到events_statements_summary_by_digest表中。分組列基於該語句的DIGEST列值(md5 hash值)

* 如果給定語句的統計信息行在events_statements_summary_by_digest表中已經存在,則將該語句的統計信息進行更新,並更新LAST_SEEN列值為當前時間

* 如果給定語句的統計信息行在events_statements_summary_by_digest表中沒有已存在行,並且events_statements_summary_by_digest表空間限制未滿的情況下,會在events_statements_summary_by_digest表中新插入一行統計信息,FIRST_SEEN和LAST_SEEN列都使用當前時間

* 如果給定語句的統計信息行在events_statements_summary_by_digest表中沒有已存在行,且events_statements_summary_by_digest表空間限制已滿的情況下,則該語句的統計信息將添加到DIGEST 列值為 NULL的特殊「catch-all」行,如果該特殊行不存在則新插入一行,FIRST_SEEN和LAST_SEEN列為當前時間。如果該特殊行已存在則更新該行的信息,LAST_SEEN為當前時間

由於performance_schema表內存限制,所以維護了DIGEST = NULL的特殊行。 當events_statements_summary_by_digest表限制容量已滿的情況下,且新的語句統計信息在需要插入到該表時又沒有在該表中找到匹配的DIGEST列值時,就會把這些語句統計信息都統計到 DIGEST = NULL的行中。此行可幫助您估算events_statements_summary_by_digest表的限制是否需要調整

* 如果DIGEST = NULL行的COUNT_STAR列值佔據整個表中所有統計信息的COUNT_STAR列值的比例大於0%,則表示存在由於該表限制已滿導致部分語句統計信息無法分類保存,如果你需要保存所有語句的統計信息,可以在server啟動之前調整系統變數performance_schema_digests_size的值,默認大小為200

PS2:關於存儲程序監控行為:對於在setup_objects表中啟用了instruments的存儲程序類型,events_statements_summary_by_program將維護存儲程序的統計信息,如下所示:

當某給定對象在server中首次被使用時(即使用call語句調用了存儲過程或自定義存儲函數時),將在events_statements_summary_by_program表中添加一行統計信息;

當某給定對象被刪除時,該對象在events_statements_summary_by_program表中的統計信息行將被刪除;

當某給定對象被執行時,其對應的統計信息將記錄在events_statements_summary_by_program表中並進行統計。

PS3:對這些表使用truncate語句,影響與等待事件類似。

| 內存事件統計表

performance_schema把內存事件統計表也按照與等待事件統計表類似的規則進行分類統計。

performance_schema會記錄內存使用情況並聚合內存使用統計信息,如:使用的內存類型(各種緩存,內部緩衝區等)和線程、帳號、用戶、主機的相關操作間接執行的內存操作。performance_schema從使用的內存大小、相關操作數量、高低水位(內存一次操作的最大和最小的相關統計值)。

內存大小統計信息有助於了解當前server的內存消耗,以便及時進行內存調整。內存相關操作計數有助於了解當前server的內存分配器的整體壓力,及時掌握server性能數據。例如:分配單個位元組一百萬次與單次分配一百萬個位元組的性能開銷是不同的,通過跟蹤內存分配器分配的內存大小和分配次數就可以知道兩者的差異。

檢測內存工作負載峰值、內存總體的工作負載穩定性、可能的內存泄漏等是至關重要的。

內存事件instruments中除了performance_schema自身內存分配相關的事件instruments配置默認開啟之外,其他的內存事件instruments配置都默認關閉的,且在setup_consumers表中沒有像等待事件、階段事件、語句事件與事務事件那樣的單獨配置項。

PS:內存統計表不包含計時信息,因為內存事件不支持時間信息收集。

內存事件統計表有如下幾張表:

我們先來看看這些表中記錄的統計信息是什麼樣子的(由於單行記錄較長,這裡只列出memory_summary_by_account_by_event_name 表中的示例數據,其餘表的示例數據省略掉部分相同欄位)。

從上面表中的示例記錄信息中,我們可以看到,同樣與等待事件類似,按照用戶、主機、用戶+主機、線程等緯度進行分組與統計的列,分組列與等待事件類似,這裡不再贅述,但對於內存統計事件,統計列與其他幾種事件統計列不同(因為內存事件不統計時間開銷,所以與其他幾種事件類型相比無相同統計列),如下:

每個內存統計表都有如下統計列:

* COUNT_ALLOC,COUNT_FREE:對內存分配和釋放內存函數的調用總次數

* SUM_NUMBER_OF_BYTES_ALLOC,SUM_NUMBER_OF_BYTES_FREE:已分配和已釋放的內存塊的總位元組大小

* CURRENT_COUNT_USED:這是一個便捷列,等於COUNT_ALLOC - COUNT_FREE

* CURRENT_NUMBER_OF_BYTES_USED:當前已分配的內存塊但未釋放的統計大小。這是一個便捷列,等於SUM_NUMBER_OF_BYTES_ALLOC - SUM_NUMBER_OF_BYTES_FREE

* LOW_COUNT_USED,HIGH_COUNT_USED:對應CURRENT_COUNT_USED列的低和高水位標記

* LOW_NUMBER_OF_BYTES_USED,HIGH_NUMBER_OF_BYTES_USED:對應CURRENT_NUMBER_OF_BYTES_USED列的低和高水位標記

內存統計表允許使用TRUNCATE TABLE語句。使用truncate語句時有如下行為:

*通常,truncate操作會重置統計信息的基準數據(即清空之前的數據),但不會修改當前server的內存分配等狀態。也就是說,truncate內存統計表不會釋放已分配內存

*將COUNT_ALLOC和COUNT_FREE列重置,並重新開始計數(等於內存統計信息以重置後的數值作為基準數據)

*SUM_NUMBER_OF_BYTES_ALLOC和SUM_NUMBER_OF_BYTES_FREE列重置與COUNT_ALLOC和COUNT_FREE列重置類似

*LOW_COUNT_USED和HIGH_COUNT_USED將重置為CURRENT_COUNT_USED列值

*LOW_NUMBER_OF_BYTES_USED和HIGH_NUMBER_OF_BYTES_USED將重置為CURRENT_NUMBER_OF_BYTES_USED列值

*此外,按照帳戶,主機,用戶或線程分類統計的內存統計表或memory_summary_global_by_event_name表,如果在對其依賴的accounts、hosts、users表執行truncate時,會隱式對這些內存統計表執行truncate語句

關於內存事件的行為監控設置與注意事項

內存行為監控設置:

* 內存instruments在setup_instruments表中具有memory/code_area/instrument_name格式的名稱。但默認情況下大多數instruments都被禁用了,默認只開啟了memory/performance_schema/*開頭的instruments

* 以前綴memory/performance_schema命名的instruments可以收集performance_schema自身消耗的內部緩存區大小等信息。memory/performance_schema/* instruments默認啟用,無法在啟動時或運行時關閉。performance_schema自身相關的內存統計信息只保存在memory_summary_global_by_event_name表中,不會保存在按照帳戶,主機,用戶或線程分類聚合的內存統計表中

* 對於memory instruments,setup_instruments表中的TIMED列無效,因為內存操作不支持時間統計

* 注意:如果在server啟動之後再修改memory instruments,可能會導致由於丟失之前的分配操作數據而導致在釋放之後內存統計信息出現負值,所以不建議在運行時反覆開關memory instruments,如果有內存事件統計需要,建議在server啟動之前就在my.cnf中配置好需要統計的事件採集

當server中的某線程執行了內存分配操作時,按照如下規則進行檢測與聚合:

* 如果該線程在threads表中沒有開啟採集功能或者說在setup_instruments中對應的instruments沒有開啟,則該線程分配的內存塊不會被監控

* 如果threads表中該線程的採集功能和setup_instruments表中相應的memory instruments都啟用了,則該線程分配的內存塊會被監控

對於內存塊的釋放,按照如下規則進行檢測與聚合:

* 如果一個線程開啟了採集功能,但是內存相關的instruments沒有啟用,則該內存釋放操作不會被監控到,統計數據也不會發生改變

* 如果一個線程沒有開啟採集功能,但是內存相關的instruments啟用了,則該內存釋放的操作會被監控到,統計數據會發生改變,這也是前面提到的為啥反覆在運行時修改memory instruments可能導致統計數據為負數的原因

對於每個線程的統計信息,適用以下規則。

當一個可被監控的內存塊N被分配時,performance_schema會對內存統計表中的如下列進行更新:

* COUNT_ALLOC:增加1

* CURRENT_COUNT_USED:增加1

* HIGH_COUNT_USED:如果CURRENT_COUNT_USED增加1是一個新的最高值,則該欄位值相應增加

* SUM_NUMBER_OF_BYTES_ALLOC:增加N

* CURRENT_NUMBER_OF_BYTES_USED:增加N

* HIGH_NUMBER_OF_BYTES_USED:如果CURRENT_NUMBER_OF_BYTES_USED增加N之後是一個新的最高值,則該欄位值相應增加

當一個可被監控的內存塊N被釋放時,performance_schema會對統計表中的如下列進行更新:

* COUNT_FREE:增加1

* CURRENT_COUNT_USED:減少1

* LOW_COUNT_USED:如果CURRENT_COUNT_USED減少1之後是一個新的最低值,則該欄位相應減少

* SUM_NUMBER_OF_BYTES_FREE:增加N

* CURRENT_NUMBER_OF_BYTES_USED:減少N

* LOW_NUMBER_OF_BYTES_USED:如果CURRENT_NUMBER_OF_BYTES_USED減少N之後是一個新的最低值,則該欄位相應減少

對於較高級別的聚合(全局,按帳戶,按用戶,按主機)統計表中,低水位和高水位適用於如下規則 :

* LOW_COUNT_USED和LOW_NUMBER_OF_BYTES_USED是較低的低水位估算值。performance_schema輸出的低水位值可以保證統計表中的內存分配次數和內存小於或等於當前server中真實的內存分配值

* HIGH_COUNT_USED和HIGH_NUMBER_OF_BYTES_USED是較高的高水位估算值。performance_schema輸出的低水位值可以保證統計表中的內存分配次數和內存大於或等於當前server中真實的內存分配值

對於內存統計表中的低水位估算值,在memory_summary_global_by_event_name表中如果內存所有權在線程之間傳輸,則該估算值可能為負數

|溫馨提示

性能事件統計表中的數據條目是不能刪除的,只能把相應統計欄位清零;

性能事件統計表中的某個instruments是否執行統計,依賴於在setup_instruments表中的配置項是否開啟;

性能事件統計表在setup_consumers表中只受控於"global_instrumentation"配置項,也就是說一旦"global_instrumentation"配置項關閉,所有的統計表的統計條目都不執行統計(統計列值為0);

內存事件在setup_consumers表中沒有獨立的配置項,且memory/performance_schema/* instruments默認啟用,無法在啟動時或運行時關閉。performance_schema相關的內存統計信息只保存在memory_summary_global_by_event_name表中,不會保存在按照帳戶,主機,用戶或線程分類聚合的內存統計表中。

下期將為大家分享 《資料庫對象事件統計與屬性統計 | performance_schema全方位介紹》 ,謝謝你的閱讀,我們下期不見不散!

| 作者簡介


更多乾貨,歡迎來撩~


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 數據浮雲 的精彩文章:

Docker,讓資料庫部署完成在彈指一揮間

TAG:數據浮雲 |