成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

絕了!這個MySQL故障定位方法太好用了

新聞 前端
這篇文章介紹的探針像調試程序時候打斷點一樣,只不過打斷點是有交互的,同時是以字節碼形式運行在內核虛擬機(BPF)中的。

我們都知道,MySQL 中的錯誤日志,慢查詢日志可以幫你快速定位問題。

但有時候,日志記錄的信息過少,或者是你感興趣信息被沒有被記下來,有時候又記錄了過多問題,大量無效信息干擾你排查問題。

因此,這篇文章介紹一種新的思路——探針技術,這種技術可以在不影響 MySQL 運行,不破現場環境的前提下,在系統中的關鍵節點插入一些探針來收集信息。

理論上,探針可以插入 MySQL 或者 Linux 內核任意函數進出口,輕松訪問參數等其他詳細信息,資源損失很少,一旦移除探針后沒有任何損失。就像醫生給病人拍片子一樣,在不影響病人健康前提下,實時觀察病人體內情況,為分析病因提供依據和支撐。

Part1 探針的原理

這篇文章介紹的探針像調試程序時候打斷點一樣,只不過打斷點是有交互的,同時是以字節碼形式運行在內核虛擬機(BPF)中的。

一、異常

異常(exception) 就是控制流中的突變,用來響應處理器狀態中的某些變化。理解異常有助于理解探針技術。下圖 所示處理器在執行時執行時,發生了一個重要的變化,我們把它稱為事件(event)。事件可能與當前指令直接相關,如缺頁異常,算術溢出,嘗試除以 0 。也有可能無關如定時器產生信號,I/O 完成。在任何情況下處理器通過異常表進行一個間接過程調用到專門的異常處理程序來處理。

異常可以分成四類: 中斷(interrupt), 陷阱(trap),故障(fault)和終止(abort)。

中斷是異步發生的,是來自處理器外部 I/O (鼠標,鍵盤,網卡等)設備信號的結果。 硬件中斷不是由任何一條專門的指令造成,從這個意義講它是異步的。剩下的異常類型(陷阱,故障,終止)是同步發生的,是執行當前指令的結果。我們把這種指令稱為故障指令。

陷阱是有意的異常,是程序員“主動”觸發的,就像是自己在代碼埋下一個陷阱一樣。 陷阱最常見的用戶是進程發起系統調用,通過 INT 從用戶態 trap 進內核態。

故障由錯誤情況引起,能夠被故障處理程序修正。 當故障發生時,處理器講控制轉移給故障處理程序。例如當缺頁異常發生時,故障處理程序可以從磁盤中間對應的頁 swap 進物理內存。

終止,是不可恢復的致命錯誤造成的結果,通常是一些硬件錯誤。 程序員平常調試代碼時,給程序添加斷點,讓程序在我們想要的地方停住。調試器能夠隨心所欲控制程序運行,主要靠軟件中斷。軟件斷點在 X86 系統中就是指令 INT 3。當程序執行到 INT 3 指令時,會引發軟件中斷。這就是上文提到的陷阱。不同于我們在 Visual Studio 和 GDB 中交互式的斷點,如果程序在 trap 發生時,自動執行預定義和 handle 記錄和統計運行情況,不影響程序的正常運行,達到觀察 MySQL 的目的。

二、探針

為了捕捉程序運行情況,我們在程序中設置一些 “ 陷阱 ”,并設置處理程序,我們稱之為探針。有的探針是在代碼中預定義的,有的是在運行時動態添加的。

1. 靜態探針

靜態探針是事先在程序中定義好,并編譯到程序或者內核的探針。

靜態探針只有被開啟時才會運行,不開啟就不會運行,常見的靜態探針包括內核中的跟蹤點(tracepoints)和 USDT(Userland Statically Defined Tracing)探針。tracepoints 在代碼中埋下鉤子,在運行時調用相連接的探針。

