国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

MySQL 中讀寫分離數據延遲

這篇具有很好參考價值的文章主要介紹了MySQL 中讀寫分離數據延遲。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

  • MySQL 中讀寫分離可能遇到的問題
    • 前言
    • 讀寫分離的架構
      • 基于客戶端實現讀寫分離
      • 基于中間代理實現讀寫分離
    • MySQL 中如何保證主從數據一致
      • 循環(huán)復制問題
    • 主從同步延遲
    • 主從同步延遲的原因
    • 主從延遲如何處理
      • 強制走主庫方案
      • Sleep 方案
      • 判斷主從無延遲方案
      • 配合semi-sync
      • 等主庫位點方案
      • 等 GTID 方案
    • 總結
    • 參考

MySQL 中讀寫分離可能遇到的問題

前言

MySQL 中讀寫分離是經常用到了的架構了,通過讀寫分離實現橫向擴展的能力,寫入和更新操作在源服務器上進行,從服務器中進行數據的讀取操作,通過增大從服務器的個數,能夠極大的增強數據庫的讀取能力。

MySQL 中的高可用架構越已經呈現出越來越復雜的趨勢,但是都是才能夠最基本的一主一從演化而來的,所以這里來弄明白主從的基本原理。

首先來弄明白主從和主備,以及雙主模式之間的區(qū)別

雙主

MySQL 中讀寫分離數據延遲

有兩個主庫,每個主庫都能進行讀寫,并且兩個主庫之間都能進行數據的同步操作。

主從

MySQL 中讀寫分離數據延遲

主從中,數據寫入在主節(jié)點中進行,數據讀取在從節(jié)點中進行,主庫會同步數據到從庫中。

主備

MySQL 中讀寫分離數據延遲

主備,備庫只是用來進行數據備份,沒有讀寫操作的發(fā)生,數據的讀取和寫入發(fā)生在主庫中,主庫會同步數據到備庫中。

下面討論的數據延遲,主要是基于主從模式。主從,主備,雙主數據同步原理一樣,這里不展開分析了。

讀寫分離的架構

常用的讀寫分離有下面兩種實現:

1、客戶端實現讀寫分離;

2、基于中間代理層實現讀寫分離。

基于客戶端實現讀寫分離

客戶端主動做負載均衡,根據 select、insert 進行路由分類,讀請求發(fā)送到讀庫中,寫請求轉發(fā)到寫庫中。

這種方式的特點是性能較好,代碼中直接實現,不需要額外的硬件支持,架構簡單,排查問題更方便。

缺點需要嵌入到代碼中,需要開發(fā)人員去實現,運維無從干預,大型代碼,實現讀寫分離需要改動的代碼比較多。

MySQL 中讀寫分離數據延遲

基于中間代理實現讀寫分離

中間代理層實現讀寫分離,在 MySQL 和客戶端之間有一個中間代理層 proxy,客戶端只連接 proxy, 由 proxy 根據請求類型和上下文決定請求的分發(fā)路由。

MySQL 中讀寫分離數據延遲

帶 proxy 的架構,對客戶端比較友好??蛻舳瞬恍枰P注后端細節(jié),連接維護、后端信息維護等工作,都是由 proxy 完成的。但這樣的話,對后端維護團隊的要求會更高。而且,proxy 也需要有高可用架構。因此,帶 proxy 架構的整體就相對比較復雜。

不過那種部署方式都會遇到讀寫分離主從延遲的問題,因為主從延遲的存在,客戶端剛執(zhí)行完成一個更新事務,然后馬上發(fā)起查詢,如果選擇查詢的是從庫,可能讀取到的狀態(tài)是更新之前的狀態(tài)。

MySQL 中如何保證主從數據一致

MySQL 數據進行主從同步,主要是通過 binlog 實現的,從庫利用主庫上的binlog進行重播,實現主從同步。

來看下實現原理

在主從復制中,從庫利用主庫上的 binlog 進行重播,實現主從同步,復制的過程中蛀主要使用到了 dump thread,I/O thread,sql thread 這三個線程。

IO thread: 在從庫執(zhí)行 start slave 語句時創(chuàng)建,負責連接主庫,請求 binlog,接收 binlog 并寫入 relay-log;

