0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

探討MySQL的復(fù)制機(jī)制實(shí)現(xiàn)的方式

OSC開源社區(qū) ? 來源:vivo互聯(lián)網(wǎng)技術(shù) ? 2023-04-12 09:29 ? 次閱讀

MySQL Replication(主從復(fù)制)是指數(shù)據(jù)變化可以從一個(gè)MySQL Server被復(fù)制到另一個(gè)或多個(gè)MySQL Server上,通過復(fù)制的功能,可以在單點(diǎn)服務(wù)的基礎(chǔ)上擴(kuò)充數(shù)據(jù)庫(kù)的高可用性、可擴(kuò)展性等。

一、背景

MySQL在生產(chǎn)環(huán)境中被廣泛地應(yīng)用,大量的應(yīng)用和服務(wù)都對(duì)MySQL服務(wù)存在重要的依賴關(guān)系,可以說如果數(shù)據(jù)層的MySQL實(shí)例發(fā)生故障,在不具備可靠降級(jí)策略的背景下就會(huì)直接引發(fā)上層業(yè)務(wù),甚至用戶使用的障礙;同時(shí)MySQL中存儲(chǔ)的數(shù)據(jù)也是需要盡可能地減少丟失的風(fēng)險(xiǎn),以避免故障時(shí)出現(xiàn)數(shù)據(jù)丟失引發(fā)的資產(chǎn)損失、客訴等影響。

在這樣對(duì)服務(wù)可用性和數(shù)據(jù)可靠性需求的背景下,MySQL在Server層提供了一種可靠的基于日志的復(fù)制能力(MySQL Replication),在這一機(jī)制的作用下,可以輕易構(gòu)建一個(gè)或者多個(gè)從庫(kù),提高數(shù)據(jù)庫(kù)的高可用性可擴(kuò)展性,同時(shí)實(shí)現(xiàn)負(fù)載均衡

實(shí)時(shí)數(shù)據(jù)變化備份

主庫(kù)的寫入數(shù)據(jù)會(huì)持續(xù)地在冗余的從庫(kù)節(jié)點(diǎn)上被執(zhí)行保留,減少數(shù)據(jù)丟失的風(fēng)險(xiǎn)

橫向拓展節(jié)點(diǎn),支撐讀寫分離

當(dāng)主庫(kù)本身承受壓力較大時(shí),可以將讀流量分散到其它的從庫(kù)節(jié)點(diǎn)上,達(dá)成讀擴(kuò)展性和負(fù)載均衡

高可用性保障

當(dāng)主庫(kù)發(fā)生故障時(shí),可以快速的切到其某一個(gè)從庫(kù),并將該從庫(kù)提升為主庫(kù),因?yàn)閿?shù)據(jù)都一樣,所以不會(huì)影響系統(tǒng)的運(yùn)行

具備包括但不限于以上特性的MySQL集群就可以覆蓋絕大多數(shù)應(yīng)用和故障場(chǎng)景,具備較高的可用性與數(shù)據(jù)可靠性,當(dāng)前存儲(chǔ)組提供的生產(chǎn)環(huán)境MySQL就是基于默認(rèn)的異步主從復(fù)制的集群,向業(yè)務(wù)保證可用性99.99%,數(shù)據(jù)可靠性99.9999%的在線數(shù)據(jù)庫(kù)服務(wù)。

本文將深入探討MySQL的復(fù)制機(jī)制實(shí)現(xiàn)的方式, 同時(shí)討論如何具體地應(yīng)用復(fù)制的能力來提升數(shù)據(jù)庫(kù)的可用性,可靠性等。

二、復(fù)制的原理

2.1 Binlog 的引入

從比較寬泛的角度來探討復(fù)制的原理,MySQL的Server之間通過二進(jìn)制日志來實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)變化的傳輸復(fù)制,這里的二進(jìn)制日志是屬于MySQL服務(wù)器的日志,記錄了所有對(duì)MySQL所做的更改。這種復(fù)制模式也可以根據(jù)具體數(shù)據(jù)的特性分為三種:

Statement:基于語句格式

Statement模式下,復(fù)制過程中向獲取數(shù)據(jù)的從庫(kù)發(fā)送的就是在主庫(kù)上執(zhí)行的SQL原句,主庫(kù)會(huì)將執(zhí)行的SQL原有發(fā)送到從庫(kù)中。

Row:基于行格式

Row模式下,主庫(kù)會(huì)將每次DML操作引發(fā)的數(shù)據(jù)具體行變化記錄在Binlog中并復(fù)制到從庫(kù)上,從庫(kù)根據(jù)行的變更記錄來對(duì)應(yīng)地修改數(shù)據(jù),但DDL類型的操作依然是以Statement的格式記錄。

Mixed:基于混合語句和行格式

MySQL 會(huì)根據(jù)執(zhí)行的每一條具體的 SQL 語句來區(qū)分對(duì)待記錄的日志形式,也就是在 statement 和 row 之間選擇一種。

最早的實(shí)現(xiàn)是基于語句格式,在3.23版本被引入MySQL,從最初起就是MySQL Server層的能力,這一點(diǎn)與具體使用的存儲(chǔ)引擎沒有關(guān)聯(lián);在5.1版本后開始支持基于行格式的復(fù)制;在5.1.8版本后開始支持混合格式的復(fù)制。

這三種模式各有優(yōu)劣,相對(duì)來說,基于Row的行格式被應(yīng)用的更廣泛,雖然這種模式下對(duì)資源的開銷會(huì)偏大,但數(shù)據(jù)變化的準(zhǔn)確性以及可靠性是要強(qiáng)于Statement格式的,同時(shí)這種模式下的Binlog提供了完整的數(shù)據(jù)變更信息,可以使其應(yīng)用不被局限在MySQL集群系統(tǒng)內(nèi),可以被例如Binlogserver,DTS數(shù)據(jù)傳輸?shù)确?wù)應(yīng)用,提供靈活的跨系統(tǒng)數(shù)據(jù)傳輸能力, 目前互聯(lián)網(wǎng)業(yè)務(wù)的在線MySQL集群全部都是基于Row行格式的Binlog。

2.2 Binlog 的要點(diǎn)

2.2.1 Binlog事件類型

對(duì)于Binlog的定義而言,可以認(rèn)為是一個(gè)個(gè)單一的Event組成的序列,這些單獨(dú)的Event可以主要分為以下幾類:

40334724-d88b-11ed-bfe3-dac502259ad0.jpg

各類Event出現(xiàn)是具有顯著的規(guī)律的:

XID_EVENT標(biāo)志一個(gè)事務(wù)的結(jié)尾

當(dāng)發(fā)生了DDL類型的QUERY_EVENT,那么也是一次事務(wù)的結(jié)束提交點(diǎn),且不會(huì)出現(xiàn)XID_EVENT

