日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql主从是同步还是异步_mysql主从同步异步场景的分析

發布時間:2024/7/23 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql主从是同步还是异步_mysql主从同步异步场景的分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

之所以進行這塊內容的研究,主要針對之前遇到的兩個未解的疑惑:

a.?線上有個系統,半同步狀態經常從半同步變成異步,然后又馬上恢復為半同步,具體原因未明,雖然之前也猜得八九不離十,但還是未完全確定。

b.?前段時間因為有業務場景需求,做了跨機房異步復制測試。當mysql寫qps非常高的時候,發現很多日志還沒有來得及發送到從庫,也就是binlog日志在主庫的產生速度大于傳送到從庫的速度,這個速度差一直存在,因此當主庫在持續高壓力地產生binlog的時候,越來越多的binlog沒有傳送到從庫,但當時的網絡流量也才18M/S左右(一主一從),從常規的知識認為,千兆的網絡傳送的速度可以達到100M,而當前的主從之間的binlog傳送速度只達到了18M左右,原因是什么? 是網絡問題? 還是其他原因。

主從復制原理

Dump線程與io線程

當主從復制關系建立之后,主庫上有個dump線程,用來傳送在主庫產生的binlog日志的,而從庫上的io線程,則用來接收由dump線程通過網絡傳送到從庫的binlog日志,并負責將其寫入relay log 中去。 這就是主從復制的機制, 同時,由于是異步復制,傳送過程不需要ack的確認。

疑問也正在此處——因為是異步傳輸,如果單純地理解為binlog文件直接網絡傳送,這個速度應該很快才是,但實際情況:在我們的測試環境中,binlog日志的傳送速度才18M/s ,小于日志產生的22M/s左右的速度。為什么只有這個速度,而沒有把網絡帶寬用滿?原因是什么?

日志傳送細節

主從復制的結構中,主庫上的dump線程跟從庫上的io線程各自有一個,所以不存在多線程地并發發送跟接收的情況,只需要了解binlog dump線程的工作機制,就能了解所有的細節。

通過解析binlog文件,我們可以知道,一個事務可以包含多個event, 下面是一個最簡單的事物的在binlog中所記錄的信息:

# at 33580

#170531 17:22:53 server id 153443358 ?end_log_pos 33645 CRC32 0x4ea17869 ???????GTID ???last_committed=125 ?????sequence_number=126

SET @@SESSION.GTID_NEXT= ‘e1028e43-4123-11e7-a3c2-005056aa17e6:198’/*!*/;

# at 33645

#170531 17:22:53 server id 153443358 ?end_log_pos 33717 CRC32 0x66820e00 ???????Query ??thread_id=4 ????exec_time=0 ????error_code=0

SET TIMESTAMP=1496222573/*!*/;

BEGIN

/*!*/;

# at 33717

#170531 17:22:53 server id 153443358 ?end_log_pos 33770 CRC32 0x22ddf25e ???????Table_map: `test`.`xcytest` mapped to number 222

# at 33770

#170531 17:22:53 server id 153443358 ?end_log_pos 33817 CRC32 0x61051ea0 ???????Write_rows: table id 222 flags: STMT_END_F

BINLOG ‘

bYsuWRMeXCUJNQAAAOqDAAAAAN4AAAAAAAEABHRlc3QAB3hjeXRlc3QAAgMPAlgCAl7y3SI=

bYsuWR4eXCUJLwAAABmEAAAAAN4AAAAAAAEAAgAC//x9AAAABQBzZGZhc6AeBWE=

‘/*!*/;

### INSERT INTO `test`.`xcytest`

### SET

### ??@1=125 /* INT meta=0 nullable=0 is_null=0 */

### ??@2=’sdfas’ /* VARSTRING(600) meta=600 nullable=1 is_null=0 */

# at 33817

#170531 17:22:53 server id 153443358 ?end_log_pos 33848 CRC32 0x630805b4 ???????Xid = 303

COMMIT/*!*/;

每一個at xxxxx段,是一個event .

函數Binlog_sender::send_events?就是發送binlog中的event事件的函數:

函數入參:

end_pos,當前讀到的binlog文件的最末尾位置。

log_cache,記錄是當前傳送的日志的信息,包含已經傳送的binlog日志的位置,以及binlog日志文件。

函數邏輯分析:

如果當前已發送的位置log_pos小于已獲取到的文件的末尾位置end_pos.則表明還有binlog日志未發送,進入循環。

循環體內:

a.?首先調用函數read_event,獲取一個事件event.

b.?Log_event_type?event_type= (Log_event_type)event_ptr[EVENT_TYPE_OFFSET];

該語句用來獲取事件event的類型,然后進行類型檢查

check_event_type(event_type, log_file, log_pos),如果沒有通過檢查,直接返回1給上層函數。

c.?log_pos= my_b_tell(log_cache); 更新log_pos位置,也就是將讀binlog位置的游標前移到當前位置。

d.?然后調用send_packet() 函數進行binlog的發送。

原來, 不管當前還有多少binlog沒有同步到從庫,主庫發送binlog的粒度依然是一個一個event的發送,發送之前,還需要檢查event的類型。因為是小包發送,所以網絡的流量并不大。

但需要說明一下出現這個現象的前提條件:我們測試環境中,當時數據庫的寫qps達到了50000以上,所以需要發送的event特別多,即使是異步,也導致單線程的dump線程來不及發送當前產生的日志。

當寫的qps巨大的時候,確實存在來不及發送日志的情景。

總結

現在,再來回頭看線上遇到的問題,“同步狀態經常從半同步狀態變成異步狀態,然后又被及時復原到半同步狀態”,原因是該數據庫是一個分析系統,有時候會做批量的更新,以及批量的導入。同時,數據庫設置的binlog格式為row模式,對于一個更新多行的事務,里面包含很多的event(一行是一個event), 所以發送這個事務的binlog耗時會比較長,無法在1秒鐘內發送完成(半同步的timeout時間設置為1),所以半同步狀態變成了異步。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的mysql主从是同步还是异步_mysql主从同步异步场景的分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。