MySQL因大事務(wù)導(dǎo)致的Insert慢實(shí)例分析
【問(wèn)題】
INSERT語(yǔ)句是最常見的SQL語(yǔ)句之一,最近有臺(tái)MySQL服務(wù)器不定時(shí)的會(huì)出現(xiàn)并發(fā)線程的告警,從記錄信息來(lái)看,有大量insert的慢查詢,執(zhí)行幾十秒,等待flushing log,狀態(tài)query end

【初步分析】
從等待資源來(lái)看,大部分時(shí)間消耗在了innodb_log_file階段,懷疑可能是磁盤問(wèn)題導(dǎo)致,經(jīng)過(guò)排查沒有發(fā)現(xiàn)服務(wù)器本身存在硬件問(wèn)題

后面開啟線程上升時(shí)pstack的自動(dòng)采集,定位MySQL線程等待的位置。
【分析過(guò)程】
部署了pstack的自動(dòng)抓取后,出現(xiàn)過(guò)6次thread concurrency >=50的告警(每次告警時(shí)會(huì)有大量的慢查詢產(chǎn)生),有3次抓到了現(xiàn)場(chǎng)。
并發(fā)線程升高時(shí),有50多個(gè)線程卡在Stage_manager::enroll_for函數(shù),處于group commit階段


線程0x519c5940對(duì)應(yīng)的SQL語(yǔ)句如下,已經(jīng)執(zhí)行18秒

Stage_manager::enroll_for函數(shù)的作用實(shí)現(xiàn)了多個(gè)線程在flush_stage階段的排隊(duì)。簡(jiǎn)單來(lái)說(shuō),對(duì)于一個(gè)分組的事務(wù),是被leader線程去提交的,其他線程處于排隊(duì)等待狀態(tài),等待leader線程將該線程的事務(wù)提交完成。
如果第一個(gè)線程執(zhí)行慢,后面的線程都處于等待狀態(tài),整組事務(wù)無(wú)法提交。

流程也可以理解如下,
Session A COMMIT-->拿到鎖-->進(jìn)行binlog寫-->commit完成
Session B COMMIT-->等待鎖--------------------------->拿到鎖-->進(jìn)行binlog寫-->commit完成
第一個(gè)線程為什么執(zhí)行很慢,分析了發(fā)生告警時(shí)間段的日志文件,發(fā)現(xiàn)日志中存在2個(gè)15M和20M的大事務(wù)

查看日志明細(xì),存在delete from的大事務(wù)刪除語(yǔ)句,約包含23W條記錄,ROW模式下刪除23W條記錄,會(huì)產(chǎn)生大約20M的日志文件,刷盤時(shí)間較長(zhǎng),阻塞了同一個(gè)分組下其他事務(wù)的提交。

事務(wù)的開始時(shí)間與告警時(shí)間吻合
積壓的分組下事務(wù)集中刷盤,反應(yīng)到磁盤指標(biāo)上可以看到在問(wèn)題時(shí)間段的disk_write_kbytes指標(biāo)出現(xiàn)明顯的上升

【優(yōu)化方案】
1、 建議開發(fā)避免使用delete from 整表的大事務(wù)刪除語(yǔ)句
【其他變通方案】
2、 Binlog 記錄的ROW模式下會(huì)產(chǎn)生大量的日志,改為MIXED模式,理論上也可以解決問(wèn)題
3、 更換性能好的磁盤
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
MySQL刪除表時(shí)I/O錯(cuò)誤的原因分析與解決
這篇文章主要給大家介紹了關(guān)于MySQL刪除表時(shí)I/O錯(cuò)誤的原因分析與解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
十個(gè)實(shí)用且簡(jiǎn)單的MySQL函數(shù)
本文給大家分享了十個(gè)實(shí)用且簡(jiǎn)單的MySQL函數(shù),需要的朋友可以參考下2018-01-01
MySQL使用GROUP?BY使用技巧和注意事項(xiàng)總結(jié)
GROUP?BY?子句是?在MySQL?中用于將查詢結(jié)果按照指定的列或表達(dá)式進(jìn)行分組的關(guān)鍵字,它通常與聚合函數(shù)一起使用,能夠?qū)γ總€(gè)分組進(jìn)行統(tǒng)計(jì)或計(jì)算,本文給大家總結(jié)了MySQL使用GROUP?BY使用技巧和注意事項(xiàng),需要的朋友可以參考下2024-05-05
為什么代碼規(guī)范要求SQL語(yǔ)句不要過(guò)多的join
SQL中的join可以根據(jù)某些條件把指定的表給結(jié)合起來(lái)并將數(shù)據(jù)返回給客戶端,那么在項(xiàng)目開發(fā)中如果需要使用join語(yǔ)句,如何優(yōu)化提升性能?本文就來(lái)詳細(xì)的介紹一下2021-06-06
使MySQL查詢區(qū)分大小寫的實(shí)現(xiàn)方法
我們?cè)贛ySQL中使用SELECT語(yǔ)句查詢時(shí),可不可以使查詢區(qū)分大小寫?今天從網(wǎng)絡(luò)上找到了方法,現(xiàn)總結(jié)如下。2010-12-12
Windows安裝MySQL后怎么開啟root的網(wǎng)絡(luò)訪問(wèn)權(quán)限
Windows安裝MySQL后默認(rèn)只能本機(jī)訪問(wèn),怎么開啟網(wǎng)絡(luò)訪問(wèn),本文給大家介紹介紹了Windows安裝MySQL后怎么開啟root的網(wǎng)絡(luò)訪問(wèn)權(quán)限,需要的朋友可以參考下2023-08-08