它有“打開”(已連接探針)和“關閉”(未連接探針)兩種狀態。

當跟蹤點處于“關閉”狀態時,它沒有任何作用,只增加微小的時間損失(檢查分支的條件)和空間損失。當跟蹤點為“ 打開”時,每次在調用者的執行上下文中執行跟蹤點時,都會調用相連接的探針。探針函數執行完后,將返回到調用方。USDT和tracepoint類似,只不過是用戶態的,在代碼中插入DTRACE_PROBE()即可。

2. 動態探針

動態探針是應用程序沒有定義,在程序運行時動態添加的探針。

動態探針類似于異常處理機制,當系統產生一個異常,就會跳轉去執行對應的 handle。動態探針會在函數入口和出口插入一些斷點,程序執行到斷點時候會去執行對應的 handle,從而達到觀測應用程序的目的。這里的中斷是指 trap(陷阱),在X86體系是int3指令。

KProbes 是 Linux 內核探針,可以用于監視生產系統中的事件。您可以使用它來解決性能瓶頸,記錄特定事件,跟蹤問題等。

KProbes 能實時在內核代碼中插入中斷指令,雖然這聽上去有點不可思議,實際上 KProbes 做了很多安全性保證,例如 stop_machine 用于確保其他CPU在被修改時停止執行。

實際上 kprobes 最大風險是給一些調用十分頻繁的函數加上探針,如在網絡模塊中,頻繁中斷可能造成一定的性能風險。KProbe需要定義 pre-handler 和 post-handler,當被探測的指令要被執行時,先執行pre-handler程序。同樣,當被探測指令執行之后立即執行post-handler。

uprobes 是Linux提供用戶態的動態探針,合并于2012年7月發布的 Linux 3.5 內核中。uprobes 和 kprobes 十分相似,用于用戶態。

三、BPF

BPF(Berkeley Packet Filter) 最早開發在 BSD 操作系統中,是 TCP/IP 包過濾的工業標注,被 tcpdump 使用。

它的工作方法有點特別: 用戶自定義包過濾表達式,然后注入內核中的 BPF 中運行 ,這樣的好處就是在內核進行過濾而不是將包拷貝到用戶態,避免大量數據從內核態拷貝到用戶態,因此具有較好的性能。

后來出現了eBPF(extend BPF), eBPF 有自己的語言,用戶自己編寫程序編譯后通過 BPF 調用注入到內核的 BPF 虛擬機中運行,可以安全訪問內核內存,它使得內核變成可編程。運行在內核中因為不需要把數據拷貝到用戶空間往往具有比較高的性能,因此 BPF 被很多性能追蹤工具使用。

Part2 使用探針觀測MySQL

上文介紹了相關的技術背景,接下來介紹使用追蹤工具觀測 bpftrace, 它是一種使用 BPF 進行性能分析的前端工具,使用起來很方便,類似與 awk 語言。由于 MySQL 是運行在用戶態態的,要追蹤 MySQL 本身只能使用 ** USDT** 和** uprobes** 。

一、使用 USDT 觀測 MySQL

MySQL 在系統中一些關鍵位置定義了 USDT, 參考文檔 mysqld DTrace Probe Reference(DTrace 是 Solaris 中的動態追蹤工具,bpftrace 是 Linux 版本的 DTrace) 下面展示一下記錄追蹤到的慢查詢的腳本。

  1. #!/usr/bin/bpftrace 
  2.  
  3.  
  4. BEGIN 
  5.         printf("Tracing mysqld queries slower than %d ms. Ctrl-C to end.\n"
  6.             $1); 
  7.         printf("%-10s %-6s %6s %s\n""TIME(ms)""PID""MS""QUERY"); 
  8.  
  9.  
  10. usdt:/usr/sbin/mysqld:mysql:query__start 
  11.         @query[tid] = str(arg0); 
  12.         @start[tid] = nsecs; 
  13.  
  14.  
  15. usdt:/usr/sbin/mysqld:mysql:query__done 
  16. /@start[tid]/ 
  17.         $dur = (nsecs - @start[tid]) / 1000000
  18.         if ($dur > $1) { 
  19.                 printf("%-10u %-6d %6d %s\n", elapsed / 1000000
  20.                     pid, $dur, @query[tid]); 
  21.         } 
  22.         delete(@query[tid]); 
  23.         delete(@start[tid]); 