GTID_EVENT只有開啟了GTID_MODE(MySQL版本大于5.6)

TABLE_MAP_EVENT必定出現(xiàn)在某個(gè)表的變更數(shù)據(jù)前,存在一對(duì)多個(gè)ROW_EVENT的情況

除了上面和數(shù)據(jù)更貼近的事件類型外,還有ROTATE_EVENT(標(biāo)識(shí)Binlog文件發(fā)生了切分),F(xiàn)ORMAT_DESCRIPTION_EVENT(定義元數(shù)據(jù)格式)等。

2.2.2 Binlog的生命周期

Binlog和Innodb Log(redolog)的存在方式是不同的,它并不會(huì)輪轉(zhuǎn)重復(fù)覆寫文件,Server會(huì)根據(jù)配置的單個(gè)Binlog文件大小配置不斷地切分并產(chǎn)生新的Binlog,在一個(gè).index文件記錄當(dāng)前硬盤上所有的binlog文件名,同時(shí)根據(jù)Binlog過期時(shí)間回收刪除掉過期的Binlog文件,這兩個(gè)在目前自建數(shù)據(jù)庫(kù)的配置為單個(gè)大小1G,保留7天。

所以這種機(jī)制背景下,只能在短期內(nèi)追溯歷史數(shù)據(jù)的狀態(tài),而不可能完整追溯數(shù)據(jù)庫(kù)的數(shù)據(jù)變化的,除非是還沒有發(fā)生過日志過期回收的Server。

2.2.3Binlog事件示例

Binlog是對(duì)Server層生效的,即使沒有從庫(kù)正在復(fù)制主庫(kù),只要在配置中開啟了log_bin,就會(huì)在對(duì)應(yīng)的本地目錄存儲(chǔ)binlog文件,使用mysqlbinlog打開一個(gè)Row格式的示例binlog文件:

403d683a-d88b-11ed-bfe3-dac502259ad0.png

如上圖,可以很明顯地注意到三個(gè)操作,創(chuàng)建數(shù)據(jù)庫(kù)test, 創(chuàng)建數(shù)據(jù)表test, 一次寫入引發(fā)的行變更,可讀語句(create, alter, drop, begin, commit.....)都可以認(rèn)為是QUERY_EVENT,而Write_rows就屬于ROW_EVENT中的一種。

在復(fù)制的過程中,就是這樣的Binlog數(shù)據(jù)通過建立的連接發(fā)送到從庫(kù),等待從庫(kù)處理并應(yīng)用。

2.2.4 復(fù)制基準(zhǔn)值

Binlog在產(chǎn)生時(shí)是嚴(yán)格有序的,但它本身只具備秒級(jí)的物理時(shí)間戳,所以依賴時(shí)間進(jìn)行定位或排序是不可靠的,同一秒可能有成百上千的事件,同時(shí)對(duì)于復(fù)制節(jié)點(diǎn)而言,也需要有效可靠的記錄值來定位Binlog中的水位,MySQL Binlog支持兩種形式的復(fù)制基準(zhǔn)值,分別是傳統(tǒng)的Binlog File:Binlog Position模式,以及5.6版本后可用的全局事務(wù)序號(hào)GTID。

FILE Position

只要開啟了log_bin,MySQL就會(huì)具有File Position的位點(diǎn)記錄,這一點(diǎn)不受GTID影響。

File: binlog.000001
Position: 381808617

這個(gè)概念相對(duì)來說更直觀,可以直接理解為當(dāng)前處在File對(duì)應(yīng)編號(hào)的Binlog文件中,同時(shí)已經(jīng)產(chǎn)生了合計(jì)Position bytes的數(shù)據(jù),如例子中所示即該實(shí)例已經(jīng)產(chǎn)生了381808617 bytes的Binlog,這個(gè)值在對(duì)應(yīng)機(jī)器直接查看文件的大小也是匹配的,所以File Postion就是文件序列與大小的對(duì)應(yīng)值。

基于這種模式開啟復(fù)制,需要顯式地在復(fù)制關(guān)系中指定對(duì)應(yīng)的File和Position:

CHANGE MASTER TO MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POSITION=381808617;

這個(gè)值必須要準(zhǔn)確,因?yàn)檫@種模式下從庫(kù)獲取的數(shù)據(jù)完全取決于有效的開啟點(diǎn),那么如果存在偏差,就會(huì)丟失或執(zhí)行重復(fù)數(shù)據(jù)導(dǎo)致復(fù)制中斷。

GTID

MySQL 會(huì)在開啟GTID_MODE=ON的狀態(tài)下,為每一個(gè)事務(wù)分配唯一的全局事務(wù)ID,格式為:server_uuid:id

Executed_Gtid_Set: e2e0a733-3478-11eb-90fe-b4055d009f6c:1-753

其中e2e0a733-3478-11eb-90fe-b4055d009f6c用于唯一地標(biāo)識(shí)產(chǎn)生該Binlog事件的實(shí)例,1-753表示已經(jīng)產(chǎn)生或接收了由e2e0a733-3478-11eb-90fe-b4055d009f6c實(shí)例產(chǎn)生的753個(gè)事務(wù);

從庫(kù)在從主庫(kù)獲取Binlog Event時(shí),自身的執(zhí)行記錄會(huì)保持和獲取的主庫(kù)Binlog GTID記錄一致,還是以e2e0a733-3478-11eb-90fe-b4055d009f6c:1-753,如果有從庫(kù)對(duì)e2e0a733-3478-11eb-90fe-b4055d009f6c開啟了復(fù)制,那么在從庫(kù)自身執(zhí)行show master status也是會(huì)看到相同的值。

如果說從庫(kù)上可以看到和復(fù)制的主庫(kù)不一致的值,那么可以認(rèn)為是存在errant GTID,這個(gè)一般是由于主從切換或強(qiáng)制在從庫(kù)上執(zhí)行了寫操作引發(fā),正常情況下從庫(kù)的Binlog GTID應(yīng)該和主庫(kù)的保持一致;

基于這種模式開啟復(fù)制,不需要像File Position一樣指定具體的值,只需要設(shè)置:

CHANGE MASTER TO MASTER_AUTO_POSITION=1;

從庫(kù)在讀取到Binlog后,會(huì)自動(dòng)根據(jù)自身Executed_GTID_Set記錄比對(duì)是否存在已執(zhí)行或未執(zhí)行的Binlog事務(wù),并做對(duì)應(yīng)的忽略和執(zhí)行操作。

2.3 復(fù)制的具體流程

2.3.1基本復(fù)制流程

當(dāng)主庫(kù)已經(jīng)開啟了binlog( log_bin = ON ),并正常地記錄binlog,如何開啟復(fù)制?

這里以MySQL默認(rèn)的異步復(fù)制模式進(jìn)行介紹:

首先從庫(kù)啟動(dòng)I/O線程,跟主庫(kù)建立客戶端連接。

