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

慢查詢導致 MySQL 雪崩,危險可能不止于此……

數據庫 新聞
殺慢查詢還是需要非常謹慎的,提供服務是第一原因,所以既需要保證殺的準確,也需要保證殺的及時,還需要保證不能殺出來問題,所以這事情本身是一個很復雜的問題。

一、背景

慢查詢在 MySQL 數據庫管理中,已經是再熟悉不過的事情了,只要我們在使用 MySQL,那慢查詢就會一直存在下去,因為不管是業務 APP,還是 MySQL,他們的狀態都是動態變化的,在這個動態的服務中,可能經常遇到的問題是,某幾個指標的變化形成了共振效應,進而導致本來不慢的查詢語句變成慢查詢,本來可以走二級索引并很快返回的語句變成了全表掃描,這還不止,可能這種影響范圍會繼續進一步擴大,導致整個實例或者集群被打死,出現一些“被影響”的很慢的查詢語句,從而產生了我們通常意義上的“雪崩效應”,最終導致的是由慢查詢引起的數據庫故障。

但這樣的故障,真是由慢查詢導致的么?這個我認為不一定,具體原因很難窮盡,但在一個動態變化的環境中,多個因素導致了共振效應,進一步導致雪崩現象,這應該是確定的。面對這樣的問題,我們應該怎么解決,或者提前避免呢?可能很多人會認為因為是共振導致的,是不是要去查到具體共振因素,這樣問題就解決了?我想說的是,這種解決辦法有時候可以解決問題,但通常問題發生之后,共振的場景已經不見了,我們此時見到的只有慢查詢,除非有很全面的日志,不然這種方法不具有可操作性。

二、解決辦法

對于上面出現的問題,我們不能從原因上解決慢查詢,那么是不是可以考慮從結果上去解決呢?結果就是慢查詢,也就是說,我們是不是只需要把慢查詢消滅了,就可以把相應的雪崩避免了?

答案是肯定的,我們可以想想,如果雪崩出現的時候,也就是雪崩引起的故障出現的時候,我們是咋處理故障的?一般情況下,也是通過不斷殺慢查詢的方式來解決問題的,讓擁堵消失,擁堵消失之后,數據庫本身的狀態就平靜了,業務就可以繼續有條不紊的訪問了,所以用同樣的原理,我們如果能在共振出現之后,第一批慢查詢出現的時候,將其殺掉,這樣可能就能有效避免后續的雪崩效應,這樣的推論是沒有問題的。

三、殺慢查詢的方式

很多人想到了上面的解決方案,就是將慢查詢殺掉,但在慢查詢一開始出現的時候,壓力還不大,數據庫可能可以扛過去,DBA 可能并不會注意到這個數據庫“將來”會出現問題,所以并不會選擇殺掉,只有惡化了,或者已經出現小面積的雪崩了,才會選擇去殺掉慢查詢,但此時殺掉的邏輯很簡單——只要是查詢的,時間大于多少的,可能就會被殺掉了,大不了再多加幾個過濾條件而已,比如狀態是 statistics,方式是大同小異的,但這樣的方式有很多弊端,我列舉如下:

1. 很難做到常態化

就像上面說的,在雪崩之前,并不能預測到當前數據庫馬上要故障了。就自動啟動殺慢查詢這個動作,因為數據庫是一個動態服務,當前的服務水平,和服務能力,需要綜合各種指標來判斷,包括 CPU、內存、多實例互相影響、IO、并發個數、Buffer Pool的有效性等等,即使是人工去判斷,也很難做到,所以常態化程序去決定要不要殺一個慢查詢,基本是無稽之談。這種殺慢查詢的方法,只能用來在處理故障的時候使用,而不是常態化。

2. 很難做到準確