dump thread:用于主庫同步 binlog 給從庫,負責響應從 IO thread 的請求。主庫會給每個從庫的連接創(chuàng)建一個 dump thread,然后同步 binlog 給從庫;

sql thread:讀取 relay log 執(zhí)行命令實現從庫數據的更新。

來看下復制的流程:

1、主庫收到更新命令,執(zhí)行更新操作,生成 binlog;

2、從庫在主從之間建立長連接;

3、主庫 dump_thread 從本地讀取 binlog 傳送剛給從庫;

4、從庫從主庫獲取到 binlog 后存儲到本地,成為 relay log(中繼日志);

5、sql_thread 線程讀取 relay log 解析、執(zhí)行命令更新數據。

需要注意的是

一開始創(chuàng)建主從關系的時候,同步是由從庫指定的。比如基于位點的主從關系,從庫說“我要從 binlog 文件 A 的位置 P ”開始同步, 主庫就從這個指定的位置開始往后發(fā)。

而主從復制關系搭建完成以后,是主庫來決定“要發(fā)數據給從庫”的。只有主庫有新的日志,就會發(fā)送給從庫。

binlog 有三種格式 statement,row 和 mixed。

1、Statement(Statement-Based Replication,SBR):每一條會修改數據的 SQL 都會記錄在 binlog 中,里面記錄的是執(zhí)行的 SQL;

Statement 模式只記錄執(zhí)行的 SQL,不需要記錄每一行數據的變化,因此極大的減少了 binlog 的日志量,避免了大量的 IO 操作,提升了系統(tǒng)的性能。

正是由于 Statement 模式只記錄 SQL,而如果一些 SQL 中包含了函數,那么可能會出現執(zhí)行結果不一致的情況。

比如說 uuid() 函數,每次執(zhí)行的時候都會生成一個隨機字符串,在 master 中記錄了 uuid,當同步到 slave 之后,再次執(zhí)行,就獲取到另外一個結果了。

所以使用 Statement 格式會出現一些數據一致性問題。

2、Row(Row-Based Replication,RBR):不記錄 SQL 語句上下文信息,僅僅只需要記錄某一條記錄被修改成什么樣子;

Row 格式的日志內容會非常清楚的記錄下每一行數據修改的細節(jié),這樣就不會出現 Statement 中存在的那種數據無法被正常復制的情況。

比如一個修改,滿足條件的數據有 100 行,則會把這 100 行數據詳細記錄在 binlog 中。當然此時,binlog 文件的內容要比第一種多很多。

不過 Row 格式也有一個很大的問題,那就是日志量太大了,特別是批量 update、整表 delete、alter 表等操作,由于要記錄每一行數據的變化,此時會產生大量的日志,大量的日志也會帶來 IO 性能問題。

3、Mixed(Mixed-Based Replication,MBR):Statement 和 Row 的混合體。

因為有些 statement 格式的 binlog 可能會導致主從不一致,所以要使用 row 格式。

但 row 格式的缺點是,很占空間。比如你用一個 delete 語句刪掉10萬行數據,用 statement 的話就是一個SQL語句被記錄到binlog中,占用幾十個字節(jié)的空間。但如果用 row 格式的 binlog,就要把這10萬條記錄都寫到 binlog 中。這樣做,不僅會占用更大的空間,同時寫 binlog 也要耗費IO資源,影響執(zhí)行速度。所以,MySQL就取了個折中方案,也就是有了 mixed 格式的 binlog。

mixed 格式的意思是,MySQL 自己會判斷這條SQL語句是否可能引起主從不一致,如果有可能,就用 row 格式,否則就用 statement 格式。也就是說,mixed 格式可以利用 statment 格式的優(yōu)點,同時又避免了數據不一致的風險。

不過現在越來越多的場景會把把 MySQL 的 binlog 格式設置成 row,例如下面的場景數據恢復。

這里從 delete、insert 和 update 這三種 SQL 語句的角度,來看看數據恢復的問題。

1、delete:如果執(zhí)行的是 delete 操作,需要恢復數據。row 格式的 binlog 也會把被刪掉的行的整行信息保存起來。所以,如果在執(zhí)行完一條 delete 語句以后,發(fā)現刪錯數據了,可以直接把 binlog 中記錄的 delete 語句轉成 insert,把被錯刪的數據插入回去就可以恢復了;