主庫(kù)啟動(dòng)binlog dump線程,讀取主庫(kù)上的binlog event發(fā)送給從庫(kù)的I/O線程,I/O線程獲取到binlog event之后將其寫入到自己的Relay Log中。

從庫(kù)啟動(dòng)SQL線程,將等待Relay中的數(shù)據(jù)進(jìn)行重放,完成從庫(kù)的數(shù)據(jù)更新。

總結(jié)來說,主庫(kù)上只會(huì)有一個(gè)線程,而從庫(kù)上則會(huì)有兩個(gè)線程。

404b59cc-d88b-11ed-bfe3-dac502259ad0.jpg

時(shí)序關(guān)系

當(dāng)集群進(jìn)入運(yùn)行的狀態(tài)時(shí),從庫(kù)會(huì)持續(xù)地從主庫(kù)接收到Binlog事件,并做對(duì)應(yīng)的處理,那么這個(gè)過程中將會(huì)按照下述的數(shù)據(jù)流轉(zhuǎn)方式:

Master將數(shù)據(jù)更改記錄在Binlog中,BinlogDump Thread接到寫入請(qǐng)求后,讀取對(duì)應(yīng)的Binlog

Binlog信息推送給Slave的I/O Thread。

Slave的I/O 線程將讀取到的Binlog信息寫入到本地Relay Log中。

Slave的SQL 線程讀取Relay Log中內(nèi)容在從庫(kù)上執(zhí)行。

4060931e-d88b-11ed-bfe3-dac502259ad0.png

上述過程都是異步操作,所以在某些涉及到大的變更,例如DDL改變字段,影響行數(shù)較大的寫入、更新或刪除操作都會(huì)導(dǎo)致主從間的延遲激增,針對(duì)延遲的場(chǎng)景,高版本的MySQL逐步引入了一些新的特性來幫助提高事務(wù)在從庫(kù)重放的速度。

Relay Log的意義

Relay log在本質(zhì)上可以認(rèn)為和binlog是等同的日志文件,即使是直接在本地打開兩者也只能發(fā)現(xiàn)很少的差異;

Binlog Version 3 (MySQL 4.0.2 - < 5.0.0)

added the relay logs and changed the meaning of the log position

在MySQL 4.0 之前是沒有Relay Log這部分的,整個(gè)過程中只有兩個(gè)線程。但是這樣也帶來一個(gè)問題,那就是復(fù)制的過程需要同步的進(jìn)行,很容易被影響,而且效率不高。例如主庫(kù)必須要等待從庫(kù)讀取完了才能發(fā)送下一個(gè)binlog事件。這就有點(diǎn)類似于一個(gè)阻塞的信道和非阻塞的信道。

在流程中新增Relay Log中繼日志后,讓原本同步的獲取事件、重放事件解耦了,兩個(gè)步驟可以異步的進(jìn)行,Relay Log充當(dāng)了緩沖區(qū)的作用。Relay Log包含一個(gè)relay-log.info的文件,用于記錄當(dāng)前復(fù)制的進(jìn)度,下一個(gè)事件從什么Pos開始寫入,該文件由SQL線程負(fù)責(zé)更新。

對(duì)于后續(xù)逐漸引入的特殊復(fù)制模式,會(huì)存在一些差異,但整體來說,是按照這個(gè)流程來完成的。

2.3.2半同步復(fù)制

異步復(fù)制的場(chǎng)景下,不能確保從庫(kù)實(shí)時(shí)更新到和主庫(kù)一致的狀態(tài),那么如果在出現(xiàn)延遲的背景下發(fā)生主庫(kù)故障,那么兩者間的差異數(shù)據(jù)還是無法進(jìn)行保障,同時(shí)也無法在這種情況下進(jìn)行讀寫分離,而如果說由異步改為完全同步,那么性能開銷上又會(huì)大幅提高,很難滿足實(shí)際使用的需求。

基于這一的背景,MySQL從5.5版本開始引入了半同步復(fù)制機(jī)制來降低數(shù)據(jù)丟失的概率,在這種復(fù)制模式中,MySQL讓Master在某一個(gè)時(shí)間點(diǎn)等待一個(gè)Slave節(jié)點(diǎn)的 ACK(Acknowledge Character)消息,接收到ACK消息后才進(jìn)行事務(wù)提交,這樣既可以減少對(duì)性能的影響,還可以相對(duì)異步復(fù)制獲得更強(qiáng)的數(shù)據(jù)可靠性。

介紹半同步復(fù)制之前先快速過一下 MySQL 事務(wù)寫入碰到主從復(fù)制時(shí)的完整過程,主庫(kù)事務(wù)寫入分為 4個(gè)步驟:

InnoDB Redo File Write (Prepare Write)

Binlog File Flush & Sync to Binlog File

InnoDB Redo File Commit(Commit Write)

Send Binlog to Slave

當(dāng)Master不需要關(guān)注Slave是否接受到Binlog Event時(shí),即為異步主從復(fù)制

當(dāng)Master需要在第3步Commit Write回復(fù)客戶端前等待Slave的ACK時(shí),為半同步復(fù)制(after-commit)

當(dāng)Master需要在第2步Flush&Sync,即Commit前等待Slave的ACK時(shí),為增強(qiáng)半同步復(fù)制(after-sync)

時(shí)序關(guān)系

從半同步復(fù)制的時(shí)序圖來看,實(shí)際上只是在主庫(kù)Commit的環(huán)節(jié)多了等待接收從庫(kù)ACK的階段,這里只需要收到一個(gè)從節(jié)點(diǎn)的ACK即可繼續(xù)正常的處理流程,這種模式下,即使主庫(kù)宕機(jī)了,也能至少保證有一個(gè)從庫(kù)節(jié)點(diǎn)是可以用的,此外還減少了同步時(shí)的等待時(shí)間。

406c7f08-d88b-11ed-bfe3-dac502259ad0.png

2.3.3 小結(jié)

在當(dāng)前生產(chǎn)環(huán)境的在線數(shù)據(jù)庫(kù)版本背景下,由MySQL官方提供的復(fù)制方式主要如上文介紹的內(nèi)容,當(dāng)然目前有還很多基于MySQL或兼容MySQL的衍生數(shù)據(jù)庫(kù)產(chǎn)品,能在可用性和可靠性上做更大的提升,本文就不繼續(xù)展開這部分的描述。

2.4 復(fù)制的特性

目前已經(jīng)提及的復(fù)制方式,存在一個(gè)顯著的特性:無法回避數(shù)據(jù)延遲的場(chǎng)景,異步復(fù)制會(huì)使得從庫(kù)的數(shù)據(jù)落后,而半同步復(fù)制則會(huì)阻塞主庫(kù)的寫入,影響性能。