這種殺慢查詢的方法,其實就是憑借經驗值,綜合各種指標,去制定殺慢查詢的策略,比如當機器 Load,或者 CPU 使用率到達多少的時候,就開始殺了,但請問,在多實例模式下,你如何判斷是 3306 導致的 Load 升高,而不是 3307 呢?比如再考慮 IO 的問題,如果發現某一個時間 IO 特別高,然后就開始啟動殺慢查詢的操作,IO 高了你如何去判斷是哪個 SQL 語句導致的 IO 高?判斷不出來的話,難道是要全部殺掉嗎?IO達到多少的時候要殺?30?50?還是 100?這個由誰來定義,假定定義為 30,那 29 要不要殺呢?如何確定30是有問題的,而 29 是沒有問題的?同時業務出故障,還有一個容忍度,有些業務 30 就可能出問題了,但有些業務 load 到達 100 也沒問題,那請問用什么邏輯來區分對待不同的數據庫呢?因為很明顯的是,不同數據庫使用相同的判斷指標,是非常不明智的。其實這里舉了兩個指標的例子,想說明的問題是,最終這種方式,可能就是亂殺一通,本身沒問題,卻制造了不少問題,本身有問題卻并沒有解決,請問,殺出來問題,誰來負責?

3. 很難做到自動化

自動化有一個程度的問題,這里包括兩種,一種是自動決定要不要殺,要殺什么,另一種是需要殺的時候 DBA 啟動自動化腳本去殺,這里最關鍵的問題是決策問題,什么時候啟動的問題。很明顯,人判斷比機器判斷靠譜多了,目前 AIDBA 還不具備這樣的能力,如果不具備,那就沒辦法談自動化了,只能是人工觸發,很明顯這就是在處理故障的問題,而不是提前避免或者預防故障的問題了。

4. 很難做到統一化

就像上面說到的,不同業務線,不同的機器性能,不同的 SQL 語句,不同的數據量,不同的索引,不同的表大小,一個語句執行多久需要被殺掉?掃描多少行需要被殺掉?Load 達到多少需要被殺掉?并發量達到多少又需要被殺掉呢?相關指標不一而足,但核心問題是,這些指標難道有一個標準嗎?達到這個標準就肯定出問題嗎?這個誰能定這樣的邏輯?誰又敢定呢?假如達到某個標準就肯定出問題,或者誤殺了之后,業務自己承擔責任,那不同業務肯定具有不同的指標,那么多數據庫實例,如何管理這些指標呢?這些都是問題。

5. DBA 不了解 SQL 語句

DBA 在運維過程中的角色,大多數是去做 DB 本身的一些運維工作,比如遷移、風險控制、故障處理、拆分、優化等,但針對 SQL 語句本身,只有業務自己了解其內部邏輯及語句之間的相關邏輯等,一個語句執行多少時間是合理的,超過多少時間是不合理的,這種信息 DBA 是不了解的,這方面沒有任何專業度可言,而現在恰恰是要把殺 SQL 語句的決策交給 DBA,這是荒唐的,不可信的,DBA 不可以去做這樣的決定,除非數據庫此時已經故障了,這是故障處理的范疇。因為 DBA 沒有能力去做這個事情,那就不做,因為運維邏輯很簡單,DBA 不做沒有把握的事情。

6. 業務沒辦法做決定

上面也講到了,判斷指標包括很多,沒有標準能確定一個指標達到了某個值就肯定出問題,或者小于某個值就肯定沒問題,這個 DBA 沒辦法去定義,也沒有經驗值可用,但這事兒要做的話,DBA 沒有辦法做到,也沒有權利決定是不是殺慢查詢,是不是可以把這些參數的決定權交給業務開發自己去定義,比如他關心的某個數據庫,如果出現慢查詢的話,給出一系列指標,這些指標達到多少的時候就去殺,指標之間的關系是或還是與,或者可以更精細化的定制,系統做得非常精細,或和與可以隨便定制,但這樣的問題是,業務看到 Load 這個框的時候,應該填多少呢?多少才是沒有問題的,或者給一個數據庫指標,比如并發量,達到多少就會有問題呢?這個時候我相信,業務是懵的,這是跨領域的,你雖然把決定權交出去了,但他在專業度上面,沒辦法做這個決定,他怎么會把并發度與故障聯系起來呢?或者 Load 與故障聯系起來呢?這更是無稽之談了。

7. 責任界定