2、insert:如果執(zhí)行的是 insert 操作,需要恢復數據。row 格式下,insert 語句的 binlog 里會記錄所有的字段信息,這些信息可以用來精確定位剛剛被插入的那一行。這時,可以直接把 insert 語句轉成 delete 語句,刪除掉這被誤插入的一行數據就可以了;

3、update:如果執(zhí)行的是 update 操作,需要進行數據恢復。binlog里面會記錄修改前整行的數據和修改后的整行數據。所以,如果誤執(zhí)行了 update 語句的話,只需要把這個 event 前后的兩行信息對調一下,再去數據庫里面執(zhí)行,就能恢復這個更新操作了。

循環(huán)復制問題

上面 binlog 的原理,我們可以知道 MySQL 中主從數據同步就是通過 binlog 來保持數據一致的。

不過,雙 M 結構可能存在循環(huán)復制的問題。

MySQL 中讀寫分離數據延遲

什么是雙 M 架構,雙 M 結構和 M-S 結構,其實區(qū)別只是多了一條線,即:節(jié)點 A 和 B 之間總是互為主從關系。這樣在切換的時候就不用再修改主從關系。

業(yè)務邏輯在節(jié)點 A 中更新了一條語句,然后把生成的 binlog 發(fā)送給節(jié)點 B,節(jié)點 B 同樣也會生成 binlog 。

如果節(jié)點 A 同時又是節(jié)點 B 的從庫,節(jié)點 B 同樣也會傳遞 binlog 到節(jié)點 A,節(jié)點 A 會執(zhí)行節(jié)點 B 傳過來的 binlog。這樣,節(jié)點 A 和節(jié)點 B 會不斷的循環(huán)這個更新語句,這就是循環(huán)復制。

如何解決呢?

1、規(guī)定兩個庫的 server id 必須不同,如果相同,則它們之間不能設定為主從關系;

2、一個從庫接到 binlog 并在重放的過程中,生成與原 binlog 的 server id 相同的新的 binlog;

3、每個庫在收到從自己的主庫發(fā)過來的日志后,先判斷 server id,如果跟自己的相同,表示這個日志是自己生成的,就直接丟棄這個日志。

這樣當設置了雙 M 結構,日志的執(zhí)行流就會變成這樣:

1、從節(jié)點 A 更新的事務,binlog 里面記的都是 A 的 server id;

2、傳到節(jié)點 B 執(zhí)行一次以后,節(jié)點 B 生成的 binlog 的 server id 也是 A 的 server id;

3、再傳回給節(jié)點 A,A 判斷到這個 server id 與自己的相同,就不會再處理這個日志。所以,死循環(huán)在這里就斷掉了。

主從同步延遲

主從同步延遲,就是同一個事務,在從庫執(zhí)行完成的時間和主庫執(zhí)行完成的時間之間的差值。

1、主庫 A 執(zhí)行完成一個事務,并且寫入到 binlog ,記錄這個時間為 T1;

2、傳遞數據給從庫,從庫接收這個 binlog,接收完成的時間記為 T2;

3、從庫 B 執(zhí)行完成這個接收的事務,這個時間記為 T3。

主從延遲的時間就是 T3-T1 之間的時間差。

通過 show slave status 命令能到 seconds_behind_master 這個值就表示當前從庫延遲了多少秒。

seconds_behind_master 的計算方式:

1、每個事務的 binlog 都有一個時間字段,用于記錄主庫寫入的時間;

2、從庫取出當前正在執(zhí)行的事務的時間字段的值,計算他與當前系統(tǒng)時間的差值,就能得到 seconds_behind_master。

簡單的講 seconds_behind_master 就是上面 T3 -T1 的時間差值。

如果主從機器的時間設置的不一致,會不會導致主從延遲的不準確?

答案是不會的,從庫連接到主庫,會通過 SELECT UNIX_TIMESTAMP()函數來獲取當前主庫的時間,如果這時候發(fā)現主庫系統(tǒng)時間與自己的不一致,從庫在執(zhí)行 seconds_behind_master 計算的時候會主動扣減掉這差值。

主從同步延遲的原因

主從同步延遲可能存在的原因:

1、從庫的性能比主庫所在的機器性能較差;

從庫的性能比較查,如果從庫的復制能力,低于主庫,那么在主庫寫入壓力很大的情況下,就會造成從庫長時間數據延遲的情況出現。