MySQL早期的復(fù)制模式中,從庫(kù)的IO線程和SQL線程本質(zhì)上都是串行獲取事件并讀取重放的,只有一個(gè)線程負(fù)責(zé)執(zhí)行Relaylog,但主庫(kù)本身接收請(qǐng)求是可以并發(fā)地,性能上限只取決于機(jī)器資源瓶頸和MySQL處理能力的上限,主庫(kù)的執(zhí)行和從庫(kù)的執(zhí)行(SQL線程應(yīng)用事件)是很難對(duì)齊的,這里引用一組測(cè)試數(shù)據(jù):

機(jī)器:64核 256G,MySQL 5.7.29

測(cè)試場(chǎng)景:常規(guī)的INSERT,UPDATE壓測(cè)場(chǎng)景

結(jié)果:MySQL Server的IO線程速度以網(wǎng)絡(luò)上的數(shù)據(jù)量評(píng)估,每秒超過100MB,正常是可以覆蓋業(yè)務(wù)使用的,然而SQL線程的預(yù)估速度只有21~23MB/s,如果是涉及UPDATE場(chǎng)景,性能還會(huì)減少;

需要注意的是,以上結(jié)果是在高版本的MySQL具備并行復(fù)制能力的前提下取得,如果是不具備該特性的版本,性能會(huì)更差。

期望業(yè)務(wù)層限制使用是不現(xiàn)實(shí)的,MySQL則在5.6版本開始嘗試引入可用的并行復(fù)制方案,總的來說,都是通過嘗試加強(qiáng)在從庫(kù)層面的應(yīng)用速度的方式。

2.4.1 基于Schema級(jí)別的并行復(fù)制

基于庫(kù)級(jí)別的并行復(fù)制是出于一個(gè)非常簡(jiǎn)易的原則,實(shí)例中不同Database/Schema內(nèi)的數(shù)據(jù)以及數(shù)據(jù)變更是無關(guān)的,可以并行去處置。

在這種模式中,MySQL的從節(jié)點(diǎn)會(huì)啟動(dòng)多個(gè)WorkThread ,而原來負(fù)責(zé)回放的SQLThread會(huì)轉(zhuǎn)變成Coordinator角色,負(fù)責(zé)判斷事務(wù)能否并行執(zhí)行并分發(fā)給WorkThread。

如果事務(wù)分別屬于不同的Schema,并且不是DDL語句,同時(shí)沒有跨Schema操作,那么就可以并行回放,否則需要等所有Worker線程執(zhí)行完成后再執(zhí)行當(dāng)前日志中的內(nèi)容。

MySQLServer
 
MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aksay_record       |
| mysql              |
| performance_schema |
| proxy_encrypt      |
| sys                |
| test               |
+--------------------+
7 rows in set (0.06 sec)

對(duì)于從庫(kù)而言,如果接收到了來自主庫(kù)的aksay_record以及proxy_encrypt內(nèi)的數(shù)據(jù)變更,那么它是可以同時(shí)去處理這兩部分Schema的數(shù)據(jù)的。

但是這種方式也存在明顯缺陷和不足,首先只有多個(gè)Schema流量均衡的情況下才會(huì)有較大的性能改善,但如果存在熱點(diǎn)表或?qū)嵗现挥幸粋€(gè)Schema有數(shù)據(jù)變更,那么這種并行模式和早期的串行復(fù)制也不存在差異;同樣,雖然不同Schema的數(shù)據(jù)是沒有關(guān)聯(lián),這樣并行執(zhí)行也會(huì)影響事務(wù)的執(zhí)行順序,某種程度來說,整個(gè)Server的因果一致性被破壞了。

2.4.2基于組提交的復(fù)制(Group Commit)

基于Schema的并行復(fù)制在大部分場(chǎng)景是沒有效力的,例如一庫(kù)多表的情況下,但改變從庫(kù)的單執(zhí)行線程的思路被延續(xù)了下來,在5.7版本新增加了一種基于事務(wù)組提交的并行復(fù)制方式,在具體介紹應(yīng)用在復(fù)制中的組提交策略前,需要先介紹Server本身Innodb引擎提交事務(wù)的邏輯:

Binlog的落盤是基于sync_binlog的配置來的,正常情況都是取sync_binlog=1,即每次事務(wù)提交就發(fā)起fsync刷盤。

主庫(kù)在大規(guī)模并發(fā)執(zhí)行事務(wù)時(shí),因?yàn)槊總€(gè)事務(wù)都觸發(fā)加鎖落盤,反而使得所有的Binlog串行落盤,成為性能上的瓶頸。針對(duì)這個(gè)問題,MySQL本身在5.6版本引入了事務(wù)的組提交能力(這里并不是指在從庫(kù)上應(yīng)用的邏輯),設(shè)計(jì)原理很容易理解,只要是能在同一個(gè)時(shí)間取得資源,開啟Prepare的所有事務(wù),都是可以同時(shí)提交的。

在主庫(kù)具有這一能力的背景下,可以很容易得發(fā)現(xiàn)從庫(kù)也可以應(yīng)用相似的機(jī)制來并行地去執(zhí)行事務(wù),下面介紹MySQL具體實(shí)現(xiàn)經(jīng)歷的兩個(gè)階段:

基于Commit-Parents-Based

MySQL中寫入是基于鎖的并發(fā)控制,所以所有在Master端同時(shí)處于Prepare階段且未提交的事務(wù)就不會(huì)存在鎖沖突,在Slave端執(zhí)行時(shí)都可以并行執(zhí)行。

因此可以在所有的事務(wù)進(jìn)入prepare階段的時(shí)候標(biāo)記上一個(gè)logical timestamp(實(shí)現(xiàn)中使用上一個(gè)提交事務(wù)的sequence_number),在Slave端同樣timestamp的事務(wù)就可以并發(fā)執(zhí)行。

但這種模式會(huì)依賴上一個(gè)事務(wù)組的提交,如果本身是不受資源限制的并發(fā)事務(wù),卻會(huì)因?yàn)樗腸ommit-parent沒有提交而無法執(zhí)行;

基于Logic-Based

針對(duì)Commit-Parent-Based中存在的限制進(jìn)行了解除,純粹的理解就是只有當(dāng)前事務(wù)的sequence_number一致就可以并發(fā)執(zhí)行,只根據(jù)是否能取得鎖且無沖突的情況即可以并發(fā)執(zhí)行,而不是依賴上一個(gè)已提交事務(wù)的sequence_number。

三、應(yīng)用

當(dāng)前vivo的在線MySQL數(shù)據(jù)庫(kù)服務(wù)標(biāo)準(zhǔn)架構(gòu)是基于一主一從一離線的異步復(fù)制集群,其中一從用于業(yè)務(wù)讀請(qǐng)求分離,離線節(jié)點(diǎn)不提供讀服務(wù),提供給大數(shù)據(jù)離線和實(shí)時(shí)抽數(shù)/DB平臺(tái)查詢以及備份系統(tǒng)使用;針對(duì)這樣的應(yīng)用背景,存儲(chǔ)研發(fā)組針對(duì)MySQL場(chǎng)景提供了兩種額外的擴(kuò)展服務(wù):

