mysqldump如何保證資料一致性

2021-06-23 02:41:02 字數 2028 閱讀 6281

作為dba的小k,搭建備機應該是家常便飯了,這時候用到的方法無非有如下三種:

1、停掉一台備機(這裡叫備機1),直接拷貝整個資料目錄下的所有檔案到新的備機(這裡叫備機2)。優點是簡單、快速,只需要拷貝;缺點也很明顯,在整個備份過程中備機1處於完全不可用的狀態,且備機2無法釋放備機1中因為碎片導致的空間浪費和無法**已發生擴充套件的innodb表空間。

2、用xtrabackup進行熱備。優點是備份過程中可繼續提供服務;缺點和第一種方法差不多,備機2無法釋放備機1中因為碎片導致的空間浪費和無法**已發生擴充套件的innodb表空間。

3、使用官方自帶的mysqldump邏輯重做。優點是在整個備份過程中備機1可以向外提供服務,最重要的一點是可以解決碎片浪費。

這三種方法的步驟都比較簡單,所以這裡不做介紹。小k在這裡主要是解釋一下mysqldump是如何在備份過程中確保資料一致性這個問題

首先要介紹一下repeatable read這個事務隔離級別,這是理解下面內容的基礎,主要有兩點:

1、在repeatable read事務隔離級別下,在同乙個事務內,每次讀到的資料都是一樣的,這個特性也叫可重複讀;

2、事務隔離級別可以在session級別設定

mysqldump對不同型別的儲存引擎,內部實現也不一樣。主要是針對兩種型別的儲存引擎:支援事務的儲存引擎(如innodb)和不支援事務的儲存引擎(如myisam),下面分別看看這兩種儲存引擎的實現:

1、對於支援事務的引擎如innodb,引數上是在備份的時候加上--single-transaction保證資料一致性

--single-transaction實際上通過做了下面兩個操作:

①、在開始的時候把該session的事務隔離級別設定成repeatable read;

②、然後啟動乙個事務(執行bigin),備份結束的時候結束該事務(執行commit)

有了這兩個操作,在備份過程中,該session讀到的資料都是啟動備份時的資料(同乙個點),所以匯入完成後從該點(可通過新增--master-data=2獲取)應用binlog得到的資料是和主機完全一致的。

2、對於不支援事務的引擎如myisam,只能通過鎖表來保證資料一致性,這裡分三種情況:

①、匯出全庫:加--lock-all-tables引數,這會在備份開始的時候啟動乙個全域性讀鎖(執行flush tables with read lock),其他session可以讀取但不能更新資料,備份過程中資料沒有變化,所以最終得到的資料肯定是完全一致的;

②、匯出單個庫:加--lock-tables引數,這會在備份開始的時候所在該庫的所有表,其他session可以讀但不能更新該庫的所有表,該庫的資料一致;

③、匯出單個表:加--lock-tables引數,這會在備份開始的時候所在該錶,其他表不受影響,該錶資料一致。

有一次乙個同事這麼跟我說:myisam表不鎖表最終也不會不一致啊,只要從備份開始的點應用binlog,不就把所有資料庫的所有變化都應用上了嘛。一開始我走入過這個坑,但是後來請教了組內大牛後,豁然開朗。有圖有真相啊有木有,小k用下面這張圖來介紹為什麼在備份不支援事務的儲存引擎如myisam表時,不鎖表最終得到的資料是不一致的。

說明:1、在t1時間點,用mysqldump啟動不鎖表備份;

2、先導出a表,共耗時5分鐘,因為沒有鎖表,在這5分鐘內b表insert了10行資料;

3、到了t2時間點,a表匯出完成,開始匯出b表;

4、匯出b表耗時10分鐘,在匯出b表的過程中,a、b表均沒有資料變化;

5、到了t3時間點,b表匯出完成,全部備份結束;

6、然後備機從t1時間點的binlog位置開始應用binlog,最後備機中b表的資料比主機多10行,資料不一致。

從這個圖可以看出,對於不支援事務的儲存引擎如myisam如果備份過程中不鎖表,不同表開始備份時對應的binlog和pos是不一致的,這時候所有表都從備份開始的點應用binlog,有很大肯會出現資料不一致(備份過程中所有表均無資料更新除外)。

Mysql如何保證資料不會丟失

簡單來說就是依靠redo log和binlog保證持久化到磁碟後就可以保證,異常重啟資料可以正常恢復 這裡主要說下這兩個log的寫入機制。乙個事務執行的過程中,會先把日誌寫入到binlog cache中,事務提交的時候再把binlog cache中的日誌寫到binlog中。系統給binlog cac...

Kafka如何保證資料不丟失

kafka的ack機制 在kafka傳送資料的時候,每次傳送訊息都會有乙個確認反饋機制,確保訊息正常的能夠被收到,其中狀態有0,1,1。producer.type sync request.required.acks 1 producer.type async request.required.ac...

如何保證資料掉電不損壞?

1.建議使用ext3 ext4等日誌式檔案系統,並開啟journal。2.檔案系統無法保證write是原子的,所以,建議直接使用一些優秀的資料庫儲存資料或者配置,比如sqlite。sqlite可以考慮開啟synchronous full,fullfsync 1。如果還是出現檔案損壞的情況,考慮是硬體...