2、從庫的壓力大;

大量查詢放在從庫上,可能會導致從庫上耗費了大量的 CPU 資源,進而影響了同步速度,造成主從延遲。

3、大事務的執(zhí)行;

有事務產生的時候,主庫必須要等待事務完成之后才能寫入到 binlog,假定執(zhí)行的事務是一個非常大的數據插入,這些數據傳輸到從庫,從庫同步這些數據也需要一定的時間,就會導致從節(jié)點出現數據延遲。

4、主庫異常發(fā)生主從或主從切換切換。

發(fā)生主庫切換的時候,可能會出現數據的不一致,主從切換會有下面兩種策略:

可靠性優(yōu)先策略:

1、首先判斷下從庫的 seconds_behind_master ,如果小于某個可以容忍的值,就進行下一步,否則持續(xù)重試這一步;

2、把主庫 A 改成只讀狀態(tài),設置 readonly 為 true;

3、判斷從庫 B 的 seconds_behind_master,直到這個值變成 0 為止;

4、把從庫 B 改成可讀寫狀態(tài),設置 readonly 為 false,從庫 B 變成新的主庫;

5、更新業(yè)務請求會切換到到從庫 B。

這個切換的過程中是存在不可用時間的,在步驟 2 之后,主庫 A 和從庫 B 都處于 readonly 狀態(tài),這時候系統(tǒng)處于不可寫狀態(tài),知道從庫庫 B readonly 狀態(tài)變成 false,這時候才能正常的接收寫請求。

步驟 3 判斷 seconds_behind_master 為 0,這個操作是最耗時的,通過步驟 1 中的提前判斷,可以確保 seconds_behind_master 的值足夠小,能夠減少步驟 3 的等待時間。

可用性優(yōu)先策略:

如果把步驟4、5調整到最開始執(zhí)行,不等主庫的數據同步,直接把連接切到從庫 B,讓從庫 B 可以直接讀寫,這樣系統(tǒng)就幾乎沒有不可用時間了。

這種策略能最大可能保障服務的可用性,但是會出現數據不一致的情況,因為寫請求直接切換到從庫 B 中,也就是設置 B 為新的主庫,因為 B 庫中還沒有同步到最新的數據,變成主庫之后,這部分數據就丟失了。

主從延遲如何處理

面對主從延遲,有下面幾種應對方案:

1、強制走主庫方案;

2、sleep方案;

3、判斷主從無延遲方案;

4、配合 semi-sync 方案;

5、等主庫位點方案;

6、等 GTID 方案。

強制走主庫方案

強制走主庫方案是實質上就是將查詢進行分類,將不能容忍同步延遲的查詢直接在主庫中進行。

1、對于必須要拿到最新結果的請求,強制將其發(fā)到主庫上。

2、對于可以讀到舊數據的請求,才將其發(fā)到從庫上。

這種方式有點投機的意思,如果所有的查詢都不允許有延遲的出現,也就意味所有的查詢,都會在主庫中出現。這樣就相當于放棄讀寫分離,所有的讀寫壓力都在主庫,等同于放棄了擴展性。

Sleep 方案

主庫更新完成,從庫在讀取數據之前,首先 sleep 一會。具體的方案就是,類似于執(zhí)行一條 select sleep(1) 命令。

這個方案的假設是,大多數情況下主從延遲在1秒之內,做一個sleep可以有很大概率拿到最新的數據。

這種方式不是一個靠譜的方案

1、如果一個查詢請求本來 0.5 秒就可以在從庫上拿到正確結果,也會等 1 秒;

2、如果延遲超過1秒,還是會出現過期讀。

判斷主從無延遲方案

可以通過主從是否有延遲,沒有延遲就在從庫中執(zhí)行查詢操作,有下面三種方法。

1、判斷 seconds_behind_master;

每次查詢之前首先判斷 seconds_behind_master 的值是否等于 0 。如果不等于 0 表示還有延遲,直到等于 0 才進行查詢操作。

2、對比位點確保主從無延遲;

  • Master_Log_File 和 Read_Master_Log_Pos,表示的是讀到的主庫的最新位點;

  • Relay_Master_Log_File 和 Exec_Master_Log_Pos,表示的是從庫執(zhí)行的最新位點。