解讀一下 ** BEGIN** 是這個腳本剛開始運行時候的執行的,打印一些提示信息。usdt:/usr/sbin/mysqld:mysql:query__start 是給** query__start ** 這個函數加的探針,當程序執行到這里時,記錄一下第一個參數 arg0(query), 和當前時間時間戳,并把這些信息保存在 BPF 的 map 中。query__done 探針被執行時,記錄當前時間,減去開始時間(從 BPF 的 map 中獲取),就是這個查詢的花費時間,如果超過閾值就打印出來。如果你會說 MySQL 有慢查詢日志啊,不過這里優勢是不需要重啟 MySQL,可以實時修改閾值。而且 usdt 在高級版本MySQL 會被移除,同時需要編譯時設置參數 -DENABLE_DTRACE=1 才能支持 usdt。

二、使用 uprobes 觀測 MySQL

不同與 usdt 需要事先在代碼中設置觀測點,uprobes 可以在程序中動態添加,可以插入到任意函數的進口和出口位置。下面展示是使用 uprobes 探針對 dispatch_command 進行追蹤,打印出慢查詢語句。

  1. #!/usr/bin/bpftrace 
  2.  
  3.  
  4. BEGIN 
  5.         printf("Tracing mysqld queries slower than %d ms. Ctrl-C to end.\n"
  6.             $1); 
  7.         printf("%-10s %-6s %6s %s\n""TIME(ms)""PID""MS""QUERY"); 
  8.  
  9.  
  10. uprobe:/usr/sbin/mysqld:*dispatch_command* 
  11.         $COM_QUERY = 3;    
  12.         if (arg2 == $COM_QUERY) { 
  13.                 @query[tid] = str(*arg1); 
  14.                 @start[tid] = nsecs; 
  15.         } 
  16.  
  17.  
  18. uretprobe:/usr/sbin/mysqld:*dispatch_command* 
  19. /@start[tid]/ 
  20.         $dur = (nsecs - @start[tid]) / 1000000
  21.         if ($dur > $1) { 
  22.                 printf("%-10u %-6d %6d %s\n", elapsed / 1000000
  23.                     pid, $dur, @query[tid]); 
  24.         } 
  25.         delete(@query[tid]); 
  26.         delete(@start[tid]); 
 運行一下 這里使用參數 10,表示慢查詢閾值是 10 ms.
  1. sudo ./mysql_uprobe_slow.bt 10 
  2. Attaching 3 probes... 
  3. Tracing mysqld queries slower than 10 ms. Ctrl-C to end. 
  4. TIME(ms)   PID        MS QUERY 
  5. 35976      1083      742 select employees.first_name, employees.last_name, titles.title  
  6. 93145      1083      224 select * from employees 
  7. 125348     1083     1727 select * from salaries 
 bpftrace 還提供了直方圖工具,可以將所有查詢耗時記錄下來,最后打印出耗時分布直方圖。
  1. #!/usr/bin/bpftrace 
  2.  
  3.  
  4. BEGIN 
  5.   printf("Tracing MySQL query... Hit Ctrl-C to end.\n"); 
  6.  
  7.  
  8. uprobe:/usr/sbin/mysqld:*dispatch_command* 
  9.   @start[tid] = nsecs; 
  10.  
  11.  
  12. uretprobe:/usr/sbin/mysqld:*dispatch_command* 
  13. /@start[tid]/ 
  14.   @usecs = hist((nsecs - @start[tid]) / 1000000); 
  15.         delete(@start[tid]); 
  16.  
  17.  
  18. END 
  19.   clear(@start); 
  1. sudo ./histo.bt  
  2. Attaching 4 probes... 
  3. Tracing MySQL query... Hit Ctrl-C to end. 
  4. ^C 
  5.  
  6.  
  7.  
  8.  
  9. @usecs:  
  10. [0]                   10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| 
  11. [1]                    0 |                                                    | 
  12. [24)                 0 |                                                    | 
  13. [48)                 0 |                                                    | 
  14. [816)                0 |                                                    | 
  15. [1632)               0 |                                                    | 
  16. [3264)               0 |                                                    | 
  17. [64128)              0 |                                                    | 
  18. [128256)             1 |@@@@@                                               | 
  19. [256512)             1 |@@@@@                                               | 
  20. [512, 1K)              0 |                                                    | 
  21. [1K, 2K)               1 |@@@@@                                               | 

