溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Mysql?update?sql引起的生產(chǎn)故障怎么解決

發(fā)布時間:2022-04-01 13:39:59 來源:億速云 閱讀:143 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Mysql update sql引起的生產(chǎn)故障怎么解決”,在日常操作中,相信很多人在Mysql update sql引起的生產(chǎn)故障怎么解決問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Mysql update sql引起的生產(chǎn)故障怎么解決”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

故障表現(xiàn)

  • 一方面 :在阿里云控制臺云數(shù)據(jù)庫PolarDB對應(yīng)的集群管理頁面上,在診斷與優(yōu)化模塊里面的一鍵診斷會話管理中,發(fā)現(xiàn)某條update sql 執(zhí)行時間非常久且非常頻繁;

  • 另一方面:業(yè)務(wù)監(jiān)控系統(tǒng)中開始不斷有業(yè)務(wù)執(zhí)行時間發(fā)出告警信息提示,且告警的業(yè)務(wù)數(shù)據(jù)不斷上升,部分操作影響客戶使用。

業(yè)務(wù)背景

由于業(yè)務(wù)操作涉及到的業(yè)務(wù)流比較復(fù)雜,對純技術(shù)的分享來看,不是重點討論的話,為了更有利于理解問題發(fā)生的原因,使用類比的方式,把復(fù)雜的業(yè)務(wù)類比成如下描述: 有數(shù)據(jù)庫3張表,第一張表t_grandfather (爺表),第二張表為t_father(父表),第三張表t_grandson(子孫表),DDL如下:

CREATE TABLE `t_grandfather ` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `count` int(11) NOT NULL DEFAULT 0 COMMENT '子孫后代數(shù)量',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='老爺表';

CREATE TABLE `t_father ` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `grandfather_id` int(11) NOT NULL COMMENT '老爺表id',
  PRIMARY KEY (`id`),
  KEY `idx_grandfather_id` (`grandfather_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='老爸表';

CREATE TABLE `t_grandson` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `grandfather_id` int(11) NOT NULL COMMENT '老爺表id',
  PRIMARY KEY (`id`),
  KEY `idx_grandfather_id` (`grandfather_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='孫子表';

三張表之間的業(yè)務(wù)邏輯關(guān)系為,先生成老爺表,然后這個老爺取很多老婆(業(yè)務(wù)),會不斷的生娃,生一個娃就會生成一張老爸表,同時會更新老爺表的count=count+1,表示新增一個后代了,老爺?shù)睦掀牛I(yè)務(wù))在不斷的生娃的時候,之前的生的娃也會有老婆,他們的老婆也會生娃,對老爺來說,就是它有了孫子(產(chǎn)生新的業(yè)務(wù)數(shù)據(jù)),那有了孫子之后也需要更新老爺表的count=count+1,表示新增一個后代了,以此類推,子子孫孫無窮盡也(業(yè)務(wù)數(shù)據(jù)不斷生成) 如下圖所示:

Mysql?update?sql引起的生產(chǎn)故障怎么解決

祖?zhèn)鞔a的邏輯為,只要是t_father表和t_grandson有新增,就去更新t_grandfather。這個邏輯設(shè)計上問題不大,不過考慮到孫子表數(shù)據(jù)量很猛的時候,這里就會出現(xiàn)一個非常嚴(yán)重的性能問題。以下是業(yè)務(wù)摘取的一部分偽代碼

 /**
 * 處理 father 的業(yè)務(wù)
 */
 public void doFatherBusiness  (){
     //do fatherBusiness baba .... 此處省
     // 插入 t_father 表
    if (fatherMapper.inster(father)){
         //update t_grandfather set count=count+1 where id= #{grandfatherId}
         grandfatherMapper.updateCount(father.getGrandfatherId  ())  ;
     }
}


 /**
 * 處理 grandson 的業(yè)務(wù)
 */
 public void doGrandsonBusiness  (){
     //do grandson baba .... 此處省略
     // 插入 t_grandson 表
     if(grandsonMapper.inster(grandson)){
          //update t_grandfather set count=count+1 where id= #{grandfatherId}
          grandfatherMapper.updateCount(grandson.getGrandfatherId());
     }
}

當(dāng)多個業(yè)務(wù)(線程)分別調(diào)用上面的方法時,都會對t_grandfather表的更新操作造成巨大的壓力,特別是更新同一個id的情況下,mysql server內(nèi)部對鎖的競爭非常激烈。最后表現(xiàn)出來就如前文背景描述的一致。

解決方案

1. 臨時處理方案:

一方面,在阿里云控制臺,對sql進(jìn)行限流,在正常阻塞的會話,強(qiáng)制kill掉,讓數(shù)據(jù)的線程不阻塞著,釋放資源,另外一方面,在把接收請求的服務(wù)減少節(jié)點數(shù),目的是減少業(yè)務(wù)數(shù)據(jù)量進(jìn)入;

2. 長久方案

一方面更改掉上面的業(yè)務(wù)邏輯,插入t_grandson表和t_father表時,不在去更新t_grandfather表的count字段;另一方面,需要用到count統(tǒng)計需求時,全部切換成別的方式;

到此,關(guān)于“Mysql update sql引起的生產(chǎn)故障怎么解決”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI