redo log(重做日志):
https://www.cnblogs.com/hapjin/archive/2019/09/28/11521506.html
https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html
redo log又稱重做日志文件,用于記錄事務(wù)操作的變化朝巫,記錄的是數(shù)據(jù)修改之后的值笙隙,不管事務(wù)是否提交都會記錄下來。在實例和介質(zhì)失斠惴谩(media failure)時,redo log文件就能派上用場盘榨,如數(shù)據(jù)庫掉電喻粹,InnoDB存儲引擎會使用redo log恢復(fù)到掉電前的時刻,以此來保證數(shù)據(jù)的完整性草巡。用于保證事務(wù)的完整性守呜。日志文件名如ib_logfile0,固定大小山憨,循環(huán)寫入查乒,具有crash safe的能力。
由參數(shù)innodb_log_file_size = 512M 和innodb_log_files_in_group?= 2控制郁竟,redo log file的大小對innodb的性能影響非常大玛迄,設(shè)置的太大,恢復(fù)的時候就會時間較長棚亩,設(shè)置的太小蓖议,就會導(dǎo)致在寫redo log的時候循環(huán)切換redo log file。
-rw-r----- 1 mysql mysql 512M Apr 13 13:13 ib_logfile0
-rw-r----- 1 mysql mysql 512M Apr 13 13:08 ib_logfile1
MySQL 的設(shè)計者就用了類似酒店掌柜粉板+賬本的思路來提升更新效率讥蟆。而粉板和賬本配合的整個過程勒虾,其實就是 MySQL 里經(jīng)常說到的 WAL 技術(shù)(Hbase、oracle等數(shù)據(jù)庫皆是如此)瘸彤,WAL 的全稱是 Write-Ahead Logging修然,它的關(guān)鍵點就是先寫日志,再寫磁盤质况,(其實日志也是寫磁盤低零,但是是追加寫,順序IO要比隨機IO快得多拯杠。redo log 主要節(jié)省的是隨機寫磁盤的 IO 消耗(轉(zhuǎn)成順序?qū)懱蜕簦瑫r還有一個組提交機制,降低IOPS)潭陪,而 change buffer 主要節(jié)省的則是隨機讀磁盤的 IO 消耗雄妥。)也就是先寫粉板最蕾,等不忙的時候再寫賬本。
具體來說老厌,當(dāng)有一條記錄需要更新的時候瘟则,InnoDB 引擎就會先把記錄寫到 redo log(粉板)里面,并更新內(nèi)存枝秤,這個時候更新就算完成了醋拧。同時,InnoDB 引擎會在適當(dāng)?shù)臅r候淀弹,將這個操作記錄更新到磁盤里面丹壕,而這個更新往往是在系統(tǒng)比較空閑的時候做,這就像打烊以后掌柜做的事薇溃。
log buffer-------->os buffer---------->log files菌赖,3個部分都算是redo log,對應(yīng)于下面3個取值沐序。
redo log 可能存在的三種狀態(tài):
1琉用、存在 redo log buffer 中,物理上是在 MySQL用戶進程中策幼,user buffer邑时;
2、寫到磁盤 (write)特姐,os buffer刁愿,但是沒有持久化(fsync),屬于系統(tǒng)調(diào)用到逊,物理上是在文件系統(tǒng)的 page cache 里面;
3滤钱、持久化到磁盤觉壶,對應(yīng)的是 hard disk。
日志寫到 redo log buffer 是很快的件缸,wirte 到 page cache 也差不多铜靶,但是持久化到磁盤的速度就慢多了。
為了控制 redo log 的寫入策略他炊,InnoDB 提供了 innodb_flush_log_at_trx_commit 參數(shù)争剿,它有三種可能取值:
1、設(shè)置為 0 的時候痊末,表示每次事務(wù)提交時都只是把 redo log 留在 redo log buffer 中 ;
2蚕苇、設(shè)置為 1 的時候,表示每次事務(wù)提交時都將 redo log 直接持久化到磁盤凿叠;
3涩笤、設(shè)置為 2 的時候嚼吞,表示每次事務(wù)提交時都只是把 redo log 寫到 page cache。
InnoDB 有一個后臺線程蹬碧,每隔 1 秒舱禽,由參數(shù)innodb_flush_log_at_timeout控制。就會把 redo log buffer 中的日志恩沽,調(diào)用 write 寫到文件系統(tǒng)的 page cache誊稚,然后調(diào)用 fsync 持久化到磁盤。
注意罗心,事務(wù)執(zhí)行中間過程的 redo log 也是直接寫在 redo log buffer 中的里伯,這些 redo log 也會被后臺線程一起持久化到磁盤。也就是說协屡,一個沒有提交的事務(wù)的 redo log俏脊,也是可能已經(jīng)持久化到磁盤的。
實際上肤晓,除了后臺線程每秒一次的輪詢操作外爷贫,還有兩種場景會讓一個沒有提交的事務(wù)的 redo log 寫入到磁盤中。
一種是补憾,redo log buffer 占用的空間即將達(dá)到 innodb_log_buffer_size 一半的時候漫萄,后臺線程會主動寫盤。注意盈匾,由于這個事務(wù)并沒有提交腾务,所以這個寫盤動作只是 write,而沒有調(diào)用 fsync削饵,也就是只留在了文件系統(tǒng)的 page cache岩瘦。
另一種是,并行的事務(wù)提交的時候窿撬,順帶將這個事務(wù)的 redo log buffer 持久化到磁盤启昧。假設(shè)一個事務(wù) A 執(zhí)行到一半,已經(jīng)寫了一些 redo log 到 buffer 中劈伴,這時候有另外一個線程的事務(wù) B 提交密末,如果 innodb_flush_log_at_trx_commit 設(shè)置的是 1,那么按照這個參數(shù)的邏輯跛璧,事務(wù) B 要把 redo log buffer 里的日志全部持久化到磁盤严里。這時候,就會帶上事務(wù) A 在 redo log buffer 里的日志一起持久化到磁盤追城。
這里需要說明的是刹碾,我們介紹兩階段提交的時候說過,時序上 redo log 先 prepare座柱, 再寫 binlog教硫,最后再把 redo log commit叨吮。
如果把 innodb_flush_log_at_trx_commit 設(shè)置成 1,那么 redo log 在 prepare 階段就要持久化一次瞬矩,因為有一個崩潰恢復(fù)邏輯是要依賴于 prepare 的 redo log茶鉴,再加上 binlog 來恢復(fù)的。
每秒一次后臺輪詢刷盤景用,再加上崩潰恢復(fù)這個邏輯涵叮,InnoDB 就認(rèn)為 redo log 在 commit 的時候就不需要 fsync 了,只會 write 到文件系統(tǒng)的 page cache 中就夠了伞插。
通常我們說 MySQL 的“雙 1”配置割粮,指的就是 sync_binlog 和 innodb_flush_log_at_trx_commit 都設(shè)置成 1。也就是說媚污,一個事務(wù)完整提交前舀瓢,需要等待兩次刷盤,一次是 redo log(prepare 階段)耗美,一次是 binlog京髓。但是因為組提交機制,不會太影響IO商架,為了數(shù)據(jù)安全還是建議設(shè)置為1堰怨。
當(dāng)內(nèi)存數(shù)據(jù)頁跟磁盤數(shù)據(jù)頁內(nèi)容不一致的時候,我們稱這個內(nèi)存頁為“臟頁”蛇摸。內(nèi)存數(shù)據(jù)寫入到磁盤后备图,內(nèi)存和磁盤上的數(shù)據(jù)頁的內(nèi)容就一致了,稱為“干凈頁”赶袄。redo log會引起臟頁問題揽涮。
何時會刷臟頁?饿肺?
1蒋困、InnoDB 的 redo log 寫滿了。阻塞更新唬格,應(yīng)盡量避免。
2颜说、系統(tǒng)內(nèi)存不足购岗。InnoDB 用緩沖池(buffer pool)管理內(nèi)存,會優(yōu)先把數(shù)據(jù)緩存在內(nèi)存门粪,而內(nèi)存臟頁太多會影響性能喊积,需要控制臟頁比例。innodb_io_capacity 建議你設(shè)置成磁盤的 IOPS玄妈。如果設(shè)置過小乾吻,會使mysql不能完全使用io的性能髓梅,尤其是SSD的時候。
3绎签、系統(tǒng)“空閑”的時候枯饿。
4、MySQL 正常關(guān)閉的情況诡必。
InnoDB 的刷盤速度就是要參考這兩個因素:一個是臟頁比例奢方,一個是 redo log 寫盤速度。
innodb_max_dirty_pages_pct 臟頁比例上線爸舒,默認(rèn)75%蟋字。
innodb_flush_neighbors ,開啟會連坐隔壁的數(shù)據(jù)頁也被刷扭勉,可以減少隨機IO鹊奖,磁盤較好時不需要開啟,mysql 8.0默認(rèn)關(guān)閉涂炎。
InnoDB 的 redo log 是固定大小的忠聚,比如可以配置為一組 4 個文件,每個文件的大小是 1GB璧尸,那么這塊“粉板”總共就可以記錄 4GB 的操作咒林。從頭開始寫,寫到末尾就又回到開頭循環(huán)寫爷光。
有了 redo log垫竞,InnoDB 就可以保證即使數(shù)據(jù)庫發(fā)生異常重啟,之前提交的記錄都不會丟失蛀序,這個能力稱為crash-safe欢瞪。要理解 crash-safe 這個概念,可以想想我們前面賒賬記錄的例子徐裸。只要賒賬記錄記在了粉板上或?qū)懺诹速~本上遣鼓,之后即使掌柜忘記了,比如突然停業(yè)幾天重贺,恢復(fù)生意后依然可以通過賬本和粉板上的數(shù)據(jù)明確賒賬賬目骑祟。
undo日志:
undo log有兩個作用:提供回滾和多個行版本控制(MVCC)。
undo log和redo log記錄物理日志不一樣气笙,它是邏輯日志次企。可以認(rèn)為當(dāng)delete一條記錄時,undo log中會記錄一條對應(yīng)的insert記錄潜圃,反之亦然缸棵,當(dāng)update一條記錄時,它記錄一條對應(yīng)相反的update記錄谭期。當(dāng)執(zhí)行rollback時堵第,就可以從undo log中的邏輯記錄讀取到相應(yīng)的內(nèi)容并進行回滾吧凉。有時候應(yīng)用到行版本控制的時候,也是通過undo log來實現(xiàn)的:當(dāng)讀取的某一行被其他事務(wù)鎖定時踏志,它可以從undo log中分析出該行記錄以前的數(shù)據(jù)是什么阀捅,從而提供該行版本信息,讓用戶實現(xiàn)非鎖定一致性讀取狰贯。
undo log是采用段(segment)的方式來記錄的也搓,每個undo操作在記錄的時候占用一個undo log segment。另外涵紊,undo log也會產(chǎn)生redo log傍妒,因為undo log也要實現(xiàn)持久性保護。在以前老版本摸柄,只支持1個rollback segment颤练,這樣就只能記錄1024個undo log segment。后來MySQL5.5可以支持128個rollback segment驱负,即支持128*1024個undo操作嗦玖,還可以通過變量innodb_undo_logs(5.6版本以前該變量是innodb_rollback_segments)自定義多少個rollback segment,默認(rèn)值為128跃脊。
undo log默認(rèn)存放在共享表空間中宇挫。即ibdata1文件。如果開啟了innodb_file_per_table酪术,將放在每個表的.ibd(表的數(shù)據(jù)文件)中器瘪。在MySQL5.6中,undo的存放位置還可以通過變量innodb_undo_directory來自定義存放目錄绘雁,默認(rèn)值為"."表示datadir橡疼。默認(rèn)rollback segment全部寫在一個文件中,但可以通過設(shè)置變量?innodb_undo_tablespaces?平均分配到多少個文件中庐舟。該變量默認(rèn)值為0欣除,即全部寫入一個表空間文件。該變量為靜態(tài)變量挪略,只能在數(shù)據(jù)庫示例停止?fàn)顟B(tài)下修改历帚,如寫入配置文件或啟動時帶上對應(yīng)參數(shù)。但是innodb存儲引擎在啟動過程中提示杠娱,不建議修改為非0的值挽牢。
當(dāng)事務(wù)提交的時候,innodb不會立即刪除undo log墨辛,因為后續(xù)還可能會用到undo log卓研,如隔離級別為repeatable read時趴俘,事務(wù)讀取的都是開啟事務(wù)時的最新提交行版本睹簇,只要該事務(wù)不結(jié)束奏赘,該行版本就不能刪除,即undo log不能刪除太惠。
但是在事務(wù)提交的時候磨淌,會將該事務(wù)對應(yīng)的undo log放入到刪除列表中,未來通過purge來刪除凿渊。并且提交事務(wù)時梁只,還會判斷undo log分配的頁是否可以重用,如果可以重用埃脏,則會分配給后面來的事務(wù)搪锣,避免為每個獨立的事務(wù)分配獨立的undo log頁而浪費存儲空間和性能。
通過undo log記錄delete和update操作的結(jié)果發(fā)現(xiàn):(insert操作無需分析彩掐,就是插入行而已)
delete操作實際上不會直接刪除构舟,而是將delete對象打上delete flag,標(biāo)記為刪除堵幽,最終的刪除操作是purge線程完成的狗超。
update分為兩種情況:update的列是否是主鍵列。
如果不是主鍵列朴下,在undo log中直接反向記錄是如何update的努咐。即update是直接進行的。
如果是主鍵列殴胧,update分兩部執(zhí)行:先刪除該行渗稍,再插入一行目標(biāo)行。
binlog(歸檔日志):
binlog 的寫入邏輯比較簡單:事務(wù)執(zhí)行過程中溃肪,先把日志寫到 binlog cache免胃,事務(wù)提交的時候,再把 binlog cache 寫到 binlog 文件中惫撰。binlog 一般用來備份和恢復(fù)羔沙。一個事務(wù)的 binlog 是不能被拆開的,因此不論這個事務(wù)多大厨钻,也要確保一次性寫入扼雏。這就涉及到了 binlog cache 的保存問題。每個線程有自己 binlog cache夯膀,但是共用同一份 binlog 文件诗充。
binlog記錄了對MySQL數(shù)據(jù)庫執(zhí)行更改的所有操作,但是不包括SELECT和SHOW(也是select其實)這類操作诱建,因為這類操作對數(shù)據(jù)本身并沒有修改蝴蜓。binlog可在臨時庫上恢復(fù)數(shù)據(jù)庫到任何時間點的狀態(tài),因為它保存了所有修改的邏輯。每個線程一個茎匠,參數(shù) binlog_cache_size 用于控制單個線程內(nèi) binlog cache 所占內(nèi)存的大小格仲。如果超過了這個參數(shù)規(guī)定的大小,就要暫存到磁盤诵冒。
1凯肋、write,指的就是指把日志寫入到文件系統(tǒng)的 page cache汽馋,并沒有把數(shù)據(jù)持久化到磁盤侮东,所以速度比較快。
2豹芯、fsync悄雅,才是將數(shù)據(jù)持久化到磁盤的操作。一般情況下铁蹈,我們認(rèn)為 fsync 才占磁盤的 IOPS煤伟。
write 和 fsync 的時機,是由參數(shù) sync_binlog 控制的:
sync_binlog=0 的時候木缝,表示每次提交事務(wù)都只 write便锨,不 fsync;
sync_binlog=1 的時候我碟,表示每次提交事務(wù)都會執(zhí)行 fsync放案;
sync_binlog=N(N>1) 的時候,表示每次提交事務(wù)都 write矫俺,但累積 N 個事務(wù)后才 fsync(刷盤)吱殉。
因此,在出現(xiàn) IO 瓶頸的場景里厘托,將 sync_binlog 設(shè)置成一個比較大的值友雳,可以提升性能。在實際的業(yè)務(wù)場景中铅匹,考慮到丟失日志量的可控性押赊,一般不建議將這個參數(shù)設(shè)成 0,比較常見的是將其設(shè)置為 100~1000 中的某個數(shù)值包斑。
但是流礁,將 sync_binlog 設(shè)置為 N,對應(yīng)的風(fēng)險是:如果主機發(fā)生異常重啟罗丰,會丟失最近 N 個事務(wù)的 binlog 日志神帅。
MySQL 整體來看,其實就有兩塊:一塊是 Server 層萌抵,它主要做的是 MySQL 功能層面的事情找御;還有一塊是引擎層元镀,負(fù)責(zé)存儲相關(guān)的具體事宜。 上面我們聊到的粉板 redo log 是 InnoDB 引擎特有的日志霎桅,而 Server 層也有自己的日志凹联,稱為 binlog(歸檔日志)。
最開始 MySQL 里并沒有 InnoDB 引擎哆档。MySQL 自帶的引擎是 MyISAM,但是 MyISAM 沒有 crash-safe 的能力住闯,binlog 日志只能用于歸檔瓜浸。而 InnoDB 是另一個公司以插件形式引入 MySQL 的,既然只依靠 binlog 是沒有 crash-safe 能力的比原,所以 InnoDB 使用另外一套日志系統(tǒng)——也就是 redo log 來實現(xiàn) crash-safe 能力插佛,即crash的一瞬間,那些沒有完成的事務(wù)依然能夠完成量窘。
這兩種日志有以下三點不同雇寇。
1、redo log 是 InnoDB 引擎特有的蚌铜;binlog 是 MySQL 的 Server 層實現(xiàn)的锨侯,所有引擎都可以使用。
2冬殃、redo log 是物理日志囚痴,記錄的是“在某個數(shù)據(jù)頁上做了什么修改”;binlog 是邏輯日志审葬,記錄的是這個語句的原始邏輯深滚,比如“給 ID=2 這一行的 c 字段加 1 ”。
3涣觉、redo log 是循環(huán)寫的痴荐,空間固定會用完;binlog 是可以追加寫入的官册∩祝“追加寫”是指 binlog 文件寫到一定大小后會切換到下一個,并不會覆蓋以前的日志膝宁。
update流程:
你可能注意到了皂贩,最后三步看上去有點“繞”,將 redo log 的寫入拆成了兩個步驟:prepare 和 commit昆汹,這就是"兩階段提交"明刷。如果不使用“兩階段提交”,那么數(shù)據(jù)庫的狀態(tài)就有可能和用它的日志恢復(fù)出來的庫的狀態(tài)不一致满粗。
redo log 和 binlog 都可以用于表示事務(wù)的提交狀態(tài)辈末,而兩階段提交就是讓這兩個狀態(tài)保持邏輯上的一致。redo log 用于保證 crash-safe 能力。innodb_flush_log_at_trx_commit 這個參數(shù)設(shè)置成 1 的時候挤聘,表示每次事務(wù)的 redo log 都直接持久化到磁盤轰枝。這個參數(shù)我建議你設(shè)置成 1,這樣可以保證 MySQL 異常重啟之后數(shù)據(jù)不丟失组去。
sync_binlog 這個參數(shù)設(shè)置成 1 的時候鞍陨,表示每次事務(wù)的 binlog 都持久化到磁盤。這個參數(shù)我也建議你設(shè)置成 1从隆,這樣可以保證 MySQL 異常重啟之后 binlog 不丟失诚撵。
我還跟你介紹了與 MySQL 日志系統(tǒng)密切相關(guān)的“兩階段提交”。兩階段提交是跨系統(tǒng)維持?jǐn)?shù)據(jù)邏輯一致性時常用的一個方案键闺,即使你不做數(shù)據(jù)庫內(nèi)核開發(fā)寿烟,日常開發(fā)中也有可能會用到。
事務(wù)日志redo log具有冪等性辛燥,所以多次操作得到同一結(jié)果的行為在日志中只記錄一次筛武。而二進制日志binlog不具有冪等性,多次操作會全部記錄下來挎塌,在恢復(fù)的時候會多次執(zhí)行二進制日志中的記錄徘六,速度就慢得多。
Mysql的IO瓶頸優(yōu)化:
1榴都、設(shè)置 binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count 參數(shù)硕噩,減少 binlog 的寫盤次數(shù)。這個方法是基于“額外的故意等待”來實現(xiàn)的缭贡,因此可能會增加語句的響應(yīng)時間炉擅,但沒有丟失數(shù)據(jù)的風(fēng)險。
2阳惹、將 sync_binlog 設(shè)置為大于 1 的值(比較常見是 100~1000谍失,默認(rèn)1)。這樣做的風(fēng)險是莹汤,主機掉電時會丟 binlog 日志快鱼。
3、將 innodb_flush_log_at_trx_commit 設(shè)置為 2(生產(chǎn)默認(rèn)1纲岭,redo log兩階段提交的prepare時就會持久化一次)抹竹。這樣做的風(fēng)險是,主機掉電的時候會丟數(shù)據(jù)止潮。
什么時候會把線上生產(chǎn)庫設(shè)置成“非雙 1”:
1窃判、業(yè)務(wù)高峰期。一般如果有預(yù)知的高峰期喇闸,DBA 會有預(yù)案袄琳,把主庫設(shè)置成“非雙 1”询件。
2、備庫延遲唆樊,為了讓備庫盡快趕上主庫宛琅。
3、用備份恢復(fù)主庫的副本逗旁,應(yīng)用 binlog 的過程嘿辟,這個跟上一種場景類似。
4片效、批量導(dǎo)入數(shù)據(jù)的時候红伦。
一般情況下,把生產(chǎn)庫改成“非雙 1”配置堤舒,是設(shè)置 innodb_flush_logs_at_trx_commit=2、sync_binlog=1000哺呜。主要就是大量操作舌缤,避免頻繁IO操作,通過組的方式合并事務(wù)的IO操作某残。
組提交(group sync):
1国撵、組提交的核心思想就是:一次fsync()調(diào)用,可以刷新N個事務(wù)的redo log(redo的組提交) & binlog(binlog的組提交)
2玻墅、組提交的最終目的就是為了減少IO的頻繁刷盤介牙,來提高并發(fā)性能,當(dāng)然也是之后多線程復(fù)制的基礎(chǔ)
3、組提交中:sync_binlog=1 & innodb_trx_at_commit=1 代表的不再是1個事務(wù)澳厢,而是一組事務(wù)和一個事務(wù)組的binlog
4环础、組提交中:binlog是順序fsync的,事務(wù)也是按照順序進行提交的剩拢,這都是有序的线得,MySQL5.7 并對這些有序的事務(wù)進行打好標(biāo)記(last_committed,sequence_number )
相關(guān)問題:
問題 1:執(zhí)行一個 update 語句以后徐伐,我再去執(zhí)行 hexdump 命令直接查看 ibd 文件內(nèi)容贯钩,為什么沒有看到數(shù)據(jù)有改變呢?
回答:這可能是因為 WAL 機制的原因办素。update 語句執(zhí)行完成后角雷,InnoDB 只保證寫完了 redo log、內(nèi)存性穿,可能還沒來得及將數(shù)據(jù)寫到磁盤勺三。
問題 2:為什么 binlog cache 是每個線程自己維護的,而 redo log buffer 是全局共用的需曾?
回答:MySQL 這么設(shè)計的主要原因是檩咱,binlog 是不能“被打斷的”揭措。一個事務(wù)的 binlog 必須連續(xù)寫,因此要整個事務(wù)完成后刻蚯,再一起寫到文件里绊含。
而 redo log 并沒有這個要求,中間有生成的日志可以寫到 redo log buffer 中炊汹。redo log buffer 中的內(nèi)容還能“搭便車”躬充,其他事務(wù)提交的時候可以被一起寫到磁盤中。
問題 3:事務(wù)執(zhí)行期間讨便,還沒到提交階段充甚,如果發(fā)生 crash 的話,redo log 肯定丟了霸褒,這會不會導(dǎo)致主備不一致呢伴找?
回答:不會。因為這時候 binlog 也還在 binlog cache 里废菱,沒發(fā)給備庫技矮。crash 以后 redo log 和 binlog 都沒有了,從業(yè)務(wù)角度看這個事務(wù)也沒有提交殊轴,所以數(shù)據(jù)是一致的衰倦。
問題 4:如果 binlog 寫完盤以后發(fā)生 crash,這時候還沒給客戶端答復(fù)就重啟了旁理。等客戶端再重連進來樊零,發(fā)現(xiàn)事務(wù)已經(jīng)提交成功了,這是不是 bug孽文?
回答:不是驻襟。
你可以設(shè)想一下更極端的情況,整個事務(wù)都提交成功了芋哭,redo log commit 完成了塑悼,備庫也收到 binlog 并執(zhí)行了。但是主庫和客戶端網(wǎng)絡(luò)斷開了楷掉,導(dǎo)致事務(wù)成功的包返回不回去厢蒜,這時候客戶端也會收到“網(wǎng)絡(luò)斷開”的異常。這種也只能算是事務(wù)成功的烹植,不能認(rèn)為是 bug斑鸦。
實際上數(shù)據(jù)庫的 crash-safe 保證的是:
如果客戶端收到事務(wù)成功的消息,事務(wù)就一定持久化了草雕;
如果客戶端收到事務(wù)失斚镉臁(比如主鍵沖突、回滾等)的消息墩虹,事務(wù)就一定失敗了嘱巾;
如果客戶端收到“執(zhí)行異澈┝眨”的消息,應(yīng)用需要重連后通過查詢當(dāng)前狀態(tài)來繼續(xù)后續(xù)的邏輯旬昭。此時數(shù)據(jù)庫只需要保證內(nèi)部(數(shù)據(jù)和日志之間篙螟,主庫和備庫之間)一致就可以了。
5.6 skip-counter
5.7 gtid 不能跳
slave_skip_error