這種殺慢查詢的方式,上面已經講得非常清楚了,沒有優點只有缺點,花了大力氣還惹一身騷,吃力不討好,做了一個非常強大的系統,最后不知道如何下手,不知道如何去執行,那不是白費力氣了么?這種方式存在一個很大的問題是,存在大量的錯殺問題,殺錯了,出故障了,誰的責任?這意味著出現的局面是各種扯皮,各種推卸責任,之后,可能會進入無休止的調參運動中,這樣 DBA /開發就成功地做了一次華麗轉身,請叫我們調參工程師。

8. 數據庫核心是服務

最后一個問題,其實是 DB 的核心作用,作為 DBA 或者了解 DBA 的人都知道,操作系統、手機系統、APP 等系統出了名的運維三板斧之一是:重啟,重啟是很湊效的。但數據庫不是這樣,數據庫是管理數據的,重啟導致的問題可能更大,所以數據庫的運維思路是盡可能讓他活著,盡可能讓他好好地活著,這樣的目的只有一個,就是更好的服務業務,所以不管任何時候,我們第一思路是提供服務,而不是寧愿錯殺,也要在某種情況下就進入拒絕服務的狀態,這種思路是有問題的,不符合數據庫運維思路的。

上面講了殺慢查詢的綜合方法的各種弊端,很明顯這是不靠譜的,不負責任的,后患無窮的,不解決問題的,我們時刻要堅決守住這樣的底線,不要去做這樣的事情,不然肯定是徒勞的,吃力不討好的。

那還有沒有一種辦法,在有效避免上述所有問題的同時,還能解決慢查詢帶來的各種問題呢?答案是有的。

四、解鈴還須系鈴人

我們做這個事情,需要換一種思路去考慮問題,語句是開發寫的,語句是從應用程序訪問過來的,那只有應用端或者開發才了解 SQL 語句的情況,包括需要執行多久(SQL 語句的超時時間設置),或者說執行多長時間,就肯定是有問題的,而語句相關的其它參數,他們是不一定能知道的,他們在只知道這樣的信息的情況下,如何去殺慢查詢呢?有三種辦法:

1.注冊制

DBA 開發一個“強大”的系統,用來注冊 SQL 語句,指標包括數據庫地址,最大執行時間,其它都可以不要,有了這個系統,DBA 可以在每一個數據庫上面搞一個 Agent,不斷地去訪問這個配置庫,同時去看 Processlist 中的信息,如果語句和時間都能匹配得上,就殺掉,這種辦法當然比上面的辦法強多了,至少執行殺的動作是有決策根據的,這種決策根據是建立在業務對自己語句的了解以及對健康度的風險把控之上的,這樣就可以有效的避免意外情況相互擁堵導致的數據庫雪崩問題,至少在雪崩之前就可以將這個擁堵的狀態解決掉。但這種辦法也是有問題的,久而久之這個配置庫會非常大,因為極限條件下,線上出現的每個 SQL 語句都會出現在這里,這個殺慢查詢的 Agent 就沒辦法良好運行了,并且匹配的是整個 SQL 語句,涉及到模式處理問題,以及很重的字符串比較的問題,效率不能保證。所以,這種辦法也是不可行的。

2.簽名制

還有一種更好的辦法,就是在 SQL 語句中加上注釋,類似這樣的形式:

/*!99999 21B2438F55 kill me when query_time > 10 app comments*/ select sleep(10);

下面首先講一下設計細節:

1)99999 表示的是 MySQL 版本,99999 大于現在所有的 MySQL 版本,所以注釋里面的內容就會被 MySQL 忽略,所以這用的是 MySQL 所支持的方式。

2)后面的 MD5 值,是為了做簽名的,主要是為了防止錯殺的,一個 MD5 填在這里,如果能碰巧雷同了,那是不是可以買彩票了。所以這個 MD5 值,可以很好地用來給 DBA 做語句識別的功能,而不用去比較整個字符串了,識別到這個值之后,再去解析其它信息,匹配到了,則執行殺的動作。

