最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析MySQL中主從延遲問(wèn)題的原因與解決方法

 更新時(shí)間:2024年02月28日 09:44:35   作者:DaveCui  
這篇文章主要帶大家從一個(gè)主從延遲問(wèn)題開始回顧主從復(fù)制原理,并思考主從延遲造成的原因和解決方案,文中的示例代碼講解詳細(xì),感興趣的可以了解下

從一個(gè)主從延遲問(wèn)題開始回顧主從復(fù)制原理,并思考主從延遲造成的原因和解決方案。當(dāng)然,作為底層開發(fā),最后還是只能快準(zhǔn)狠的通過(guò)一個(gè)簡(jiǎn)單粗暴的等待方案進(jìn)行應(yīng)對(duì)。

事情的起因

事情要從我寫下這樣的代碼開始

// 獲取當(dāng)前數(shù)據(jù)庫(kù)中未使用的數(shù)據(jù)轉(zhuǎn)為正在使用的狀態(tài)
int updateUsing = fateDataDao.update(FateDataStatusEnum.UNUSED.getCode(),FateDataStatusEnum.USING.getCode());
log.info("update UNUSED to USING:{}",updateUsing);
// 獲取正在使用狀態(tài)的數(shù)據(jù)
List<FateData> fateDataList = fateService.queryStatus(FateDataStatusEnum.USING.getCode());
log.info("queryStatus USING:{}",fateDataList.size());

這部分邏輯清晰簡(jiǎn)單明了,把UNUSED狀態(tài)的數(shù)據(jù)更新為USING狀態(tài),然后查詢?nèi)〕?strong>USING狀態(tài)的數(shù)據(jù)。

按照一個(gè)正常的邏輯來(lái)說(shuō)updateUsing的數(shù)量和fateDataList.size()的數(shù)量應(yīng)該一樣,但是,他不正常。

我在測(cè)試環(huán)境小數(shù)據(jù)量測(cè)試時(shí),這段代碼邏輯完全無(wú)誤。但是上了灰度環(huán)境進(jìn)行大量數(shù)據(jù)的測(cè)試就出現(xiàn)了這樣的問(wèn)題。

此時(shí),我?guī)е苫蠛筒唤?,將目光投向百度?/p>

首先我認(rèn)為問(wèn)題可能好似,MYSQL更新返回的是查詢到的行數(shù),而不是受影響的行數(shù)。

但是負(fù)責(zé)MYSQL的同事和我說(shuō)MYSQL已經(jīng)配置了返回受影響行數(shù),并告訴我應(yīng)該是主從延遲問(wèn)題,沒(méi)辦法解決,看看業(yè)務(wù)能不能改下吧。

這時(shí),我才反應(yīng)過(guò)來(lái)當(dāng)時(shí)粗略了解的主從延遲問(wèn)題,我已經(jīng)忘的差不多了。

什么是主從復(fù)制

要了解主從延遲,首先就要知道什么是主從復(fù)制。

MySQL的主從復(fù)制(Master-Slave Replication)是一種數(shù)據(jù)庫(kù)復(fù)制技術(shù),用于解決數(shù)據(jù)備份、讀寫分離、負(fù)載均衡以及故障恢復(fù)等問(wèn)題。

主從復(fù)制的基本原理是將一個(gè)數(shù)據(jù)庫(kù)實(shí)例(主服務(wù)器)的數(shù)據(jù)復(fù)制到另一個(gè)或多個(gè)數(shù)據(jù)庫(kù)實(shí)例(從服務(wù)器),使得從服務(wù)器的數(shù)據(jù)與主服務(wù)器保持同步。

主從復(fù)制的基本工作流程

  • 從服務(wù)器連接到主服務(wù)器,生成兩個(gè)線程,一個(gè)I/O線程,一個(gè)SQL線程
  • 主服務(wù)器記錄所有的數(shù)據(jù)更改(INSERT、UPDATE、DELETE),同時(shí)會(huì)生成一個(gè) log dump 線程,用來(lái)給從庫(kù) i/o線程傳binlog。
  • 主服務(wù)器會(huì)生成一個(gè) log dump 線程將binlog寫到relay log(中繼日志) 文件中
  • 從服務(wù)器的SQL 線程會(huì)讀取relay log文件中的日志,并解析成具體操作,來(lái)實(shí)現(xiàn)主從的操作一致,而最終數(shù)據(jù)一致;