3.1應(yīng)用高可用系統(tǒng)+中間件

雖然MySQL的主從復(fù)制可以提高系統(tǒng)的高可用性,但是MySQL在5.6,5.7版本是不具備類似Redis的自動(dòng)故障轉(zhuǎn)移的能力,如果主庫(kù)宕機(jī)后不進(jìn)行干預(yù),業(yè)務(wù)實(shí)際上是無法正常寫入的,故障時(shí)間較長(zhǎng)的情況下,分離在從庫(kù)上的讀也會(huì)變得不可靠。

3.1.1 VSQL(原高可用2.0架構(gòu))

那么在當(dāng)前這樣標(biāo)準(zhǔn)一主二從架構(gòu)的基礎(chǔ)上,為系統(tǒng)增加HA高可用組件以及中間件組件強(qiáng)化MySQL服務(wù)的高可用性、讀拓展性、數(shù)據(jù)可靠性:

HA組件管理MySQL的復(fù)制拓?fù)?,?fù)責(zé)監(jiān)控集群的健康狀態(tài),管理故障場(chǎng)景下的自動(dòng)故障轉(zhuǎn)移;

中間件Proxy用于管理流量,應(yīng)對(duì)原有域名場(chǎng)景下變更解析慢或緩存不生效的問題,控制讀寫分離、實(shí)現(xiàn)IP、SQL的黑白名單等;

4073e450-d88b-11ed-bfe3-dac502259ad0.png

3.1.2數(shù)據(jù)可靠性強(qiáng)化

數(shù)據(jù)本身還是依賴MySQL原生的主從復(fù)制模式在集群中同步,這樣仍然存在異步復(fù)制本身的風(fēng)險(xiǎn),發(fā)生主庫(kù)宕機(jī)時(shí),如果從庫(kù)上存在還未接收到的主庫(kù)數(shù)據(jù),這部分就會(huì)丟失,針對(duì)這個(gè)場(chǎng)景,我們提供了三種可行的方案:

日志遠(yuǎn)程復(fù)制

配置HA的中心節(jié)點(diǎn)和全網(wǎng)MySQL機(jī)器的登錄機(jī)器后,按照經(jīng)典的MHA日志文件復(fù)制補(bǔ)償方案來保障故障時(shí)的數(shù)據(jù)不丟失,操作上即HA節(jié)點(diǎn)會(huì)訪問故障節(jié)點(diǎn)的本地文件目錄讀取候選主節(jié)點(diǎn)缺失的Binlog數(shù)據(jù)并在候選主上重放。

優(yōu)勢(shì)

與1.0的MHA方案保持一致,可以直接使用舊的機(jī)制

機(jī)制改造后可以混合在高可用的能力內(nèi),不需要機(jī)器間的免密互信,降低權(quán)限需求和安全風(fēng)險(xiǎn)

劣勢(shì)

不一定可用,需要故障節(jié)點(diǎn)所在機(jī)器可訪達(dá)且硬盤正常,無法應(yīng)對(duì)硬件或網(wǎng)絡(luò)異常的情況

網(wǎng)絡(luò)上鏈路較長(zhǎng),可能無法控制中間重放日志的耗時(shí),導(dǎo)致服務(wù)較長(zhǎng)時(shí)間不可用

407c89f2-d88b-11ed-bfe3-dac502259ad0.png

日志集中存儲(chǔ)

依賴數(shù)據(jù)傳輸服務(wù)中的BinlogServer模塊,提供Binlog日志的集中存儲(chǔ)能力,HA組件同時(shí)管理MySQL集群以及BinlogServer,強(qiáng)化MySQL架構(gòu)的健壯性,真實(shí)從庫(kù)的復(fù)制關(guān)系全部建立在BinlogServer上,不直接連接主庫(kù)。

優(yōu)勢(shì)

可以自定義日志的存儲(chǔ)形式:文件系統(tǒng)或其它共享存儲(chǔ)模式

不涉及機(jī)器可用和權(quán)限的問題

間接提高binlog的保存安全性(備份)

劣勢(shì)

額外的資源使用,如果需要保留較長(zhǎng)時(shí)間的日志,資源使用量較大

如果不開啟半同步,也不能保證所有的binlog日志都能被采集到,即使采集(相當(dāng)于IO線程)速度遠(yuǎn)超relay速度,極限約110MB/s

系統(tǒng)復(fù)雜度提升,需要承受引入額外鏈路的風(fēng)險(xiǎn)

改變?yōu)榘胪綇?fù)制

MySQL集群開啟半同步復(fù)制,通過配置防止退化(風(fēng)險(xiǎn)較大),Agent本身支持半同步集群的相關(guān)監(jiān)控,可以減少故障切換時(shí)日志丟失的量(相比異步復(fù)制)

優(yōu)勢(shì)

MySQL原生的機(jī)制,不需要引入額外的風(fēng)險(xiǎn)

本質(zhì)上就是在強(qiáng)化高可用的能力(MySQL集群本身)

HA組件可以無縫接入開啟半同步的集群,不需要任何改造

劣勢(shì)

存在不兼容的版本,不一定可以開啟

業(yè)務(wù)可能無法接受性能下降的后果

半同步不能保證完全不丟數(shù)據(jù),Agent本身機(jī)制實(shí)際上是優(yōu)先選擇“執(zhí)行最多”的從節(jié)點(diǎn)而不是“日志最多”的從節(jié)點(diǎn)

orchestrator will promote the replica which has executed more events rather than the replica which has more data in the relay logs.

目前來說,我們采用的是日志遠(yuǎn)程復(fù)制的方案,同時(shí)今年在規(guī)劃集中存儲(chǔ)的BinlogServer方案來強(qiáng)化數(shù)據(jù)安全性;不過值得一提的是,半同步也是一種有效可行的方式,對(duì)于讀多寫少的業(yè)務(wù)實(shí)際上是可以考慮升級(jí)集群的能力,這樣本質(zhì)上也可以保證分離讀流量的準(zhǔn)確性。

3.2數(shù)據(jù)傳輸服務(wù)

3.2.1 基于Binlog的跨系統(tǒng)數(shù)據(jù)流轉(zhuǎn)

通過利用Binlog,實(shí)時(shí)地將MySQL的數(shù)據(jù)流轉(zhuǎn)到其它系統(tǒng),包括MySQL,ElasticSearch,Kafka等MQ已經(jīng)是一種非常經(jīng)典的應(yīng)用場(chǎng)景了,MySQL原生提供的這種變化數(shù)據(jù)同步的能力使其可以有效地在各個(gè)系統(tǒng)間實(shí)時(shí)聯(lián)動(dòng),DTS(數(shù)據(jù)傳輸服務(wù))針對(duì)MySQL的采集也是基于和前文介紹的復(fù)制原理一致的方法,這里介紹我們是如何利用和MySQL 從節(jié)點(diǎn)相同的機(jī)制去獲取數(shù)據(jù)的,也是對(duì)于完整開啟復(fù)制的拓展介紹:

(1)如何獲取Binlog

比較常規(guī)的方式有兩種:

監(jiān)聽Binlog文件,類似日志采集系統(tǒng)的操作

MySQL Slave的機(jī)制,采集者偽裝成Slave來實(shí)現(xiàn)

本文只介紹第二種,F(xiàn)ake Slave的實(shí)現(xiàn)方式

40874a90-d88b-11ed-bfe3-dac502259ad0.jpg

(2)注冊(cè)Slave身份

這里以GO SDK為例,GO的byte范圍是0~255,其它語言做對(duì)應(yīng)轉(zhuǎn)換即可。

data := make([]byte, 4+1+4+1+len(hostname)+1+len(b.cfg.User)+1+len(b.cfg.Password)+2+4+4)

第0-3位為0,無意義

第4位是MySQL協(xié)議中的Command_Register_Slave,byte值為21

第5-8位是當(dāng)前實(shí)例預(yù)設(shè)的server_id(非uuid,是一個(gè)數(shù)值)使用小端編碼成的4個(gè)字節(jié)

接下來的若干位是把當(dāng)前實(shí)例的hostname,user,password

接下來的2位是小端編碼的port端口

最后8位一般都置為0,其中最后4位指master_id,偽裝slave設(shè)置為0即可

(3)發(fā)起復(fù)制指令

data := make([]byte, 4+1+4+2+4+len(p.Name))

40968316-d88b-11ed-bfe3-dac502259ad0.png

第0-3位同樣置為0,無特殊意義

第4位是MySQL協(xié)議的Command_Binlog_Dump,byte值為18

第5-8位是Binlog Position值的小端序編碼產(chǎn)生的4位字節(jié)

第9-10位是MySQL Dump的類別,默認(rèn)是0,指Binlog_Dump_Never_Stop,即編碼成2個(gè)0值

第11-14位是實(shí)例的server_id(非uuid)基于小端編碼的四個(gè)字節(jié)值

最后若干位即直接追加Binlog File名稱

以上兩個(gè)命令通過客戶端連接執(zhí)行后,就可以在主庫(kù)上觀察到一個(gè)有效的復(fù)制連接。

40a098ec-d88b-11ed-bfe3-dac502259ad0.png

3.2.2 利用并行復(fù)制模式提升性能

以上兩個(gè)命令通過客戶端連接執(zhí)行后,就可以在主庫(kù)上觀察到一個(gè)有效的復(fù)制連接。

根據(jù)早期的性能測(cè)試結(jié)果,不做任何優(yōu)化,直接單連接重放源集群數(shù)據(jù),在網(wǎng)絡(luò)上的平均傳輸速度在7.3MB/s左右,即使是和MySQL的SQL Relay速度相比也是相差很遠(yuǎn),在高壓場(chǎng)景下很難滿足需求。

DTS消費(fèi)單元實(shí)現(xiàn)了對(duì)消費(fèi)自kafka的事件的事務(wù)重組以及并發(fā)的事務(wù)解析工作,但實(shí)際最終執(zhí)行還是串行單線程地向MySQL回放,這一過程使得性能瓶頸完全集中在了串行執(zhí)行這一步驟。

MySQL 5.7版本以前,會(huì)利用事務(wù)的Schema屬性,使不同db下的DML操作可以在備庫(kù)并發(fā)回放。在優(yōu)化后,可以做到不同表table下并發(fā)。但是如果業(yè)務(wù)在Master端高并發(fā)寫入一個(gè)庫(kù)(或者優(yōu)化后的表),那么slave端就會(huì)出現(xiàn)較大的延遲。基于schema的并行復(fù)制,Slave作為只讀實(shí)例提供讀取功能時(shí)候可以保證同schema下事務(wù)的因果序(Causal Consistency,本文討論Consistency的時(shí)候均假設(shè)Slave端為只讀),而無法保證不同schema間的。例如當(dāng)業(yè)務(wù)關(guān)注事務(wù)執(zhí)行先后順序時(shí)候,在Master端db1寫入T1,收到T1返回后,才在db2執(zhí)行T2。但在Slave端可能先讀取到T2的數(shù)據(jù),才讀取到T1的數(shù)據(jù)。

MySQL 5.7的LOGICAL CLOCK并行復(fù)制,解除了schema的限制,使得在主庫(kù)對(duì)一個(gè)db或一張表并發(fā)執(zhí)行的事務(wù)到slave端也可以并行執(zhí)行。Logical Clock并行復(fù)制的實(shí)現(xiàn),最初是Commit-Parent-Based方式,同一個(gè)commit parent的事務(wù)可以并發(fā)執(zhí)行。但這種方式會(huì)存在可以保證沒有沖突的事務(wù)不可以并發(fā),事務(wù)一定要等到前一個(gè)commit parent group的事務(wù)全部回放完才能執(zhí)行。后面優(yōu)化為L(zhǎng)ock-Based方式,做到只要事務(wù)和當(dāng)前執(zhí)行事務(wù)的Lock Interval都存在重疊,即保證了Master端沒有鎖沖突,就可以在Slave端并發(fā)執(zhí)行。LOGICAL CLOCK可以保證非并發(fā)執(zhí)行事務(wù),即當(dāng)一個(gè)事務(wù)T1執(zhí)行完后另一個(gè)事務(wù)T2再開始執(zhí)行場(chǎng)景下的Causal Consistency。

(1)連接池改造

舊版的DTS的每一個(gè)消費(fèi)任務(wù)只有一條維持的MySQL長(zhǎng)連接,該消費(fèi)鏈路的所有的事務(wù)都在這條長(zhǎng)連接上串行執(zhí)行,產(chǎn)生了極大的性能瓶頸,那么考慮到并發(fā)執(zhí)行事務(wù)的需求,不可能對(duì)連接進(jìn)行并發(fā)復(fù)用,所以需要改造原本的單連接對(duì)象,提升到近似連接池的機(jī)制。

go-mysql/client包本身不包含連接池模式,這里基于事務(wù)并發(fā)解析的并發(fā)度在啟動(dòng)時(shí),擴(kuò)展存活連接的數(shù)量。

// 初始化客戶端連接數(shù)
se.conn = make([]*Connection, meta.MaxConcurrenceTransaction)

(2)并發(fā)選擇連接

利用邏輯時(shí)鐘

開啟GTID復(fù)制的模式下,binlog中的GTID_EVENT的正文內(nèi)會(huì)包含兩個(gè)值:

LastCommitted  int64
SequenceNumber int64

