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

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

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

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

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

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

一、背景

MySQL在生產(chǎn)環(huán)境中被廣泛地應(yīng)用,大量的應(yīng)用和服務(wù)都對(duì)MySQL服務(wù)存在重要的依賴(lài)關(guān)系,可以說(shuō)如果數(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ù)的寫(xiě)入數(shù)據(jù)會(huì)持續(xù)地在冗余的從庫(kù)節(jié)點(diǎn)上被執(zhí)行保留,減少數(shù)據(jù)丟失的風(fēng)險(xiǎn)

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

當(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ù)制的能力來(lái)提升數(shù)據(jù)庫(kù)的可用性,可靠性等。

二、復(fù)制的原理

2.1 Binlog 的引入

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

Statement:基于語(yǔ)句格式

Statement模式下,復(fù)制過(guò)程中向獲取數(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ù)行的變更記錄來(lái)對(duì)應(yīng)地修改數(shù)據(jù),但DDL類(lèi)型的操作依然是以Statement的格式記錄。

Mixed:基于混合語(yǔ)句和行格式

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

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

這三種模式各有優(yōu)劣,相對(duì)來(lái)說(shuō),基于Row的行格式被應(yīng)用的更廣泛,雖然這種模式下對(duì)資源的開(kāi)銷(xiāo)會(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事件類(lèi)型

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

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

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

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

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

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

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

除了上面和數(shù)據(jù)更貼近的事件類(lèi)型外,還有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ù)覆寫(xiě)文件,Server會(huì)根據(jù)配置的單個(gè)Binlog文件大小配置不斷地切分并產(chǎn)生新的Binlog,在一個(gè).index文件記錄當(dāng)前硬盤(pán)上所有的binlog文件名,同時(shí)根據(jù)Binlog過(guò)期時(shí)間回收刪除掉過(guò)期的Binlog文件,這兩個(gè)在目前自建數(shù)據(jù)庫(kù)的配置為單個(gè)大小1G,保留7天。

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

2.2.3Binlog事件示例

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

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

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

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

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

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

FILE Position

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

File: binlog.000001
Position: 381808617

這個(gè)概念相對(duì)來(lái)說(shuō)更直觀,可以直接理解為當(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)值。

基于這種模式開(kāi)啟復(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ù)完全取決于有效的開(kāi)啟點(diǎn),那么如果存在偏差,就會(huì)丟失或執(zhí)行重復(fù)數(shù)據(jù)導(dǎo)致復(fù)制中斷。

GTID

MySQL 會(huì)在開(kāi)啟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開(kāi)啟了復(fù)制,那么在從庫(kù)自身執(zhí)行show master status也是會(huì)看到相同的值。

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

基于這種模式開(kāi)啟復(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)開(kāi)啟了binlog( log_bin = ON ),并正常地記錄binlog,如何開(kāi)啟復(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之后將其寫(xiě)入到自己的Relay Log中。

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

總結(jié)來(lái)說(shuō),主庫(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è)過(guò)程中將會(huì)按照下述的數(shù)據(jù)流轉(zhuǎn)方式:

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

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

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

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

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

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

Relay Log的意義

Relay log在本質(zhì)上可以認(rèn)為和binlog是等同的日志文件,即使是直接在本地打開(kāi)兩者也只能發(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 之前是沒(méi)有Relay Log這部分的,整個(gè)過(guò)程中只有兩個(gè)線程。但是這樣也帶來(lái)一個(gè)問(wèn)題,那就是復(fù)制的過(guò)程需要同步的進(jìn)行,很容易被影響,而且效率不高。例如主庫(kù)必須要等待從庫(kù)讀取完了才能發(fā)送下一個(gè)binlog事件。這就有點(diǎn)類(lèi)似于一個(gè)阻塞的信道和非阻塞的信道。

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

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

2.3.2半同步復(fù)制

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

基于這一的背景,MySQL從5.5版本開(kāi)始引入了半同步復(fù)制機(jī)制來(lái)降低數(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ù)制之前先快速過(guò)一下 MySQL 事務(wù)寫(xiě)入碰到主從復(fù)制時(shí)的完整過(guò)程,主庫(kù)事務(wù)寫(xiě)入分為 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í)序圖來(lái)看,實(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ù)展開(kāi)這部分的描述。

2.4 復(fù)制的特性

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

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)估,每秒超過(guò)100MB,正常是可以覆蓋業(yè)務(wù)使用的,然而SQL線程的預(yù)估速度只有21~23MB/s,如果是涉及UPDATE場(chǎng)景,性能還會(huì)減少;

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

