新聞中心
分布式存儲-mysql 數(shù)據(jù)庫事務與復制
作者:Javaspring架構(gòu)師 2019-06-10 14:31:24
存儲
存儲軟件
分布式 結(jié)合實際工作中碰到的問題,以尋找答案的方式來剖解技術(shù),很多時候我們都不是在創(chuàng)造新技術(shù),而是在應用技術(shù)。

創(chuàng)新互聯(lián)主營呈貢網(wǎng)站建設(shè)的網(wǎng)絡公司,主營網(wǎng)站建設(shè)方案,成都App定制開發(fā),呈貢h5小程序設(shè)計搭建,呈貢網(wǎng)站營銷推廣歡迎呈貢等地區(qū)企業(yè)咨詢
「后端分布式」包括「分布式存儲」和 「分布式計算」兩大類。結(jié)合實際工作中碰到的問題,以尋找答案的方式來剖解技術(shù),很多時候我們都不是在創(chuàng)造新技術(shù),而是在應用技術(shù)。為了更有效率與效果的用好技術(shù),我們需要了解一些技術(shù)的原理與工作方式。帶著問題從使用者的角度去剖析技術(shù)原理,并將開源技術(shù)產(chǎn)品和框架作為一類技術(shù)的參考實現(xiàn)來講解。以講清原理為主要目的,對于具體實現(xiàn)的技術(shù)細節(jié)若無特別之處則盡可能點到即止。
事務與復制
近期參與了一個數(shù)據(jù)分布化相關(guān)的項目,涉及到數(shù)據(jù)庫 MySQL 的數(shù)據(jù)分布化。簡單來說就是需要在異地數(shù)據(jù)中心實現(xiàn)多點可寫并保證分布后的數(shù)據(jù)能達成最終一致性。以前對 MySQL 作數(shù)據(jù)分布僅僅是讀寫分離,通過數(shù)據(jù)庫自身的主從復制即可實現(xiàn)寫主庫、讀從庫?,F(xiàn)在則需要雙寫主庫并在經(jīng)歷一個短暫的延時后達成最終一致性,這個問題乍一想比較復雜,但歸根結(jié)底還是數(shù)據(jù)最終一致性的問題。
先回到最簡單的情況,只有一個 MySQL 數(shù)據(jù)庫時,數(shù)據(jù)一致性是怎么保證的?了解數(shù)據(jù)庫的都知道,這是通過數(shù)據(jù)庫的事務特性來保證的,事務包括四大特性:
- Atomicity 原子性
- Consistency 一致性
- Isolation 隔離性
- Durability 持久性
事務的 ACID 四大特性不是本文重點,就不展開做學術(shù)性解說了,不了解的可以在后面參考文獻里[3]去看相關(guān)文章。這里只想提一個問題,單一數(shù)據(jù)庫事務能保證數(shù)據(jù)的一致性,那么 MySQL 在部署成主從架構(gòu)時,如何保證主從之間數(shù)據(jù)的一致性的?
MySQL 為了提供主從復制功能引入了一個新的日志文件叫 binlog,它包含了引發(fā)數(shù)據(jù)變更的事件日志集合。從庫請求主庫發(fā)送 binlog 并通過日志事件還原數(shù)據(jù)寫入從庫,所以從庫的數(shù)據(jù)來源為 binlog。這樣 MySQL 主庫只需做到 binlog 與本地數(shù)據(jù)一致就可以保證主從庫數(shù)據(jù)一致(暫且忽略網(wǎng)絡傳輸引發(fā)的主從不一致)。我們知道保證本地數(shù)據(jù)一致性是靠數(shù)據(jù)庫事務特性來達成的,而數(shù)據(jù)庫事務是如何實現(xiàn)的呢?先看下面這張圖:
MySQL 本身不提供事務支持,而是開放了存儲引擎接口,由具體的存儲引擎來實現(xiàn),具體來說支持 MySQL 事務的存儲引擎就是 InnoDB。存儲引擎實現(xiàn)事務的通用方式是基于 redo log 和 undo log。簡單來說,redo log 記錄事務修改后的數(shù)據(jù), undo log 記錄事務前的原始數(shù)據(jù)。所以當一個事務執(zhí)行時實際發(fā)生過程簡化描述如下:
先記錄 undo/redo log,確保日志刷到磁盤上持久存儲。
更新數(shù)據(jù)記錄,緩存操作并異步刷盤。
提交事務,在 redo log 中寫入 commit 記錄。
在 MySQL 執(zhí)行事務過程中如果因故障中斷,可以通過 redo log 來重做事務或通過 undo log 來回滾,確保了數(shù)據(jù)的一致性。這些都是由事務性存儲引擎來完成的,但 binlog 不在事務存儲引擎范圍內(nèi),而是由 MySQL Server 來記錄的。那么就必須保證 binlog 數(shù)據(jù)和 redo log 之間的一致性,所以開啟了 binlog 后實際的事務執(zhí)行就多了一步,如下:
先記錄 undo/redo log,確保日志刷到磁盤上持久存儲。
更新數(shù)據(jù)記錄,緩存操作并異步刷盤。
將事務日志持久化到 binlog。
提交事務,在 redo log 中寫入提交記錄。
這樣的話,只要 binlog 沒寫成功,整個事務是需要回滾的,而 binlog 寫成功后即使 MySQL Crash 了都可以恢復事務并完成提交。要做到這點,就需要把 binlog 和事務關(guān)聯(lián)起來,而只有保證了 binlog 和事務數(shù)據(jù)的一致性,才能保證主從數(shù)據(jù)的一致性。所以 binlog 的寫入過程不得不嵌入到純粹的事務存儲引擎執(zhí)行過程中,并以內(nèi)部分布式事務(xa 事務)的方式完成兩階段提交。進一步的細節(jié)就不展開了,可以參看后面參考文獻[5]。
總結(jié)
我們前面先提出了一個問題,然后從數(shù)據(jù)一致性的角度去思考,參考了 MySQL 的實現(xiàn)方式。理清并分析了 MySQL 單機環(huán)境是如何保證復制機制的數(shù)據(jù)一致性,也就是 binlog 和事務數(shù)據(jù)的一致。后面我們才能基于 binlog 這個機制去實現(xiàn)復制并保證主從復制的一致性。主從復制又引入了網(wǎng)絡因素,進一步增加了保證主從數(shù)據(jù)一致性的復雜度,后面還會撰文進一步分析這個問題。
文章名稱:分布式存儲-MySQL數(shù)據(jù)庫事務與復制
本文來源:http://www.dlmjj.cn/article/djidppj.html


咨詢
建站咨詢