流程圖如下:

主從復(fù)制解決的問(wèn)題

要用到主從復(fù)制的原因主要是為了高可用、高并發(fā)

  • 數(shù)據(jù)備份和恢復(fù): 從服務(wù)器可以用作主服務(wù)器的備份,當(dāng)主服務(wù)器發(fā)生故障時(shí),可以快速切換到從服務(wù)器進(jìn)行恢復(fù)。
  • 讀寫分離: 主服務(wù)器負(fù)責(zé)寫操作,而從服務(wù)器可以用于處理讀操作,從而分擔(dān)主服務(wù)器的負(fù)載,提高系統(tǒng)性能。
  • 負(fù)載均衡: 多個(gè)從服務(wù)器可以平均分擔(dān)讀請(qǐng)求,實(shí)現(xiàn)負(fù)載均衡,提高系統(tǒng)的可伸縮性。
  • 高可用性: 當(dāng)主服務(wù)器故障時(shí),可以快速切換到一個(gè)從服務(wù)器,保證系統(tǒng)的高可用性。

主從復(fù)制帶來(lái)的問(wèn)題

主從復(fù)制也會(huì)造成一些衍生出的問(wèn)題:

  • 數(shù)據(jù)一致性: 主從復(fù)制是異步的,存在一定的延遲,因此在進(jìn)行讀寫分離時(shí),需要注意可能出現(xiàn)的數(shù)據(jù)一致性問(wèn)題。
  • 寫操作集中: 所有寫操作都集中在主服務(wù)器上,可能導(dǎo)致主服務(wù)器的負(fù)載較高。
  • 配置和維護(hù): 操作復(fù)雜,需要正確配置主從服務(wù)器,以及定期進(jìn)行監(jiān)控和維護(hù),確保系統(tǒng)正常運(yùn)行。

本次遇到的bug,主要就是數(shù)據(jù)一致性方面的問(wèn)題了。

主從延遲的原因

主庫(kù)使用單線程順序?qū)懭隻inlog,效率很高。然而從庫(kù)的SQL Thread線程需要對(duì)主庫(kù)的日志進(jìn)行隨機(jī)IO來(lái)重新執(zhí)行DML和DDL,效率較低,難以跟上主庫(kù)日志寫入速度,因此產(chǎn)生了主從延遲。

另外,從庫(kù)SQL Thread也是單線程,當(dāng)主庫(kù)并發(fā)較高時(shí),產(chǎn)生大量DML,超過(guò)了從庫(kù)單線程能處理的速度,或者從庫(kù)中有大查詢語(yǔ)句產(chǎn)生鎖等待,也會(huì)導(dǎo)致從庫(kù)執(zhí)行延遲,無(wú)法跟上主庫(kù)的進(jìn)度。

主從延遲的解決方案

從主從延遲的原因,我們定位出主要是主庫(kù)的高并發(fā)和從庫(kù)的SQL Thread效率低造成了這樣的問(wèn)題。

所以,在不增加機(jī)器的情況下的解決方案就是控制主庫(kù)的并發(fā)或者提升從庫(kù)的SQL Thread處理效率,例如MySQL 5.6 版本后,提供的一種多線程的方式。

簡(jiǎn)單粗暴的解決方案

當(dāng)然,對(duì)于我們公司的底層開發(fā)來(lái)說(shuō),這種層次的設(shè)計(jì)需要更高層面的人來(lái)推動(dòng),而且也需要更長(zhǎng)的時(shí)間才能處理。

所以這里貼出我自己的解決方案。Thread.sleep時(shí)間請(qǐng)自行控制。

