自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

慢查詢導(dǎo)致 MySQL 雪崩,危險可能不止于此……

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

一、背景

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

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

二、解決辦法

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

答案是肯定的,我們可以想想,如果雪崩出現(xiàn)的時候,也就是雪崩引起的故障出現(xiàn)的時候,我們是咋處理故障的?一般情況下,也是通過不斷殺慢查詢的方式來解決問題的,讓擁堵消失,擁堵消失之后,數(shù)據(jù)庫本身的狀態(tài)就平靜了,業(yè)務(wù)就可以繼續(xù)有條不紊的訪問了,所以用同樣的原理,我們?nèi)绻茉诠舱癯霈F(xiàn)之后,第一批慢查詢出現(xiàn)的時候,將其殺掉,這樣可能就能有效避免后續(xù)的雪崩效應(yīng),這樣的推論是沒有問題的。

三、殺慢查詢的方式

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

1. 很難做到常態(tài)化

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

2. 很難做到準(zhǔn)確

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

3. 很難做到自動化

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

4. 很難做到統(tǒng)一化

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

5. DBA 不了解 SQL 語句

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

6. 業(yè)務(wù)沒辦法做決定

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

7. 責(zé)任界定

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

8. 數(shù)據(jù)庫核心是服務(wù)

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

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

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

四、解鈴還須系鈴人

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

1.注冊制

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

2.簽名制

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

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

下面首先講一下設(shè)計細(xì)節(jié):

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

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

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

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

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

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

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

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

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

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

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

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

3.源碼制

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

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

五、總結(jié)

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

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

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

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

作者介紹

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

責(zé)任編輯:張燕妮 來源: dbaplus社群
相關(guān)推薦

2010-02-24 09:53:07

Zaurus Ubun

2016-02-23 17:50:38

認(rèn)知計算IBM

2020-04-25 14:06:04

BGP網(wǎng)絡(luò)攻擊泄露

2020-10-27 16:20:51

人臉識別智能安全物聯(lián)網(wǎng)

2016-12-28 18:07:08

大數(shù)據(jù)大數(shù)據(jù)技術(shù)大數(shù)據(jù)發(fā)展趨勢

2019-11-25 14:06:44

AI無人駕駛自動駕駛

2020-10-27 13:50:58

央視揭AI黑產(chǎn)

2017-06-26 09:40:50

Python代碼寫法

2017-07-07 16:57:35

代碼Python

2020-07-07 15:50:17

區(qū)塊鏈互聯(lián)網(wǎng)人工智能

2017-05-03 09:49:14

OpenStack私有云搭建

2022-07-12 09:36:18

數(shù)據(jù)庫查詢

2022-06-22 16:31:26

阿里云數(shù)字化轉(zhuǎn)型云原生

2022-05-24 15:34:35

Commvault

2018-05-06 23:04:12

Android Chrome OS操作系統(tǒng)

2022-12-22 10:37:53

數(shù)字化自動化UiPath

2022-03-27 23:50:46

云計算邊緣計算技術(shù)
點贊
收藏

51CTO技術(shù)棧公眾號