我們如何做SQL監控?

qing_yun發表於2022-08-29

對於SQL,我們一般都說SQL審計,SQL最佳化,很少談SQL監控。確實也是,SQL是很難監控的,因為一個複雜的系統中,每天SQL的執行次數高達千萬級別,甚至數十數百億,執行不同SQL的數量也可能高達數萬數十萬。如果大量的SQL是動態生成的或者沒有使用繫結變數,那麼可能在幾分鐘內就有數萬條不同的SQL在執行。

在這樣的情況下,如果我們需要開發一個通用性的產品用於做SQL監控是十分困難的。當然如果我們的業務系統相對比較穩定,需要監控的SQL數量相對穩定,針對這些SQL做針對性的監控也是比較容易實現的。而事實上,對於大多數企業來說,我們需要監控的資料庫系統有上百甚至上千套,業務系統也在不斷髮生變更,在這種環境下,要實現通用的SQL監控確實還是有難度的。

對於DBA來說,也會有一定的SQL語句監控的需求,也都會掌握一些SQL語句監控與分析的技巧。對於Oracle資料庫的DBA來說,我們已經十分習慣於透過AWR報告的TOP SQL相關內容來分析SQL的執行情況,發現存在問題的SQL。不過這種分析只能算SQL最佳化,而無法稱之為SQL監控。

今天我們來探討一下SQL監控的問題,隨著硬體、雲平臺、資料庫技術以及應用架構的不斷最佳化演進,一些完全因為硬體資源或者資料庫配置等引發的資料庫問題的比例相對較少了,而因為SQL引發的問題在運維中的佔比越來越高。對於SQL的監控需求是一直存在的,而且需求的種類也五花八門。前陣子有個客戶提出需要了解隨意一條SQL在某個時間段內的精確執行次數,問我們的D-SMART是否支援。另外一個客戶問我D-SMART是否支援對任意一條SQL的執行計劃變化進行跟蹤,發現問題及時報警。

實際上SQL監控的目的依然是及時發現系統可能存在的風險。我和第一個朋友聊了聊他需要做如此精確的監控的目的是什麼,他也說不出一個所以然來。實際上這個需求最好從應用的角度去做,在應用系統的模組中透過鉤子進行統計的成本是最低的,從資料庫去做可能成本太高。如果要從資料庫的角度去統計,其精準度就要大打折扣了,因為資料庫的記憶體中儲存的SQL統計資訊並不完整,因此我們去取樣的時候會有誤差。當某條SQL有一定時間沒有執行的時候,很可能會從記憶體統計緩衝區中被清除,下一次再出現的是可能從頭統計了。目前我們的TOP SQL採集工作也是5分鐘進行一次,對這段時間內比較活躍的SQL進行一次統計。因為大型系統中的SQL數量可能會十分龐大,為了避免給生產系統帶來太大的負載,這種採集也必然是輕量級的,只採集一些十分重要的TOP SQL的詳細資訊。

至於第二個需求,如果我們要對全量的SQL進行執行計劃的跟蹤,那肯定是不現實的,如果系統中存在幾萬條SQL,幾十萬個執行計劃,採集一次的成本開銷之大,對於一些併發量較高,並且業務對SQL執行延時的穩定性要求較高的系統來說,是無法承受的。

Oracle資料庫的SQL語句都是儲存於共享記憶體的CURSOR結構中的,而不少開源、國產資料庫並不使用全域性共享CURSOR的方式,CURSOR僅在會話內共享。因此採集SQL語句與執行計劃的介面並不十分完善,有些資料庫甚至還要開啟一些特殊的跟蹤功能才能實現。針對不同的資料庫產品,我們需要採取不同的手段來採集TOP SQL,因此SQL監控的實現方式還是需要仔細去設計的。