// 獲取當(dāng)前數(shù)據(jù)庫(kù)中未使用的數(shù)據(jù)轉(zhuǎn)為正在使用的狀態(tài)
int updateUsing = fateDataDao.update(FateDataStatusEnum.UNUSED.getCode(),FateDataStatusEnum.USING.getCode());
LOGGER.info("update UNUSED to USING:{}",updateUsing);
// 獲取正在使用狀態(tài)的數(shù)據(jù)
List<FateData> fateDataList = fateService.queryStatus(FateDataStatusEnum.USING.getCode());
LOGGER.info("queryStatus USING:{}",fateDataList.size());
// 如果數(shù)據(jù)相等,直接略過(guò)。
if(updateUsing != fateDataList.size()){
    // updateUsing為0,但fateDataList不為空的情況。任務(wù)失敗,未更新
    if (updateUsing == 0){
        Cat.logEvent("updateTmpData","jobFailed:"+"updateUsing:"+updateUsing+"--fateDataList:"+fateDataList.size());
        transaction.setStatus(Transaction.SUCCESS);
        return response;
    }
    // 數(shù)據(jù)數(shù)目不相等,等待三秒相等再繼續(xù)
    boolean equalFlag = false;
    while(!equalFlag){
        // 等待主從延遲
        Thread.sleep(3000);
        fateDataList = fateService.queryStatus(FateDataStatusEnum.USING.getCode());
        Cat.logEvent("updateTmpData","equalFailed:"+"updateUsing:"+updateUsing+"--fateDataList:"+fateDataList.size());
        LOGGER.info("queryStatus USING:{}",fateDataList.size());
        equalFlag = true;
    }

    // 數(shù)據(jù)數(shù)目不相等,則需要數(shù)據(jù)不為空再繼續(xù)
    while(fateDataList.isEmpty()){
        // 等待主從延遲
        Thread.sleep(1000);
        fateDataList = fateService.queryStatus(FateDataStatusEnum.USING.getCode());
        Cat.logEvent("updateTmpData","queryFailed:"+"updateUsing:"+updateUsing+"--fateDataList:"+fateDataList.size());
        LOGGER.info("queryStatus USING:{}",fateDataList.size());
    }
}

知識(shí)補(bǔ)充

Mybatis使用<update>標(biāo)簽怎么返回影響行數(shù)

Mybatis使用<update>標(biāo)簽怎么返回影響行數(shù)

在MyBatis Plus中,使用<update>標(biāo)簽執(zhí)行更新操作時(shí),默認(rèn)情況下是不返回影響行數(shù)的。但是可以通過(guò)配置來(lái)實(shí)現(xiàn)返回影響行數(shù)的功能。
在MyBatis Plus的配置文件(通常是mybatis-plus-config.xml)中,可以添加如下配置項(xiàng):

<configuration>
  <settings>
    <setting name="returnAffectedCount" value="true"/>
  </settings>
</configuration>

通過(guò)設(shè)置returnAffectedCount為true,可以讓MyBatis Plus在執(zhí)行更新操作后返回影響行數(shù)。

另外,如果只需要獲取更新操作的影響行數(shù)而不需要返回具體的更新結(jié)果,可以使用MyBatis Plus提供的UpdateWrapper或者LambdaUpdateWrapper來(lái)進(jìn)行更新操作,并通過(guò)調(diào)用相應(yīng)的方法獲取影響行數(shù)。例如:

UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("age", 25);
int affectedCount = userMapper.update(null, updateWrapper);

在上述示例中,使用了UpdateWrapper.eq()方法指定了更新條件,并通過(guò)調(diào)用userMapper.update()方法執(zhí)行更新操作,并返回影響行數(shù)。

總結(jié)起來(lái),在MyBatis Plus中使用<update>標(biāo)簽執(zhí)行更新操作時(shí),默認(rèn)情況下是不返回影響行數(shù)的。但可以通過(guò)配置來(lái)實(shí)現(xiàn)返回影響行數(shù)的功能,或者使用UpdateWrapper或者LambdaUpdateWrapper來(lái)獲取影響行數(shù)。