如果 Master_Log_File 和 Relay_Master_Log_File、Read_Master_Log_Pos 和 Exec_Master_Log_Pos 這兩組值完全相同,就表示接收到的日志已經同步完成。

3、對比 GTID 集合確保主從無延遲:

  • Auto_Position=1 ,表示這對主從關系使用了 GTID 協(xié)議;

  • Retrieved_Gtid_Set,是從庫收到的所有日志的 GTID 集合;

  • Executed_Gtid_Set,是從庫所有已經執(zhí)行完成的GTID集合。

如果 Retrieved_Gtid_Set 和 Executed_Gtid_Set 這兩個集合相同就表示從庫接收的日志已經同步完成。

什么是 GTID ?

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

它由兩部分組成,格式是:

GTID=server_uuid:gno
  • server_uuid 是一個實例第一次啟動時自動生成的,是一個全局唯一的值;

  • gno 是一個整數,初始值是1,每次提交事務的時候分配給這個事務,并加1。

在 GTID 模式下,每一個事務都會跟一個 GTID 一一對應。GTID 有兩種生成方式,通過 session 變量 gtid_next 的值來決定:

1、如果 gtid_next=automatic,代表使用默認值。這時,MySQL 就會把 server_uuid:gno 分配給這個事務。

a、記錄 binlog 的時候,先記錄一行 SET @@SESSION.GTID_NEXT=‘server_uuid:gno’;

b、把這個 GTID 加入本實例的 GTID 集合。

2、如果 gtid_next 是一個指定的GTID的值,比如通過 set gtid_next='current_gtid’ 指定為 current_gtid,那么就有兩種可能:

a、如果 current_gtid 已經存在于實例的GTID集合中,接下來執(zhí)行的這個事務會直接被系統(tǒng)忽略;

b、如果 current_gtid 沒有存在于實例的 GTID 集合中,就將這個 current_gtid 分配給接下來要執(zhí)行的事務,也就是說系統(tǒng)不需要給這個事務生成新的 GTID,因此 gno 也不用加1。

一個 current_gtid 只能給一個事務使用。這個事務提交后,如果要執(zhí)行下一個事務,就要執(zhí)行set 命令,把 gtid_next 設置成另外一個 gtid 或者 automatic。

每個 MySQL 實例都維護了一個 GTID 集合,用來對應“這個實例執(zhí)行過的所有事務”。

明白了 GTID 的概念,再來看下基于 GTID 的主從復制的用法。

在 GTID 模式下,從庫 C 要設置為主從庫 B 的從庫的語法如下:

我們把現在這個時刻,實例 B 的 GTID 集合記為set_b,實例 C 的 GTID 集合記為 set_c。接下來,我們就看看現在的主從切換邏輯。

我們在實例 C 上執(zhí)行 start slave 命令,取 binlog 的邏輯是這樣的:

1、實例 C 指定主庫 B,基于主從協(xié)議建立連接。

2、實例 C 把 set_c 發(fā)給主庫 B。

3、實例 B 算出 set_b 與 set_c 的差集,也就是所有存在于 set_b,但是不存在于 set_c 的 GITD 的集合,判斷 B 本地是否包含了這個差集需要的所有 binlog 事務。

a、如果不包含,表示 B 已經把實例 C 需要的 binlog 給刪掉了,直接返回錯誤;

b、如果確認全部包含,B 從自己的 binlog 文件里面,找出第一個不在 set_c 的事務,發(fā)給 C;

之后就從這個事務開始,往后讀文件,按順序取 binlog 發(fā)給 C 去執(zhí)行。

這個邏輯里面包含了一個設計思想:在基于 GTID 的主從關系里,系統(tǒng)認為只要建立主從關系,就必須保證主庫發(fā)給從庫的日志是完整的。因此,如果實例 C 需要的日志已經不存在,B 就拒絕把日志發(fā)給 C。

這跟基于位點的主從協(xié)議不同?;谖稽c的協(xié)議,是由從庫決定的,從庫指定哪個位點,主庫就發(fā)哪個位點,不做日志的完整性判斷。

我們再來看看引入 GTID 后,一主多從的切換場景下,主從切換是如何實現的。

由于不需要找位點了,所以從庫 C、D 只需要分別執(zhí)行 change master 命令指向實例 B 即可。

其實,嚴謹地說,主從切換不是不需要找位點了,而是找位點這個工作,在實例 B 內部就已經自動完成了。但由于這個工作是自動的,所以對HA系統(tǒng)的開發(fā)人員來說,非常友好。

