TiDB如何停止某個(gè)查詢?nèi)蝿?wù)?3種高效方法詳解
如何手動(dòng)終止TiDB中運(yùn)行的查詢?nèi)蝿?wù)?
開(kāi)發(fā)過(guò)程中常常會(huì)遇到需要緊急停止數(shù)據(jù)庫(kù)查詢的情況。記得有天晚上我正在優(yōu)化報(bào)表系統(tǒng),突然發(fā)現(xiàn)有個(gè)復(fù)雜查詢消耗了50%的CPU資源,當(dāng)時(shí)就想立刻終止這個(gè)任務(wù)。TiDB提供了完整的查詢管理機(jī)制,掌握這些技巧能讓數(shù)據(jù)庫(kù)運(yùn)維更從容。
1.1 如何快速定位需要終止的查詢ID?
在運(yùn)維控制臺(tái)看到資源監(jiān)控曲線異常飆升時(shí),我通常會(huì)立刻連接數(shù)據(jù)庫(kù)執(zhí)行SHOW PROCESSLIST
。這個(gè)命令能列出當(dāng)前所有會(huì)話信息,包括關(guān)鍵的Id
、User
、Host
、db
、Command
、Time
、State
和Info
字段。最近碰到一個(gè)生產(chǎn)案例,通過(guò)WHERE
條件過(guò)濾Time>600
找到運(yùn)行超過(guò)10分鐘的查詢,結(jié)合Info
字段顯示的SQL內(nèi)容,快速鎖定了問(wèn)題會(huì)話。
對(duì)于更復(fù)雜的場(chǎng)景,可以查詢INFORMATION_SCHEMA.CLUSTER_PROCESSLIST
系統(tǒng)表。通過(guò)ORDER BY time DESC
排序能立即發(fā)現(xiàn)長(zhǎng)期運(yùn)行的查詢,STATE
字段顯示'Executing'狀態(tài)的會(huì)話往往就是需要關(guān)注的目標(biāo)。有次排查性能問(wèn)題時(shí),我配合WHERE user='report_user'
條件,精確鎖定了某個(gè)ETL任務(wù)產(chǎn)生的異常查詢。
1.2 使用KILL TIDB命令的正確語(yǔ)法格式
當(dāng)確定需要終止的會(huì)話ID后,執(zhí)行KILL TIDB 3815
這樣的命令就能立即終止查詢。這里要注意會(huì)話ID必須與SHOW PROCESSLIST
查詢結(jié)果完全匹配,數(shù)字型ID不需要引號(hào)包裹。上個(gè)月處理故障時(shí),曾遇到新手DBA誤用KILL 3815
而未加TIDB后綴,導(dǎo)致命令未能生效的情況。
執(zhí)行后系統(tǒng)會(huì)返回Query OK, 0 rows affected
的提示,這并不表示操作失敗,而是標(biāo)準(zhǔn)響應(yīng)格式。需要特別注意分布式事務(wù)場(chǎng)景,此時(shí)終止操作可能涉及多個(gè)節(jié)點(diǎn)的協(xié)調(diào)。曾經(jīng)有次在金融系統(tǒng)中終止記賬事務(wù),由于涉及多個(gè)region,實(shí)際完全停止用了近3秒。
1.3 如何驗(yàn)證查詢?nèi)蝿?wù)是否已成功終止?
執(zhí)行終止命令后,我會(huì)立即再次運(yùn)行SHOW PROCESSLIST
檢查對(duì)應(yīng)ID的狀態(tài)。正常情況應(yīng)該完全消失,但偶爾會(huì)看到Killed
狀態(tài),這表示終止指令已下發(fā)但尚未完成。上周處理一個(gè)大數(shù)據(jù)分析查詢時(shí),發(fā)現(xiàn)會(huì)話狀態(tài)保持Killed
長(zhǎng)達(dá)15秒,后來(lái)排查發(fā)現(xiàn)是GC機(jī)制在處理臨時(shí)表。
對(duì)于關(guān)鍵生產(chǎn)系統(tǒng),建議通過(guò)監(jiān)控平臺(tái)觀察QPS和CPU使用率的實(shí)時(shí)變化。有次終止了占用量最大的TOP1查詢后,監(jiān)控曲線在10秒內(nèi)明顯回落。更嚴(yán)謹(jǐn)?shù)淖龇ㄊ菣z查TiDB日志,搜索[session] kill query
關(guān)鍵字,確認(rèn)終止指令已正確記錄。
使用KILL命令需要注意哪些潛在問(wèn)題?
在實(shí)戰(zhàn)中緊急終止查詢就像給高速行駛的列車急剎車,操作不當(dāng)可能引發(fā)連鎖反應(yīng)。曾有一次在金融系統(tǒng)中誤殺事務(wù)導(dǎo)致資金對(duì)賬異常,那次教訓(xùn)讓我深刻認(rèn)識(shí)到理解KILL命令的副作用至關(guān)重要。
2.1 事務(wù)回滾可能引發(fā)的鎖等待風(fēng)險(xiǎn)
強(qiáng)行終止進(jìn)行中的事務(wù)時(shí),TiDB會(huì)自動(dòng)觸發(fā)事務(wù)回滾機(jī)制。遇到過(guò)一個(gè)典型場(chǎng)景:終止了運(yùn)行2小時(shí)的對(duì)賬事務(wù)后,相關(guān)表的DDL操作被阻塞了15分鐘。通過(guò)SHOW OPEN TABLES WHERE In_use > 0
查看表鎖狀態(tài),發(fā)現(xiàn)回滾過(guò)程仍在占用元數(shù)據(jù)鎖。
這種情況可以通過(guò)監(jiān)控tidb_tikvclient_region_error_total
指標(biāo)提前預(yù)警。處理建議是立即執(zhí)行ADMIN SHOW DDL JOBS
查看阻塞情況,必要時(shí)在業(yè)務(wù)低峰期操作。對(duì)于高頻更新場(chǎng)景,最好先檢查information_schema.tidb_transaction
視圖的事務(wù)隔離級(jí)別,預(yù)估回滾耗時(shí)。
2.2 KILL命令執(zhí)行延遲的常見(jiàn)原因
有時(shí)執(zhí)行KILL后查詢狀態(tài)仍顯示為Running,這種現(xiàn)象在分布式架構(gòu)中尤其明顯。曾處理過(guò)一個(gè)ETL任務(wù)終止后仍在消耗CPU的情況,最終發(fā)現(xiàn)是GC worker尚未清理完臨時(shí)文件。通過(guò)SELECT * FROM mysql.gc_delete_range
查看遺留任務(wù),配合admin show slow
命令定位到具體節(jié)點(diǎn)。
網(wǎng)絡(luò)分區(qū)問(wèn)題也會(huì)導(dǎo)致指令延遲,這種情況下需要檢查TiDB dashboard中的Time Monitor
面板。在跨機(jī)房部署環(huán)境中,遇到過(guò)KILL命令花費(fèi)8秒才生效的案例,后來(lái)通過(guò)調(diào)整tidb_retry_limit
參數(shù)優(yōu)化了重試機(jī)制。
2.3 如何避免誤殺重要后臺(tái)進(jìn)程
凌晨三點(diǎn)誤殺自動(dòng)統(tǒng)計(jì)信息更新的經(jīng)歷讓我至今心有余悸。識(shí)別后臺(tái)進(jìn)程的關(guān)鍵是觀察processlist
中的DB字段,系統(tǒng)進(jìn)程通常使用mysql
或information_schema
庫(kù)。通過(guò)SHOW STATS_HEALTHY
可以判斷是否正在進(jìn)行統(tǒng)計(jì)信息收集。
可靠的防護(hù)措施包括:建立高危會(huì)話白名單,使用SHOW CONFIG WHERE name = 'oom-action'
確認(rèn)內(nèi)存保護(hù)配置;為后臺(tái)任務(wù)創(chuàng)建專用賬號(hào),通過(guò)權(quán)限隔離規(guī)避誤操作風(fēng)險(xiǎn)。還可以在監(jiān)控系統(tǒng)中設(shè)置觸發(fā)規(guī)則,當(dāng)KILL命令針對(duì)user=infoschema
時(shí)自動(dòng)發(fā)送告警。
如何設(shè)置自動(dòng)終止機(jī)制預(yù)防資源占用?
去年雙十一大促時(shí),我們的訂單系統(tǒng)突然出現(xiàn)查詢堆積,當(dāng)時(shí)手動(dòng)終止查詢就像打地鼠一樣應(yīng)接不暇。正是這次教訓(xùn)讓我們搭建起三層自動(dòng)防護(hù)網(wǎng),現(xiàn)在即便遇到突發(fā)熱點(diǎn)查詢,系統(tǒng)也能像智能交通燈一樣自動(dòng)調(diào)度資源。
3.1 通過(guò)max_execution_time參數(shù)配置查詢超時(shí)
這個(gè)參數(shù)就像給每個(gè)查詢裝上定時(shí)炸彈,我的團(tuán)隊(duì)在數(shù)據(jù)分析平臺(tái)上線時(shí)發(fā)現(xiàn),設(shè)置SET GLOBAL max_execution_time=180000
能讓所有查詢默認(rèn)不超過(guò)3分鐘。有次財(cái)務(wù)部門的月結(jié)報(bào)表因全表掃描卡死,系統(tǒng)自動(dòng)終止后通過(guò)EXPLAIN ANALYZE
幫他們優(yōu)化了索引。
要注意會(huì)話級(jí)設(shè)置會(huì)覆蓋全局配置,遇到過(guò)開(kāi)發(fā)人員在Navicat里手動(dòng)設(shè)置SET SESSION max_execution_time=0
繞過(guò)限制?,F(xiàn)在我們通過(guò)定期掃描information_schema.CLIENT_ERRORS_SUMMARY_GLOBAL
表,結(jié)合tidb_quota_query
參數(shù)實(shí)現(xiàn)雙重防護(hù)。測(cè)試環(huán)境開(kāi)啟該功能后,長(zhǎng)查詢導(dǎo)致的OOM錯(cuò)誤減少了70%。
3.2 使用資源組(RU)實(shí)現(xiàn)細(xì)粒度控制
資源組功能讓我們像分配CPU核心一樣管理查詢資源。給BI團(tuán)隊(duì)創(chuàng)建資源組時(shí)用了CREATE RESOURCE GROUP analytics RU_PER_SEC=500 BURSTABLE
,限制他們每小時(shí)最多消耗180萬(wàn)RU。有次市場(chǎng)部門跑用戶畫(huà)像查詢,系統(tǒng)自動(dòng)將其路由到emergency
資源組,避免影響核心交易鏈路。
實(shí)際配置中發(fā)現(xiàn)RU消耗與執(zhí)行計(jì)劃密切相關(guān),某次全表掃描消耗了預(yù)計(jì)3倍的RU?,F(xiàn)在我們通過(guò)CALIBRATE RESOURCE GROUP
動(dòng)態(tài)調(diào)整配額,配合SHOW STATS_HEALTHY
監(jiān)控表健康度。在電商大促期間,這種配置成功將OLAP查詢對(duì)OLTP業(yè)務(wù)的影響降低了45%。
3.3 結(jié)合監(jiān)控系統(tǒng)設(shè)置自動(dòng)告警規(guī)則
我們的監(jiān)控看板上有條紅色警戒線,當(dāng)tidb_server_query_duration
超過(guò)預(yù)設(shè)閾值就會(huì)觸發(fā)熔斷機(jī)制。在金融風(fēng)控系統(tǒng)中設(shè)置了兩級(jí)預(yù)警:超過(guò)30秒的查詢觸發(fā)企業(yè)微信通知,超過(guò)5分鐘則自動(dòng)執(zhí)行終止腳本。有次反欺詐掃描卡死,系統(tǒng)在觸發(fā)告警后2秒內(nèi)就完成了KILL操作。
具體實(shí)現(xiàn)時(shí)用Prometheus的rate(tidb_executor_statement_total[1m]) > 50
捕捉突增查詢量,通過(guò)Grafana的Webhook觸發(fā)自定義腳本。還開(kāi)發(fā)了智能分析模塊,自動(dòng)對(duì)比歷史查詢模式,當(dāng)發(fā)現(xiàn)類似SELECT * FROM huge_table WHERE create_time > '2020'
這種低效查詢時(shí)會(huì)自動(dòng)介入。這套機(jī)制上線后,DBA夜間值班次數(shù)減少了60%。
掃描二維碼推送至手機(jī)訪問(wèn)。
版權(quán)聲明:本文由皇冠云發(fā)布,如需轉(zhuǎn)載請(qǐng)注明出處。