3)后面的 "kill me when query_time > 10",類似是一個協議內容,明確表示這個語句要啟用殺慢查詢的服務,這里的 10 是可以由業務自己定義,想定義多少都可以,以秒為單位,定義值的選擇,需要慎重考慮清楚,可以參考業務正常執行的歷史時間,也可以參考業務流程最大容忍的正常時間,大致設置一個值就行,因為當出現異常情況的時候,這個語句需要執行的時間肯定都會比這個大不少,肯定就被殺掉了。當然如果設置太大,導致沒有殺掉,也是有問題的,以秒為單位設置的話,殺慢查詢是不是及時還要決定于數據庫后臺殺慢查詢程序的執行頻率,如果 5 秒一次的話,那就精度是 5 秒,如果是1秒一次的話,精度就是 1 秒,可以自由控制。

4)后面 “app comments” 部分,業務程序就可以隨便寫了,Agent 也不會做解析,也可以不寫,主要用來做一些注釋功能。

下面再說一下這種方式的好處與缺點:

1) 精確: 很明顯,這種辦法是具體到了語句級別,誰想要使用這樣的服務,就在語句前面做簽名,寫上時間,不寫的不會被殺掉。因為有簽名,遵守了相關協議,業務程序和 DB 之間不存在責任界定不清楚的問題,合作可以很愉快。

2) 常態化: 這種辦法就可以在數據庫本機部署一個 Agent,專門每隔幾秒去檢查一次數據庫執行情況,如果能匹配到慢查詢就殺,匹配不到就白跑一次,動作輕量,影響不大,可以有效避免問題的出現。

3)風險有效控制: 當匹配到了需要殺的語句之后,也可以放心地殺掉,因為這是業務根據自己的邏輯及預期設置好的時間,即使被殺了,也是不會有問題的,風險可控,關鍵是可以避免異常語句引起的問題,因為我們殺慢查詢的目標,就是要處理異常情況的慢查詢。

4)業務決定: 業務做了自己擅長的事情,DBA 在這個過程中沒有任何決策的工作,是一個雙贏的局面。

5)效率高: 相比上面的方式,這種方式的配置都在 SQL 語句中,并且只有一個執行時間值,非常容易解析出來,并且大部分情況下,數據庫狀態都是正常的,并沒有什么語句需要殺掉的,所以效率是非常高的。Agent 本身并不需要依賴其它模塊,簡單易推廣。

6)誤殺: 這種辦法存在的唯一風險是,殺一個語句使用的是 connection id,當匹配到一個需要殺掉的語句之后,在執行 kill 動作時,這個語句正好執行完了,而此時正好這個 connection 執行了一個新的語句,殺掉的時候并不知道是新的語句,此時被殺掉的是新語句,從而導致了誤殺,但實際上應該想想,這種概率是非常小的,在匹配到與殺之時,時間差應該是幾毫秒,在這幾毫秒的窗口內,誤殺的概率可以忽略不計,但這是一種潛在風險,需要提前考慮到。

7)推廣度: 這種方法是有接入門檻的,但實際上門檻高度有限,如果所有業務都能接入的話,數據庫整體運行就會很流暢,異常問題都會提前發現與避免,不會再出現大的雪崩效應,當然這個結論,還需要時間驗證,并且還需要業務填的時間相對合理才行。

3.源碼制

還有一種辦法可以實現這種功能,就是通過修改 MySQL 源代碼來實現,其實業內已經有一些這樣的團隊做了這樣的事情,但最基本的邏輯還是沒變的,需要業務開發自己在 SQL 語句中設置超時時間值,Mysql 服務執行的時候通過解析語句發現設置了這個值,就會在執行的過程中不斷檢查已經執行的時間,如果超過所設置的時間了,就會將其殺掉,從而實現了這樣的 SQL 語句執行超時的機制。

但很明顯,這樣的實現方式,門檻非常高,需要修改源碼,不斷維護源碼,很少有人能做到這樣,并且我認為,運維和使用 MySQL 的過程中,如果有啥需求,能通過 MySQL 的原生方法就能解決掉的(外圍辦法),就不要去改源碼來解決,因為通過外圍辦法解決的話,風險度會小很多,并且自由可控,不需要對 MySQL 服務本身做過多干預,解決過程很輕量,易用。

五、總結