之后這個系統(tǒng)就由新主庫 B 寫入,主庫 B 的自己生成的 binlog 中的 GTID 集合格式是:server_uuid_of_B:1-M

GTID 主從同步設置時,主庫 A 發(fā)現需同步的 GTID 日志有刪掉的,那么 A 就會報錯。

解決辦法:

從庫 C 在啟動同步前需要設置 gtid_purged,指定 GTID 同步的起點,使用備份搭建從庫時需要這樣設置。

如果在從庫上執(zhí)行了單獨的操作,導致主庫上缺少 GTID,那么可以在主庫上模擬一個與從庫 C 上 GTID 一樣的空事務,這樣主從同步就不會報錯了。

配合semi-sync

MySQL 有三種同步模式,分別是:

1、異步復制:MySQL 中默認的復制是異步的,主庫在執(zhí)行完客戶端提交的事務后會立即將結果返回給客戶端,并不關心從庫是否已經接收并且處理。存在問題就是,如果主庫的日志沒有及時同步到從庫,然后主庫宕機了,這時候執(zhí)行故障轉移,在從庫沖選主,可能會存在選出的主庫中數據不完整;

2、全同步復制:指當主庫執(zhí)行完一個事務,并且等到所有從庫也執(zhí)行完成這個事務的時候,主庫在提交事務,并且返回數據給客戶端。因為要等待所有從庫都同步到主庫中的數據才返回數據,所以能夠保證主從數據的一致性,但是數據庫的性能必然受到影響;

3、半同步復制:是介于全同步和全異步同步的一種,主庫至少需要等待一個從庫接收并寫入到 Relay Log 文件即可,主庫不需要等待所有從庫給主庫返回 ACK。主庫收到 ACK ,標識這個事務完成,返回數據給客戶端。

MySQL 中默認的復制是異步的,所以主庫和從庫的同步會存在一定的延遲,更重要的是異步復制還可能引起數據的丟失。全同步復制的性能又太差了,所以從 MySQL 5.5 開始,MySQL 以插件的形式支持 semi-sync 半同步復制。

因為本同步復制不需要等待所有的從庫同步成功,這時候在從庫中的查詢,就會面臨兩種情況:

1、如果查詢是落在這個響應了 ack 的從庫上,是能夠確保讀到最新數據;

2、如果是查詢落到其他從庫上,它們可能還沒有收到最新的日志,就會產生過期讀的問題。

等主庫位點方案

理解等主庫位點方案之前,首先來看下下面的這條命令的含義

select master_pos_wait(file, pos[, timeout]);

看下這條命令的幾個參數:

1、這條命令是在從庫中執(zhí)行的;

2、參數 file 和 pos 指的是主庫上的文件名和位置;

3、timeout 可選,設置為正整數 N 表示這個函數最多等待 N 秒。

這條命令的正常返回是一個正整數 M ,表示從命令開始執(zhí)行,到應用完 file 和 pos 表示的 binlog 位置,成功執(zhí)行的事務個數。

如果從庫執(zhí)行這個命令,表示從庫同步完 file 和 pos 表示的 binlog 位置,同步的事務數量,正常返回 M 表示從庫數據在 timeout 時間內相對于主庫已經沒有延遲了。

除了正常返回,也會有其它的執(zhí)行返回信息

1、如果執(zhí)行期間從庫同步發(fā)生異常,就返回 NULL;

2、如果等待超過 N 秒,聚返回 -1;

3、如果剛開始執(zhí)行的時候,就發(fā)現已經執(zhí)行過這個位置了,就返回 0。

弄明白了這條命令的作用,我們再來看下等主庫位點方案的具體執(zhí)行流程,如果我們在主庫中執(zhí)行一個數據更新,然后在從庫中查詢,執(zhí)行的過程就是:

1、更新事務執(zhí)行完成,馬上執(zhí)行 show master status 得到當前主庫執(zhí)行到的 File 和 Position;

2、選定一個從庫執(zhí)行查詢;

3、在從庫上執(zhí)行 select master_pos_wait(File, Position, 1);

4、如果返回值是 >=0 的正整數,則在這個從庫執(zhí)行查詢語句;

5、否則到主庫執(zhí)行查詢。

