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

詳解如何避免MYSQL主從延遲帶來的讀寫問題

 更新時間:2024年03月10日 09:04:04   作者:藍胖子的編程夢  
當在主庫上進行更新后,有可能數(shù)據(jù)還沒來得及同步到從庫,但是這個時候又有讀數(shù)據(jù)的需求,為了能正確讀取出數(shù)據(jù),這個時候就只有讀主庫了,所以本文給大家介紹了如何避免MYSQL主從延遲帶來的讀寫問題,需要的朋友可以參考下

在MYSQL 部署架構(gòu)選型上,許多公司都會用到主從讀寫分離的架構(gòu),如下是一個一主一從的架構(gòu),主庫master負責(zé)寫入,從庫slave進行讀取。

但是既然是讀寫分離,必然會面臨這樣一個問題,當在主庫上進行更新后,有可能數(shù)據(jù)還沒來得及同步到從庫,但是這個時候又有讀數(shù)據(jù)的需求,為了能正確讀取出數(shù)據(jù),這個時候就只有讀主庫了。但是這樣做增加了主庫的壓力,違反了我們做讀寫分離的初衷。所以這一節(jié)我們就來針對這種情況探討下,如何盡量的避免對主庫的壓力,盡量的從從庫讀取數(shù)據(jù)。

主從復(fù)制的原理

在探討解決方案前,我們先要對主從復(fù)制的原理有所了解,數(shù)據(jù)庫的操作都會記錄到binlog,如下圖所示,

1,從數(shù)據(jù)庫(slave)會啟動兩個線程io_threadsql_thread ,通過io_thread將自身與主數(shù)據(jù)庫(master)建立連接。

2,slave向master發(fā)出要同步的位置信息(包含同步的文件名和偏移量),表示需要從該位置發(fā)起同步。

3,主數(shù)據(jù)庫master 將位置點后的binlog發(fā)送給slave, slave獲取到本地形成relay log(中轉(zhuǎn)日志)。

4, 接著通過sql_thread解析relay log,執(zhí)行sql。

從主從復(fù)制的過程可以看出,主從延遲時間是 在主庫master執(zhí)行sql的時間點到從庫通過解析relay log 執(zhí)行sql后的時間點之間的差值。如果應(yīng)用程序能夠在master寫入數(shù)據(jù)后等待這么一段時間,再去slave讀取,就能正確的讀取出來數(shù)據(jù)了。

但是這個時間差值是不確定的,究竟應(yīng)用程序需要等待多久才去讀取slave,就成了我們需要思考??的問題。

如何避免延遲期間的主從數(shù)據(jù)不一致

比起在寫入數(shù)據(jù)后讀取主庫或者寫入數(shù)據(jù)后sleep一段時間讀取從庫,我給出兩個我覺得比較靠譜點的方法。

判斷位點是否同步

第一種方法是通過等待slave 將master寫入數(shù)據(jù)后的 binlog的位點同步完成再對slave進行讀取。

每次修改型sql的執(zhí)行會將master的binlog 的位點(日志偏移量)前移,如果在修改型sql執(zhí)行完成后,能夠獲取到master的binlog 位點,并且在客戶端阻塞等待slave同步該位點完畢,再從slave讀取就可以了。

MYSQL中提供了一個函數(shù)select master_pos_wait(file, pos[, timeout]) 用于在slave上執(zhí)行等待master節(jié)點上的位點同步完成,其中file,和pos是在master上的文件和位點,timeout 為了讓master_pos_wait 函數(shù)在timeout秒內(nèi)沒有返回,則會直接觸發(fā)超時返回。

返回結(jié)果解析,

  • 返回結(jié)果正常情況下是一個大于0的整數(shù),表示從pos位點開始完成了多少個事務(wù)。
  • 如果直接返回結(jié)果0,則說明在執(zhí)行select master_pos_wait(file, pos[, timeout]) 時,位點已經(jīng)同步完成。
  • 如果觸發(fā)超時則返回-1。
  • 如果執(zhí)行期間slave發(fā)生錯誤,則返回NULL。

所以,在判斷是否應(yīng)該在寫入數(shù)據(jù)后讀從庫的邏輯,我們可以這樣來寫,