另外一點,我們做SQL監控的目的並不是SQL監控本身,SQL監控的目標是防止SQL出現異常,從而導致資料庫系統出現問題。因此我們不能把SQL監控當初目標,而是把SQL監控當成一種手段和方法。因此在一個系統中,監控某個時間段內某條SQL的精確執行次數在絕大多數場景中沒有任何意義,我們只需要知道某些可能影響系統的SQL語句的大致執行數量、平均每次執行的開銷以及執行次數與開銷的歷史波動情況,就足以支撐我們所需要的運維分析場景了。

而某條SQL語句的執行計劃發生了變化,如果其執行成本並無增加,對資料庫的穩定執行並無太大的影響,那麼這種變化我們也無需實時發現,只要在定期的審計中有所發現,並能夠分析出其存在的潛在風險就可以了。而因為執行計劃的變化而導致了系統負載過高,系統效能下降,那麼我們從其他一些方面也可以觀察到。我們利用資料庫可觀測性的一些其他側面能夠發現此類問題就可以了。比如我們可以透過整個系統的邏輯讀/物理的突然增加,CPU使用率的增加,活躍會話數的增加等相對容易觀察到,並且監控成本比較低的可觀測性指標也能夠發現因為SQL執行計劃變壞導致的問題,並能夠透過分析定位,快速發現是因為SQL執行計劃變壞導致了該問題。那麼我們也就能解決這個問題了。

比如說在D-SMART中採用了關鍵SQL平均邏輯讀突增與每秒邏輯讀數量超出正常水平等兩種方式來發現相關的問題。我們以關鍵SQL平均邏輯讀突然增加的告警來看看D-SMART是如何分析這個問題的。

從SQL的歷史分析上看,確實出現了平均每次邏輯讀突變的情況。我們再來看看SQL的執行計劃,是不是出現了多個執行計劃。

從分析上看,確實出現了兩個不同子游標,其中一個遊標的執行成本明顯大於另外一個。正是因為這個問題,導致了剛才那個告警的出現。這種方式是針對關鍵SQL的,關鍵SQL是一個系統中對應用可用性或者SLA有著關鍵影響的SQL,我們可以在每個取樣週期都對其進行監控。因為一個系統中的關鍵SQL的數量不會很大,因此這種專項監控的成本也不高。

而如果出問題的並不是關鍵SQL,而是隨便哪一條SQL,突然因為統計資訊不準確或者說表資料量的變化,亦或是系統變更後出現了應用的BUG,從而引起了執行計劃的變化,進而導致了系統資源不足,引起關鍵SQL因為系統資源不足(記憶體,CPU,IO等)而引發了效能問題。這種情況也是十分常見的。如果這條SQL出問題還沒有觸發系統資源不足,從而導致核心業務故障,那麼這個問題並不一定需要馬上被捕捉到,並且進行處置。只需要在定期的SQL審計(比如每週)中發現這個問題,就完全可以解決。如果比較嚴重了,可能會導致系統故障,那麼我們還是需要儘可能早的捕獲到此類問題。在D-SMART中我們針對邏輯讀突增、物理讀突增、R佇列突增、活躍會話數突增、同一條SQL的併發執行量達到某個閾值(此類SQL執行計劃異常後必然出現執行時間過長,如果對系統產生較大影響,則大機率會出現多個SQL同時執行的情況出現)等,都會產生告警。並且在這些告警中,都可有執行計劃發生變化的診斷路徑,可以用於根因溯源。這樣就採取了一種迂迴策略,從一個側面解決了此類問題的預警問題。

不同使用者對於SQL監控的需求會有所不同,不同的資料庫能夠提供的能力也不同,比如PG資料庫需要安裝外掛才能實現SQL採集。而記憶體中SQL執行計劃的採集需要另外的外掛才能夠實現。有些資料庫則需要開啟慢SQL跟蹤才能採集到某些慢SQL的執行計劃。根據資料庫的特點,用對資料庫系統影響較小的方式對TOP SQL或者關鍵SQL進行監控,才能獲得較好的效果。

來自 “ 白鱔的洞穴 ”, 原文作者:白鱔;原文連結:https://mp.weixin.qq.com/s/oht1qqyIyKSNeDBs4b3fSQ,如有侵權,請聯絡管理員刪除。

相關文章