期望業(yè)務(wù)層限制使用是不現(xiàn)實(shí)的,MySQL則在5.6版本開(kāi)始嘗試引入可用的并行復(fù)制方案,總的來(lái)說(shuō),都是通過(guò)嘗試加強(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ù)變更是無(wú)關(guān)的,可以并行去處置。

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

如果事務(wù)分別屬于不同的Schema,并且不是DDL語(yǔ)句,同時(shí)沒(méi)有跨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ù)而言,如果接收到了來(lái)自主庫(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ù)是沒(méi)有關(guān)聯(lián),這樣并行執(zhí)行也會(huì)影響事務(wù)的執(zhí)行順序,某種程度來(lái)說(shuō),整個(gè)Server的因果一致性被破壞了。

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

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

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

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

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

基于Commit-Parents-Based

MySQL中寫(xiě)入是基于鎖的并發(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ì)依賴(lài)上一個(gè)事務(wù)組的提交,如果本身是不受資源限制的并發(fā)事務(wù),卻會(huì)因?yàn)樗腸ommit-parent沒(méi)有提交而無(wú)法執(zhí)行;

基于Logic-Based

針對(duì)Commit-Parent-Based中存在的限制進(jìn)行了解除,純粹的理解就是只有當(dāng)前事務(wù)的sequence_number一致就可以并發(fā)執(zhí)行,只根據(jù)是否能取得鎖且無(wú)沖突的情況即可以并發(fā)執(zhí)行,而不是依賴(lài)上一個(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)查詢(xún)以及備份系統(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版本是不具備類(lèi)似Redis的自動(dòng)故障轉(zhuǎn)移的能力,如果主庫(kù)宕機(jī)后不進(jìn)行干預(yù),業(yè)務(wù)實(shí)際上是無(wú)法正常寫(xiě)入的,故障時(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)景下變更解析慢或緩存不生效的問(wèn)題,控制讀寫(xiě)分離、實(shí)現(xiàn)IP、SQL的黑白名單等;

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

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

數(shù)據(jù)本身還是依賴(lài)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ǔ)償方案來(lái)保障故障時(shí)的數(shù)據(jù)不丟失,操作上即HA節(jié)點(diǎn)會(huì)訪問(wèn)故障節(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á)且硬盤(pán)正常,無(wú)法應(yīng)對(duì)硬件或網(wǎng)絡(luò)異常的情況

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

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

日志集中存儲(chǔ)

依賴(lài)數(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)限的問(wèn)題

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

劣勢(shì)

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

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

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

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