綜上所述,殺慢查詢還是需要非常謹慎的,提供服務是第一原因,所以既需要保證殺的準確,也需要保證殺的及時,還需要保證不能殺出來問題,所以這事情本身是一個很復雜的問題。

上面推薦的這種解決辦法,實際上就是在給一個 SQL 語句設置一個相對合理的超時時間,這是非常容易理解的,大家可以想想,寫代碼的時候,超時時間不都是隨處可見的嗎?如果能給 SQL 語句也設置一個超時時間,這樣可以更好的保護數據庫的穩健運行,那何樂而不為呢?

DBA 是一個服務性質的工種,也非常想替業務解決一些頭疼的問題,但解決問題的時候,不能只見樹木不見森林,需要站在一定高度去看待問題,需要找到合適的方法才能很好的解決問題,不然有可能就是在創造問題,找到了好的方法,通常就可以達到事半功倍的效果。

把復雜問題簡單化,業務去做自己擅長的工作,DBA 也去做自己力所能及的工作,分工明確,合作共贏,長久下去,一定可以建立一個穩定、健康和良好的服務環境。

作者介紹

王竹峰, 去哪兒網數據庫總監。擅長數據庫開發、數據庫管理及維護,一直致力于 MySQL 數據庫源碼的研究與探索,對數據庫原理及實現有深刻的理解。曾就職于達夢數據庫,從事多年數據庫內核開發工作,后轉戰人人網,任職高級數據庫工程師,目前在去哪兒網負責 MySQL 源碼研究與運維、數據庫管理和自動化運維平臺設計開發及實踐工作,是 Inception 開源項目及《MySQL運維內參》的作者, MySQL 方向的 Oracle ACE。

責任編輯:張燕妮 來源: dbaplus社群
相關推薦

2016-02-23 17:50:38

認知計算IBM

2010-02-24 09:53:07

Zaurus Ubun

2020-04-25 14:06:04

BGP網絡攻擊泄露

2020-10-27 16:20:51

人臉識別智能安全物聯網

2019-11-25 14:06:44

AI無人駕駛自動駕駛

2016-12-28 18:07:08

大數據大數據技術大數據發展趨勢

2017-06-26 09:40:50

Python代碼寫法

2017-07-07 16:57:35

代碼Python

2020-10-27 13:50:58

央視揭AI黑產

2020-07-07 15:50:17

區塊鏈互聯網人工智能

2017-05-03 09:49:14

OpenStack私有云搭建

2022-06-22 16:31:26

阿里云數字化轉型云原生

2022-05-24 15:34:35

Commvault

2018-05-06 23:04:12

Android Chrome OS操作系統

2022-12-22 10:37:53

數字化自動化UiPath

2022-07-12 09:36:18

數據庫查詢

2017-01-06 13:45:45

智能 運動
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 美女福利网站 | 国产做a爱片久久毛片 | 久久久久久久国产精品 | 99草免费视频 | 亚洲国产日韩欧美 | 久久国产精品免费一区二区三区 | 亚洲v日韩v综合v精品v | 国产一区三区视频 | 九九九视频在线观看 | 手机在线观看av | 在线中文字幕av | 国产成人99久久亚洲综合精品 | 91看片网 | 国产精品欧美精品日韩精品 | 精品一区二区三区在线观看 | 少妇淫片aaaaa毛片叫床爽 | 亚洲精品日韩在线观看 | 97视频在线观看免费 | av激情影院| 亚洲一二三区精品 | 91久久精品一区二区二区 | 国产成人精品一区二区三区网站观看 | 美女中文字幕视频 | 国产电影一区 | 福利av在线 | 欧美伊人久久久久久久久影院 | 亚洲资源站 | 91视频在线观看 | 久久国产麻豆 | 2018国产大陆天天弄 | 欧美激情在线精品一区二区三区 | 午夜影院普通用户体验区 | 激情五月综合 | 国产999精品久久久久久 | 日日日操 | 欧美日韩国产在线 | 日本人和亚洲人zjzjhd | 久久久精彩视频 | 免费簧片视频 | 视频一二三区 | 久久er99热精品一区二区 |