1, 在master寫入數(shù)據(jù)后立馬執(zhí)行 show master status,可以獲取如下結(jié)果

可以看到master的binlog文件名稱以及位點。

2, 在slave上執(zhí)行 select master_pos_wait('mysql-bin.232011',3129472,1);,如果1s內(nèi)沒有返回,則直接返回-1。

3, 在上一步如果觸發(fā)超時返回返回-1,則直接讀取主庫,如果是>=0 的值,則直接讀取從庫。

這樣便能最大程度從從庫讀取數(shù)據(jù)。

判斷GTID 是否同步

接著,我們來看下第二種方式,其實第二種方式和通過位點的方式類似,不同的是slave判斷是否將數(shù)據(jù)同步完成的依據(jù)是看GTID的值。

什么是GTID值?

GTID 的全稱是 Global Transaction Identifier,全局事務(wù) ID,是一個事務(wù)在提交的時候生成的,是這個事務(wù)的唯一標識。

MYSQL開啟 GTID 模式的方式是 在啟動一個 MySQL 實例的時候,加上參數(shù) gtid_mode=onenforce_gtid_consistency=on

每個事務(wù)是和GTID 值一一對應(yīng)的,每個MYSQL實例會維護一個GTID 集合,來表示實例執(zhí)行過的事務(wù)。

在slave節(jié)點上,通過show slave status 可以看到 GTID集合,如下圖所示,

  • Auto_Position=1 ,表示這對主備關(guān)系使用了 GTID 協(xié)議。
  • Retrieved_Gtid_Set,是備庫收到的所有日志的 GTID 集合。
  • Executed_Gtid_Set,是備庫所有已經(jīng)執(zhí)行完成的 GTID 集合。

如果Executed_Gtid_Set 等于Retrieved_Gtid_Set 說明slave將從master那里獲取到的binlog全部執(zhí)行完畢。

在master節(jié)點執(zhí)行 show master status,也能看到GTID集合,Executed_Gtid_Set 為master節(jié)點執(zhí)行過的GTID集合。如下圖所示,

GTID 模式下判斷同步的步驟

在GTID 模式下,從庫slave從主庫master取binlog的邏輯將不再是直接告訴master 要取的文件和位點了,而是由slave將自身的GTID集合告訴master。

master再結(jié)合自身的GTID集合,找出在master中有但是在slave中沒有的GTID集合,然后從binlog中找到第一個不在GTID集合中的事務(wù),從該事務(wù)的binlog位點開始,往后讀取binlog發(fā)送給slave。

MYSQL針對于GTID同樣提供 了一個函數(shù)select wait_for_executed_gtid_set(gtid_set, 1); 來讓slave去判斷對master執(zhí)行過的gtid_set 是否已經(jīng)同步完成。

wait_for_executed_gtid_set 函數(shù)的返回結(jié)果解析如下,

  • 如果slave 執(zhí)行的事務(wù)中包含傳入的 gtid_set,返回 0。
  • 如果等待1s后還沒同步完成,則返回1。

所以在GTID 模式下的,在判斷是否應(yīng)該在寫入數(shù)據(jù)后讀從庫的邏輯,我們可以這樣來寫,

1, 在master寫入數(shù)據(jù)后立馬執(zhí)行 show master status,可以獲取如下結(jié)果

可以看到master的Executed_Gtid_Set的值。

2, 在slave上執(zhí)行