如果從庫的延遲都超過了的等待的 timeout 時間,那么所有的請求,最總還是會落到主庫中,查詢的壓力還是會爬到主庫中。

等 GTID 方案

如果開啟了 GTID 模式,對應的也有等待 GTID 的方案。

MySQL 中同樣提供了等待同步的命令

 select wait_for_executed_gtid_set(gtid_set, 1);

執(zhí)行邏輯:

1、從庫在執(zhí)行命令的時候攜帶事務的 gtid,如果返回 0 表示該事務已經正常同步到從庫中,可以在從庫中執(zhí)行查詢;

2、超時測返回 1。

在前面等位點的方案中,我們執(zhí)行完事務后,還要主動去主庫執(zhí)行 show master status。而 MySQL 5.7.6 版本開始,允許在執(zhí)行完更新類事務后,把這個事務的GTID返回給客戶端,這樣等 GTID 的方案就可以減少一次查詢。

等 GTID 方案的流程就是

1、主庫中執(zhí)行完成一個事務,從返回包直接獲取這個事務的 GTID,記為 gtid1;

2、選定一個從庫執(zhí)行查詢語句;

3、從庫中執(zhí)行 select wait_for_executed_gtid_set(gtid1, 1);

4、如果返回值是 0,就在從庫中執(zhí)行查詢;

5、返回值不是 0,表示該事務還沒有同步到從庫中,就需要到主庫中執(zhí)行查詢了。

和等主庫位點方案的方案一樣,等待超時就需要向主庫中發(fā)起查詢了。

總結

1、MySQL 中讀寫分離是經常用到了的架構了,通過讀寫分離實現橫向擴展的能力,寫入和更新操作在源服務器上進行,從服務器中進行數據的讀取操作,通過增大從服務器的個數,能夠極大的增強數據庫的讀取能力;

2、MySQL 數據進行主從同步,主要是通過 binlog 實現的,從庫利用主庫上的binlog進行重播,實現主從同步;

3、數據同步會存在一個問題及時同步延遲;

4、主從同步延遲可能存在的原因:

  • 1、從庫的性能比主庫所在的機器性能較差;

  • 2、從庫的壓力大;

  • 3、大事務的執(zhí)行;

  • 4、主庫異常發(fā)生主從或主從切換切換。

5、主從延遲應該如何處理?

面對主從延遲,有下面幾種應對方案:

  • 1、強制走主庫方案;

  • 2、sleep方案;

  • 3、判斷主從無延遲方案;

  • 4、配合 semi-sync 方案;

  • 5、等主庫位點方案;

  • 6、等 GTID 方案。

參考

【高性能MySQL(第3版)】https://book.douban.com/subject/23008813/
【MySQL 實戰(zhàn) 45 講】https://time.geekbang.org/column/100020801
【MySQL技術內幕】https://book.douban.com/subject/24708143/
【MySQL學習筆記】https://github.com/boilingfrog/Go-POINT/tree/master/mysql
【MySQL文檔】https://dev.mysql.com/doc/refman/8.0/en/replication.html
【淺談 MySQL binlog 主從同步】http://www.linkedkeeper.com/1503.html文章來源地址http://www.zghlxwxcb.cn/news/detail-437129.html