lastCommitted是我們并發(fā)的依據(jù),原則上,LastCommitted相等事務(wù)可以并發(fā)執(zhí)行,結(jié)合原本事務(wù)并發(fā)解析完成后會(huì)產(chǎn)生并發(fā)度(配置值)數(shù)量的事務(wù)集合,那么對(duì)這個(gè)列表進(jìn)行分析判斷,進(jìn)行事務(wù)到連接池的分配,實(shí)現(xiàn)一種近似負(fù)載均衡的機(jī)制。

非并發(fā)項(xiàng)互斥

對(duì)于并發(fā)執(zhí)行的場(chǎng)景,可以比較簡(jiǎn)單地使用類似負(fù)載均衡的機(jī)制,從連接池中遍歷mysql connection執(zhí)行對(duì)應(yīng)的事務(wù);但需要注意到的是,源的事務(wù)本身是具有順序的,在logical-clock的場(chǎng)景下,存在部分并發(fā)prepare的事務(wù)是可以被并發(fā)執(zhí)行的,但仍然有相當(dāng)一部分的事務(wù)是不可并發(fā)執(zhí)行,它們顯然是分散于整個(gè)事務(wù)隊(duì)列中,可以認(rèn)為并發(fā)事務(wù)(最少2個(gè))是被不可并發(fā)事務(wù)包圍的:

假定存在一個(gè)事務(wù)隊(duì)列有6個(gè)元素,其中只有t1、t2和t5、t6可以并發(fā)執(zhí)行,那么執(zhí)行t3時(shí),需要t1、t2已經(jīng)執(zhí)行完畢,執(zhí)行t5時(shí)需要t3,t4都執(zhí)行完畢。

40c03dc8-d88b-11ed-bfe3-dac502259ad0.jpg

(3)校驗(yàn)點(diǎn)更新

在并發(fā)的事務(wù)執(zhí)行場(chǎng)景下,存在水位低的事務(wù)后執(zhí)行完,而水位高的事務(wù)先執(zhí)行完,那么依照原本的機(jī)制,更低的水位會(huì)覆蓋掉更高的水位,存在一定的風(fēng)險(xiǎn):

Write_Event的構(gòu)造SQL調(diào)整為replace into,可以回避沖突重復(fù)的寫事件;Update和Delete可以基于邏輯時(shí)鐘的并發(fā)保障,不會(huì)出現(xiàn)。

水位只會(huì)向上提升,不會(huì)向下降低。

但不論怎樣進(jìn)行優(yōu)化,并發(fā)執(zhí)行事務(wù)必然會(huì)引入更多的風(fēng)險(xiǎn),例如并發(fā)事務(wù)的回滾無法控制,目標(biāo)實(shí)例和源實(shí)例的因果一致性被破壞等,業(yè)務(wù)可以根據(jù)自身的需要進(jìn)行權(quán)衡,是否開啟并發(fā)的執(zhí)行。

基于邏輯時(shí)鐘并發(fā)執(zhí)行事務(wù)改造后,消費(fèi)端的執(zhí)行性能在同等的測(cè)試場(chǎng)景下,可以從7.3MB/s提升到13.4MB/s左右。

(4)小結(jié)

基于消費(fèi)任務(wù)本身的庫(kù)、表過濾,可以實(shí)現(xiàn)另一種形式下的并發(fā)執(zhí)行,可以啟動(dòng)復(fù)數(shù)的消費(fèi)任務(wù)分別支持不同的庫(kù)、表,這也是利用了kafka的多消費(fèi)者組支持,可以橫向擴(kuò)展以提高并發(fā)性能,適用于數(shù)據(jù)遷移場(chǎng)景,這一部分可以專門提供支持。

而基于邏輯時(shí)鐘的方式,對(duì)于目前現(xiàn)網(wǎng)大規(guī)模存在的未開啟GTID的集群是無效的,所以這一部分我們也一直在尋找更優(yōu)的解決方案,例如更高版本的特性Write Set的合并等,繼續(xù)做性能優(yōu)化。

四、總結(jié)

最后,關(guān)于MySQL的復(fù)制能力不僅對(duì)于MySQL數(shù)據(jù)庫(kù)服務(wù)本身的可用性、可靠性有巨大的提升,也提供了Binlog這一非常靈活的開放式的數(shù)據(jù)接口用于擴(kuò)展數(shù)據(jù)的應(yīng)用范圍,通過利用這個(gè)“接口”,很容易就可以達(dá)成數(shù)據(jù)在多個(gè)不同存儲(chǔ)結(jié)構(gòu)、環(huán)境的實(shí)時(shí)同步,未來存儲(chǔ)組也將會(huì)聚焦于BinlogServer這一擴(kuò)展服務(wù)來強(qiáng)化MySQL的架構(gòu),包括但不限于數(shù)據(jù)安全性保障以及對(duì)下游數(shù)據(jù)鏈路的開放等。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • DTS
    DTS
    +關(guān)注

    關(guān)注

    1

    文章

    50

    瀏覽量

    16413
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    849

    瀏覽量

    27653
  • DDL
    DDL
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    6456
  • MYSQL數(shù)據(jù)庫(kù)

    關(guān)注

    0

    文章

    96

    瀏覽量

    9806

原文標(biāo)題:MySQL主從復(fù)制原理剖析與應(yīng)用實(shí)踐