select wait_for_executed_gtid_set('76cd5ea1-c541-11ee-87ef-fa163eefe144:1-56382789,  
808d2fb8-687b-11ec-b8b9-fa163e410530:1-144078103,  
9081c19b-63de-11ed-9755-fa163eb8b97f:1-1093294115', 1);

,如果1s內(nèi)沒有返回,則直接返回1。

3, 在上一步如果觸發(fā)超時即返回1,則直接讀取主庫,如果是=0 ,則直接讀取從庫。 這樣便能最大程度從從庫讀取數(shù)據(jù)。

以上就是詳解如何避免MYSQL主從延遲帶來的讀寫問題的詳細內(nèi)容,更多關(guān)于MYSQL主從延遲的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • mysql修改表結(jié)構(gòu)方法實例詳解

    mysql修改表結(jié)構(gòu)方法實例詳解

    這篇文章主要介紹了mysql修改表結(jié)構(gòu)方法,以實例形式較為詳細的分析了mysql修改表結(jié)構(gòu)的具體方法與相關(guān)注意事項,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • MySQL命令行導(dǎo)出與導(dǎo)入數(shù)據(jù)庫

    MySQL命令行導(dǎo)出與導(dǎo)入數(shù)據(jù)庫

    這篇文章主要為大家詳細介紹了利用命令行MySQL導(dǎo)出數(shù)據(jù)庫與導(dǎo)入數(shù)據(jù)庫的例子,感興趣的小伙伴們可以參考一下
    2016-06-06
  • MySQL外鍵使用及說明詳解

    MySQL外鍵使用及說明詳解

    MySQL通過外鍵約束來保證表與表之間的數(shù)據(jù)的完整性和準確性。這篇文章還通過外鍵的使用條件和外鍵的好處定義語法方面介紹了mysql外鍵使用及說明,非常不錯,具有參考借鑒價值,需要的朋友一起看下吧
    2016-08-08
  • MySQL Limit性能優(yōu)化及分頁數(shù)據(jù)性能優(yōu)化詳解

    MySQL Limit性能優(yōu)化及分頁數(shù)據(jù)性能優(yōu)化詳解

    今天小編就為大家分享一篇關(guān)于MySQL Limit性能優(yōu)化及分頁數(shù)據(jù)性能優(yōu)化詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • MySQL函數(shù)find_in_set場景介紹

    MySQL函數(shù)find_in_set場景介紹

    本文給大家分享MySQL函數(shù)find_in_set場景介紹,結(jié)合實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2025-07-07
  • linux虛擬機安裝mysql實踐

    linux虛擬機安裝mysql實踐

    這篇文章詳細介紹了在Linux系統(tǒng)上安裝MySQL 5.7的步驟,包括創(chuàng)建目錄、上傳文件、創(chuàng)建用戶、更改權(quán)限、安裝依賴、初始化數(shù)據(jù)庫、啟動服務(wù)和修改配置文件等
    2026-02-02
  • MySQL多表之間字段的匹配實現(xiàn)代碼

    MySQL多表之間字段的匹配實現(xiàn)代碼

    本文主要介紹下MySQL多表之間字段的匹配;如tag表中name匹配info中的name,接下來詳細介紹下,感興趣的你可以參考下哈
    2013-03-03
  • MySQL多表查詢詳解下

    MySQL多表查詢詳解下

    這篇文章主要介紹了MySQL多表查詢詳解下,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • php+mysql prepare 與普通查詢的性能對比實例講解

    php+mysql prepare 與普通查詢的性能對比實例講解

    prepare可以解決大訪問量的網(wǎng)站給數(shù)據(jù)庫服務(wù)器所帶來的負載和開銷,本文章通過實例向大家介紹預(yù)查詢prepare與普通查詢的性能對比,需要的朋友可以參考一下
    2016-11-11
  • MySQL中g(shù)tid_purged?的初始化和更新機制詳解

    MySQL中g(shù)tid_purged?的初始化和更新機制詳解

    文章介紹了MySQL中的gtid_purged變量,該變量用于記錄已經(jīng)從磁盤上被清除的二進制日志文件中的事務(wù)的GTID集合,它在服務(wù)器啟動時初始化,本文介紹的非常詳細感興趣的朋友一起看看吧
    2025-12-12

最新評論

监利县| 旌德县| 鄂托克前旗| 宁蒗| 鹤壁市| 柳江县| 乌审旗| 厦门市| 台北市| 满洲里市| 山东省| 肃宁县| 密山市| 广南县| 门头沟区| 遵义县| 东至县| 南召县| 桃园市| 邵东县| 方山县| 利川市| 道孚县| 兴山县| 新绛县| 科尔| 平江县| 永和县| 淮阳县| 称多县| 浙江省| 兰考县| 西乡县| 怀安县| 清水河县| 织金县| 呼图壁县| 凤翔县| 井冈山市| 儋州市| 左权县|