MySQL集群開(kāi)啟半同步復(fù)制,通過(guò)配置防止退化(風(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組件可以無(wú)縫接入開(kāi)啟半同步的集群,不需要任何改造

劣勢(shì)

存在不兼容的版本,不一定可以開(kāi)啟

業(yè)務(wù)可能無(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.

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

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

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

通過(guò)利用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ì)于完整開(kāi)啟復(fù)制的拓展介紹:

(1)如何獲取Binlog

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

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

MySQL Slave的機(jī)制,采集者偽裝成Slave來(lái)實(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,其它語(yǔ)言做對(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,無(wú)意義

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

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

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

接下來(lái)的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,無(wú)特殊意義

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

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

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

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

最后若干位即直接追加Binlog File名稱(chēng)

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

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

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

以上兩個(gè)命令通過(guò)客戶端連接執(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回放,這一過(guò)程使得性能瓶頸完全集中在了串行執(zhí)行這一步驟。

MySQL 5.7版本以前,會(huì)利用事務(wù)的Schema屬性,使不同db下的DML操作可以在備庫(kù)并發(fā)回放。在優(yōu)化后,可以做到不同表table下并發(fā)。但是如果業(yè)務(wù)在Master端高并發(fā)寫(xiě)入一個(gè)庫(kù)(或者優(yōu)化后的表),那么slave端就會(huì)出現(xiàn)較大的延遲?;趕chema的并行復(fù)制,Slave作為只讀實(shí)例提供讀取功能時(shí)候可以保證同schema下事務(wù)的因果序(Causal Consistency,本文討論Consistency的時(shí)候均假設(shè)Slave端為只讀),而無(wú)法保證不同schema間的。例如當(dāng)業(yè)務(wù)關(guān)注事務(wù)執(zhí)行先后順序時(shí)候,在Master端db1寫(xiě)入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ì)存在可以保證沒(méi)有沖突的事務(wù)不可以并發(fā),事務(wù)一定要等到前一個(gè)commit parent group的事務(wù)全部回放完才能執(zhí)行。后面優(yōu)化為L(zhǎng)ock-Based方式,做到只要事務(wù)和當(dāng)前執(zhí)行事務(wù)的Lock Interval都存在重疊,即保證了Master端沒(méi)有鎖沖突,就可以在Slave端并發(fā)執(zhí)行。LOGICAL CLOCK可以保證非并發(fā)執(zhí)行事務(wù),即當(dāng)一個(gè)事務(wù)T1執(zhí)行完后另一個(gè)事務(wù)T2再開(kāi)始執(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í)鐘

開(kāi)啟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)單地使用類(lèi)似負(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ù)的寫(xiě)事件;Update和Delete可以基于邏輯時(shí)鐘的并發(fā)保障,不會(huì)出現(xiàn)。

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

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

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

(4)小結(jié)

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

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

四、總結(jié)

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






審核編輯:劉清

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

    關(guān)注

    1

    文章

    50

    瀏覽量

    16057
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    793

    瀏覽量

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

    關(guān)注

    0

    文章

    12

    瀏覽量

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

    關(guān)注

    0

    文章

    95

    瀏覽量

    9372

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

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

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

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

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

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

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

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

    MySQL忘記root密碼解決方案

    mysql登錄密碼為password()算法加密,解密成本太高,以下為通用方案; 原理:mysql提供了特殊啟動(dòng)方式,即跳過(guò)權(quán)限表驗(yàn)證,啟動(dòng)后,登錄不需要提供密碼; 登錄后,即可修改
    的頭像 發(fā)表于 04-23 16:08 ?592次閱讀

    查詢(xún)SQL在mysql內(nèi)部是如何執(zhí)行?

    我們知道在mySQL客戶端,輸入一條查詢(xún)SQL,然后看到返回查詢(xún)的結(jié)果。這條查詢(xún)語(yǔ)句在 MySQL 內(nèi)部到底是如何執(zhí)行的呢?本文跟大家探討一下哈,我們先來(lái)看下MySQL基本架構(gòu)~
    的頭像 發(fā)表于 01-22 14:53 ?481次閱讀
    查詢(xún)SQL在<b class='flag-5'>mysql</b>內(nèi)部是如何執(zhí)行?

    ad復(fù)制元件怎么保持編號(hào)不變

    瀏覽器”來(lái)創(chuàng)建和管理元件庫(kù)。在創(chuàng)建庫(kù)時(shí),為每個(gè)元件分配一個(gè)唯一的編號(hào),該編號(hào)將在復(fù)制過(guò)程中保持不變。 復(fù)制元件:選中要復(fù)制的元件,并使用“復(fù)制”命令或快捷鍵(Ctrl+C)將其
    的頭像 發(fā)表于 12-27 17:07 ?6291次閱讀

    mysql備份還原哪些方法

    MySQL是一個(gè)開(kāi)源的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),備份和還原是保證數(shù)據(jù)安全性和可恢復(fù)性的重要措施。本文將詳細(xì)介紹MySQL備份和還原的方法,包括物理備份和邏輯備份等多種方式,以及每種方式
    的頭像 發(fā)表于 11-23 14:35 ?928次閱讀

    docker部署mysql的壞處

    Docker 是一種虛擬化技術(shù),它允許開(kāi)發(fā)人員在容器內(nèi)打包應(yīng)用程序及其所有依賴(lài)項(xiàng),從而實(shí)現(xiàn)在不同環(huán)境中運(yùn)行相同的應(yīng)用程序的能力。然而,在使用 Docker 部署 MySQL 時(shí),也存在一些潛在
    的頭像 發(fā)表于 11-23 09:29 ?1292次閱讀

    mysql主從復(fù)制數(shù)據(jù)不一致怎么辦

    MySQL主從復(fù)制是一種常用的數(shù)據(jù)復(fù)制技術(shù),用于實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)同步和分布式部署。然而,在實(shí)際應(yīng)用中,主從復(fù)制過(guò)程中出現(xiàn)數(shù)據(jù)不一致的情況也是很
    的頭像 發(fā)表于 11-16 14:35 ?2067次閱讀

    mysql主從復(fù)制 混合類(lèi)型的復(fù)制

    MySQL主從復(fù)制是一種常用的數(shù)據(jù)復(fù)制技術(shù),可以實(shí)現(xiàn)數(shù)據(jù)從一個(gè)MySQL服務(wù)器(主服務(wù)器)復(fù)制
    的頭像 發(fā)表于 11-16 14:20 ?499次閱讀

    mysql主從復(fù)制的原理

    MySQL主從復(fù)制是一種數(shù)據(jù)庫(kù)復(fù)制技術(shù),它允許將一個(gè)MySQL數(shù)據(jù)庫(kù)的更新操作自動(dòng)復(fù)制到其他MySQL
    的頭像 發(fā)表于 11-16 14:18 ?431次閱讀

    mysql主從復(fù)制主要有幾種模式

    MySQL主從復(fù)制MySQL數(shù)據(jù)庫(kù)中常用的一種數(shù)據(jù)復(fù)制方式,用于實(shí)現(xiàn)數(shù)據(jù)的備份、負(fù)載均衡、故障
    的頭像 發(fā)表于 11-16 14:15 ?1093次閱讀

    mysql如何實(shí)現(xiàn)主從復(fù)制的具體流程

    主從復(fù)制MySQL數(shù)據(jù)庫(kù)中常用的數(shù)據(jù)復(fù)制技術(shù)之一,它的主要目的是將一個(gè)數(shù)據(jù)庫(kù)服務(wù)器上的數(shù)據(jù)復(fù)制到其他服務(wù)器上,以實(shí)現(xiàn)數(shù)據(jù)的備份、高可用和分
    的頭像 發(fā)表于 11-16 14:10 ?660次閱讀

    mysql主從復(fù)制三種模式

    MySQL主從復(fù)制是一種常見(jiàn)的數(shù)據(jù)同步方式,它可以實(shí)現(xiàn)將一個(gè)數(shù)據(jù)庫(kù)的更改同步到其他多個(gè)數(shù)據(jù)庫(kù)的功能。主從復(fù)制可以提高數(shù)據(jù)庫(kù)的可用性和性能,以
    的頭像 發(fā)表于 11-16 14:04 ?1340次閱讀

    MYSQL事務(wù)的底層原理詳解

    在事務(wù)的實(shí)現(xiàn)機(jī)制上,MySQL 采用的是 WAL:Write-ahead logging,預(yù)寫(xiě)式日志,機(jī)制來(lái)實(shí)現(xiàn)的。
    的頭像 發(fā)表于 11-15 10:10 ?524次閱讀
    <b class='flag-5'>MYSQL</b>事務(wù)的底層原理詳解