到此這篇關(guān)于淺析MySQL中主從延遲問(wèn)題的原因與解決方法的文章就介紹到這了,更多相關(guān)MySQL主從延遲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL左聯(lián)多表查詢where條件寫法示例

    MySQL左聯(lián)多表查詢where條件寫法示例

    這篇文章主要介紹了MySQL左聯(lián)多表查詢where條件寫法示例,本文直接給出寫法示例,需要的朋友可以參考下
    2015-02-02
  • MySQL數(shù)據(jù)庫(kù)必備之條件查詢語(yǔ)句

    MySQL數(shù)據(jù)庫(kù)必備之條件查詢語(yǔ)句

    當(dāng)用戶查看表格的大量數(shù)據(jù)是,由于數(shù)據(jù)量過(guò)于巨大會(huì)導(dǎo)致很難獲取到需要的數(shù)據(jù),在這時(shí),就需要一個(gè)方法,一個(gè)可以通過(guò)用戶輸入獲取到用戶需要的數(shù)據(jù)并回填入表格,這就是條件查詢的作用
    2021-10-10
  • Mysql中varchar長(zhǎng)度設(shè)置方法

    Mysql中varchar長(zhǎng)度設(shè)置方法

    這篇文章主要介紹了Mysql中varchar長(zhǎng)度設(shè)置方法的相關(guān)資料,本文還給大家?guī)?lái)了valar類型的變化及char()和varchar()的區(qū)別介紹,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • mysql本地安裝過(guò)程詳解

    mysql本地安裝過(guò)程詳解

    本文詳細(xì)介紹了在Windows、macOS和Linux(Ubuntu)三大主流系統(tǒng)下MySQL的本地安裝流程、配置步驟和常見(jiàn)問(wèn)題解決方法,適合新手快速上手并順利完成環(huán)境搭建與基本驗(yàn)證
    2025-10-10
  • MySQL函數(shù)講解(MySQL函數(shù)大全)

    MySQL函數(shù)講解(MySQL函數(shù)大全)

    MySQL函數(shù)大全和函數(shù)講解,管理MYSQL數(shù)據(jù)一定會(huì)用到
    2013-11-11
  • MySQL字符串轉(zhuǎn)數(shù)字的3種方式實(shí)例

    MySQL字符串轉(zhuǎn)數(shù)字的3種方式實(shí)例

    這篇文章主要給大家介紹了關(guān)于MySQL字符串轉(zhuǎn)數(shù)字的3種方式,在使用mysql中經(jīng)常遇到要將字符串?dāng)?shù)字轉(zhuǎn)換成可計(jì)算數(shù)字,文中給出了詳細(xì)的代碼示例和圖文介紹,需要的朋友可以參考下
    2023-08-08
  • MYSQL中DML與DDL常用語(yǔ)句小結(jié)

    MYSQL中DML與DDL常用語(yǔ)句小結(jié)

    DML是一類用于查詢和操作數(shù)據(jù)的 SQL 語(yǔ)句,DDL是一類用于定義和管理數(shù)據(jù)庫(kù)結(jié)構(gòu)及對(duì)象的 SQL 語(yǔ)句,本文為大家整理了一些DML與DDL的常用語(yǔ)句,希望對(duì)大家有所幫助
    2023-12-12
  • MySQL中的三大日志用法及分析

    MySQL中的三大日志用法及分析

    這篇文章主要介紹了MySQL中的三大日志用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • mysql 計(jì)算函數(shù)詳情

    mysql 計(jì)算函數(shù)詳情

    這篇文章主要介紹了mysql 計(jì)算函數(shù),函數(shù)沒(méi)有SQL的可移植性強(qiáng) 能運(yùn)行在多個(gè)系統(tǒng)上的代碼稱為可移植的(portable)。相對(duì)來(lái)說(shuō),多數(shù)SQL語(yǔ)句是可移植的,在SQL實(shí)現(xiàn)之間有差異時(shí),這些差異通常不那么難處理,下面來(lái)看看文章的具體內(nèi)容吧
    2021-10-10
  • WIN10下cmd如何查看編碼方式,命令行窗口修改UTF-8編碼

    WIN10下cmd如何查看編碼方式,命令行窗口修改UTF-8編碼

    這篇文章主要介紹了WIN10下cmd如何查看編碼方式,命令行窗口修改UTF-8編碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09

最新評(píng)論

成武县| 曲靖市| 额济纳旗| 惠东县| 桓仁| 新乡县| 聂拉木县| 龙泉市| 全州县| 保德县| 扬州市| 黄龙县| 罗源县| 丘北县| 景谷| 泗洪县| 青龙| 连江县| 德惠市| 兴化市| 和林格尔县| 西贡区| 永康市| 柘城县| 平阴县| 五大连池市| 南开区| 湾仔区| 上饶县| 盖州市| 琼结县| 蓬安县| 永修县| 娱乐| 满洲里市| 白城市| 溆浦县| 运城市| 榆林市| 历史| 山西省|