文章出處:【微信號(hào):OSC開源社區(qū),微信公眾號(hào):OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    介紹三種常見的MySQL高可用方案

    在生產(chǎn)環(huán)境中,為了確保數(shù)據(jù)庫(kù)系統(tǒng)的連續(xù)可用性、降低故障恢復(fù)時(shí)間以及實(shí)現(xiàn)業(yè)務(wù)的無縫切換,高可用(High Availability, HA)方案至關(guān)重要。本文將詳細(xì)介紹三種常見的 MySQL 高可用
    的頭像 發(fā)表于 05-28 17:16 ?224次閱讀

    利用dockerfile搭建mysql主從集群和redis集群

    ==MySQL主從同步(Replication)是一種實(shí)現(xiàn)數(shù)據(jù)冗余和高可用性的技術(shù),通過將主數(shù)據(jù)庫(kù)(Master)的變更操作同步到一個(gè)或多個(gè)從數(shù)據(jù)庫(kù)(Slave),實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)或準(zhǔn)實(shí)時(shí)復(fù)制
    的頭像 發(fā)表于 05-14 11:38 ?322次閱讀
    利用dockerfile搭建<b class='flag-5'>mysql</b>主從集群和redis集群

    Java的SPI機(jī)制詳解

    接口規(guī)范以及可以發(fā)現(xiàn)接口實(shí)現(xiàn)機(jī)制,而不需要實(shí)現(xiàn)接口。 SPI機(jī)制在Java中應(yīng)用廣泛。例如:JDBC中的數(shù)據(jù)庫(kù)連接驅(qū)動(dòng)使用SPI機(jī)制,只定
    的頭像 發(fā)表于 03-05 11:35 ?705次閱讀
    Java的SPI<b class='flag-5'>機(jī)制</b>詳解

    hyper v 復(fù)制,hyper v 復(fù)制如何操作

    工作效率。今天就為大家介紹hyperv復(fù)制如何操作。 ? ?Hyper-V提供了多種方法來實(shí)現(xiàn)文件復(fù)制和共享,以下是幾種常見的操作方法: ? ?方法一:通過網(wǎng)絡(luò)共享復(fù)制文件 ? ?在主
    的頭像 發(fā)表于 01-22 16:01 ?1019次閱讀
    hyper v <b class='flag-5'>復(fù)制</b>,hyper v <b class='flag-5'>復(fù)制</b>如何操作

    適用于MySQL的dbExpress驅(qū)動(dòng)程序:提供對(duì)MySQL的快速訪問

    (包括社區(qū)版)快速訪問 MySQL,以及 macOS(32 位和 64 位)和 Linux(64 位)平臺(tái)。對(duì)于此服務(wù)器,dbExpress 將驅(qū)動(dòng)程序作為實(shí)現(xiàn)通用 dbExpress 的獨(dú)立庫(kù),提供用于
    的頭像 發(fā)表于 01-21 09:52 ?408次閱讀

    使用插件將Excel連接到MySQL/MariaDB

    使用插件將 Excel 連接到 MySQL/MariaDB 適用于 MySQL 的 Devart Excel 插件允許您將 Microsoft Excel 連接到 MySQL 或 MariaDB
    的頭像 發(fā)表于 01-20 12:38 ?546次閱讀
    使用插件將Excel連接到<b class='flag-5'>MySQL</b>/MariaDB

    MySQL數(shù)據(jù)庫(kù)的安裝

    MySQL數(shù)據(jù)庫(kù)的安裝 【一】各種數(shù)據(jù)庫(kù)的端口 MySQL :3306 Redis :6379 MongoDB :27017 Django :8000 flask :5000 【二】MySQL 介紹
    的頭像 發(fā)表于 01-14 11:25 ?516次閱讀
    <b class='flag-5'>MySQL</b>數(shù)據(jù)庫(kù)的安裝

    華為云 Flexus 云服務(wù)器 X 實(shí)例:在 openEuler 系統(tǒng)下搭建 MySQL 主從復(fù)制

    前言 本文將介紹如何在華為云 Flexus 云服務(wù)器 X 實(shí)例上,基于 openEuler 系統(tǒng)部署 MySQL 主從復(fù)制。MySQL 作為一款高性能且穩(wěn)定的開源關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),是眾多
    的頭像 發(fā)表于 12-30 09:11 ?467次閱讀
    華為云 Flexus 云服務(wù)器 X 實(shí)例:在 openEuler 系統(tǒng)下搭建 <b class='flag-5'>MySQL</b> 主從<b class='flag-5'>復(fù)制</b>

    MySQL還能跟上PostgreSQL的步伐嗎

    Percona 的老板 Peter Zaitsev最近發(fā)表一篇博客,討論了MySQL是否還能跟上PostgreSQL的腳步。Percona 作為MySQL 生態(tài)扛旗者,Percona 開發(fā)了知名
    的頭像 發(fā)表于 11-18 10:16 ?512次閱讀
    <b class='flag-5'>MySQL</b>還能跟上PostgreSQL的步伐嗎

    MySQL編碼機(jī)制原理

    前言 一位讀者在本地部署 MySQL 測(cè)試環(huán)境時(shí)碰到一個(gè)問題,我覺得挺有代表性的,所以寫篇文章介紹一下,看完相信你會(huì)對(duì) MySQL 的編碼機(jī)制有最本質(zhì)的了解,本文的目錄結(jié)構(gòu)如下 讀者問題簡(jiǎn)介
    的頭像 發(fā)表于 11-09 11:01 ?544次閱讀

    分布式服務(wù)高可用實(shí)現(xiàn)復(fù)制

    作者:京東保險(xiǎn) 王奕龍 1. 為什么需要復(fù)制 我們可以考慮如下問題: 當(dāng)數(shù)據(jù)量、讀取或?qū)懭胴?fù)載已經(jīng)超過了當(dāng)前服務(wù)器的處理能力,如何實(shí)現(xiàn)負(fù)載均衡? 希望在單臺(tái)服務(wù)器出現(xiàn)故障時(shí)仍能繼續(xù)工作,這該如何實(shí)現(xiàn)
    的頭像 發(fā)表于 10-29 11:27 ?898次閱讀
    分布式服務(wù)高可用<b class='flag-5'>實(shí)現(xiàn)</b>:<b class='flag-5'>復(fù)制</b>

    配置MySQL主從復(fù)制和讀寫分離

    配置MySQL主從復(fù)制和讀寫分離
    的頭像 發(fā)表于 10-23 11:44 ?770次閱讀
    配置<b class='flag-5'>MySQL</b>主從<b class='flag-5'>復(fù)制</b>和讀寫分離

    單片機(jī)的中斷機(jī)制

    單片機(jī)的中斷機(jī)制是一種重要的處理方式,它允許單片機(jī)在執(zhí)行主程序的過程中,能夠暫停當(dāng)前任務(wù),轉(zhuǎn)而處理外部或內(nèi)部緊急事件。這種機(jī)制極大地提高了系統(tǒng)的響應(yīng)速度和處理能力,使得單片機(jī)在各種應(yīng)用領(lǐng)域中得到廣泛應(yīng)用。以下是對(duì)單片機(jī)中斷
    的頭像 發(fā)表于 10-17 18:03 ?1858次閱讀

    一文了解MySQL索引機(jī)制

    接觸MySQL數(shù)據(jù)庫(kù)的小伙伴一定避不開索引,索引的出現(xiàn)是為了提高數(shù)據(jù)查詢的效率,就像書的目錄一樣。 某一個(gè)SQL查詢比較慢,你第一時(shí)間想到的就是“給某個(gè)字段加個(gè)索引吧”,那么索引是什么?是如何工作
    的頭像 發(fā)表于 07-25 14:05 ?538次閱讀
    一文了解<b class='flag-5'>MySQL</b>索引<b class='flag-5'>機(jī)制</b>

    如何實(shí)現(xiàn)Python復(fù)制文件操作

    Python 中有許多“開蓋即食”的模塊(比如 os,subprocess 和 shutil)以支持文件 I/O 操作。在這篇文章中,你將會(huì)看到一些用 Python 實(shí)現(xiàn)文件復(fù)制的特殊方法。下面我們開始學(xué)習(xí)這九種不同的方法來實(shí)現(xiàn)
    的頭像 發(fā)表于 07-18 14:53 ?732次閱讀

    電子發(fā)燒友

    中國(guó)電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品