到了這里,關于MySQL 中讀寫分離數據延遲的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • MySQL數據庫 主從復制與讀寫分離

    讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從數據庫處理SELECT查詢操作。數據庫復制被用來把事務性操作導致的變更同步到集群中的從數據庫。 因為數據庫的“寫”(寫10000條數據可能要3分鐘)操作是比較耗時的。 但是數據庫

    2024年02月10日
    瀏覽(30)
  • 【數據庫】mysql主從復制與讀寫分離

    【數據庫】mysql主從復制與讀寫分離

    ??讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE ),而從數據庫處理SELECT查詢操作。數據庫復制被用來把事務性操作導致的變更同步到集群中的從數據庫。 ??因為數據庫的\\\"寫”(寫10000條數據可能要3分鐘)操作是比較耗時的。 ??

    2024年02月11日
    瀏覽(27)
  • 【MySQL數據庫】主從復制與讀寫分離

    【MySQL數據庫】主從復制與讀寫分離

    讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從數據庫處理SELECT查詢操作。數據庫復制被用來把事務性操作導致的變更同步到集群中的從數據庫。 因為數據庫的“寫”(寫10000條數據可能要3分鐘)操作是比較耗時的。 但是數據庫

    2024年02月11日
    瀏覽(24)
  • 【數據庫七】MySQL主從復制與讀寫分離

    【數據庫七】MySQL主從復制與讀寫分離

    讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操作 (insert、update、delete),而 從數據庫處理select查詢操作 。 數據庫復制被用來把事務性操作導致的變更同步到集群中的從數據庫 。 因為數據庫的“寫”(寫10000條數據可能要3分鐘)操作是比較耗時的。 但是數據

    2024年02月11日
    瀏覽(21)
  • 看!MySQL 8.2 數據庫支持讀寫分離啦!

    看!MySQL 8.2 數據庫支持讀寫分離啦!

    MySQL 8.2.0創(chuàng)新版本已于2023-10-17發(fā)布,MySQL Router 8.2 支持數據庫的讀/寫分離,這里將在InnoDB Cluster集群中演示數如何進行讀寫分離,本篇內容包括:MySQL Server數據庫安裝、MySQL Shell安裝、MySQL Router安裝、InnoDB Cluster安裝與讀寫分離演示,若您只關注讀寫分離的演示,可直接跳至最

    2024年02月05日
    瀏覽(16)
  • MySQL一主一從、配置一主多從結構、數據讀寫分離

    部署mysql主從同步 配置mysql主從 分為主數據庫角色(master)、從數據庫服務器角色(slave) 網站服務器連接后存儲數據的服務器作為主服務器 自動同步主服務器上的數據 192.168.88.53 做master 啟用binlog日志文件?指定server_id 重啟服務 用戶授權 查看正在使用的binlog日志文件 192.

    2024年01月19日
    瀏覽(23)
  • 華為云數據庫 RDS for MySQL 的讀寫分離,憑什么打破企業(yè)數據瓶頸?

    華為云數據庫 RDS for MySQL 的讀寫分離,憑什么打破企業(yè)數據瓶頸?

    隨著云2.0時代的到來,眾多企業(yè)發(fā)現人工智能、大數據算法能為企業(yè)發(fā)展帶來巨大的利潤,人工智能、大數據算法等計算機算法被應用于企業(yè)的生產和發(fā)展,云+業(yè)務逐漸成為現代化企業(yè)發(fā)展的潮流,對傳統(tǒng)數據庫模式提出了挑戰(zhàn)。 企業(yè)的業(yè)務從線下發(fā)展到線上,這就使得服

    2024年02月22日
    瀏覽(20)
  • spring boot shardingsphere mybatis-plus druid mysql 搭建mysql數據庫讀寫分離架構

    spring boot shardingsphere mybatis-plus druid mysql 搭建mysql數據庫讀寫分離架構

    ##關于window mysql主從搭建簡單教程 傳送門?window mysql5.7 搭建主從同步環(huán)境-CSDN博客 ##父pom.xml ##模塊pom.xml ##yml配置 ##mapper.xml ##TestMapper ##TestService ##TestController ##瀏覽器訪問 ##數據庫

    2024年01月21日
    瀏覽(26)
  • mysql面試題45:讀寫分離常見方案、哪些中間件可以實現讀寫分離

    mysql面試題45:讀寫分離常見方案、哪些中間件可以實現讀寫分離

    該文章專注于面試,面試只要回答關鍵點即可,不需要對框架有非常深入的回答,如果你想應付面試,是足夠了,抓住關鍵點 讀寫分離是一種常見的數據庫架構方案,旨在分擔數據庫的讀寫壓力,提高系統(tǒng)的性能和可擴展性。以下是兩種常見的讀寫分離方案: 主從復制方案

    2024年02月07日
    瀏覽(23)
  • Mysql 主從復制、讀寫分離

    Mysql 主從復制、讀寫分離

    目錄 前言 一、主從復制原理 1.1 MySQL的復制類型 1.2?mysql主從復制的工作原理 1.3 MySQL主從復制延遲 1.4?MySQL四種同步方式 1.5 MySQL支持的復制類型 二、 MySQL應用場景 三、主從復制實驗 3.1?MySQL主從服務器時間同步 3.1.1 安裝ntp、修改配置文件 3.1.2 兩臺SLAVE服務器配置 3.2 配置主從

    2024年02月16日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包