(左右滑動查看代碼)

結語

除了本文展示的 USDT 和 UProbes 兩種探針,展示例子比較簡單,還可以同時插入多個探針,使用 BPF 的 map 來共享信息,達到更強的觀測能力。

除了這兩種探針,還可以使用 tracepoints 和 KProbe 來分析內核態,例如網絡運行情況,磁盤 I/O 情況,當然這需要你對程序有一定熟悉,要不然不知道這些探針加到哪個地方好。

 

責任編輯:張燕妮 來源: 騰訊云數據庫
相關推薦

2022-09-06 10:52:04

正則庫HumrePython

2024-12-13 16:01:35

2022-08-01 07:02:06

SpringEasyExcel場景

2024-05-11 09:38:05

React編譯器React 19

2022-05-31 09:42:49

工具編輯器

2025-01-16 08:50:33

2020-06-23 15:58:42

心電圖

2020-12-29 10:45:55

開發設計代碼

2021-08-11 09:33:15

Vue 技巧 開發工具

2021-09-10 10:15:24

Python人臉識別AI

2022-05-11 14:43:37

WindowsPython服務器

2022-07-14 08:36:28

NacosApollo長輪詢

2021-03-02 20:42:20

實戰策略

2021-03-18 10:12:54

JavaCompletable字符串

2022-07-25 06:42:24

分布式鎖Redis

2020-11-10 06:11:59

工具軟件代碼

2022-06-28 07:14:23

WizTree磁盤文件清理

2021-03-19 09:48:10

Jupyter Not插件Python

2023-12-08 13:40:24

HbaseMySQL數據庫

2022-05-11 09:16:55

Linux網絡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: caoporn国产 | 欧美色综合一区二区三区 | 天天躁日日躁狠狠躁2018小说 | 亚洲精品在线观看视频 | 日韩中文一区 | 国产精品视频网站 | 午夜精品一区 | 夜夜夜操| 午夜影院在线观看 | 91成人免费观看 | 五月天婷婷狠狠 | 精品久久一区 | 国产精品久久久久久久久久久久午夜片 | 91热爆在线观看 | 一级一片在线观看 | 久久久观看 | 一区二区在线免费观看 | 日本久草| 欧美猛交 | 1204国产成人精品视频 | 中文字幕av网站 | 精品美女久久久久久免费 | 成人在线免费视频 | 密室大逃脱第六季大神版在线观看 | 国产精品成人一区 | 免费观看www7722午夜电影 | 草久久久| 日本精品视频在线观看 | 欧美日韩一区二区三区在线观看 | 国产精品久久久久久久久久 | 日韩h| 国产一区二区久久久 | 国产精品乱码一区二区三区 | 国产精品亚洲一区 | 久久人体 | 九九爱这里只有精品 | 欧美午夜激情在线 | 久久久成人免费一区二区 | 精品国产伦一区二区三区观看方式 | 欧美精品一区二区三区四区五区 | 日日拍夜夜 |