1. 程式人生 > >mysqldump備份原理及注意事項

mysqldump備份原理及注意事項

關於MySQL熱備,可分為兩種方式:

  1. 邏輯備份

  2. 物理備份

對於前者,常用的工具是MySQL自帶的mysqldump,對於後者,常用的工具是Percona提供的XtraBackup。

對於規模比較小,業務並不繁忙的資料庫,一般都是選擇mysqldump。

那麼,mysqldump的備份原理是什麼呢?

拋開原始碼不談,其實我們可以通過開啟general log,檢視mysqldump全庫備份時執行的命令來了解mysqldump背後的原理。

只考慮innodb表的情況如下圖所示:
這裡寫圖片描述

開啟general log

[email protected] 04:55:  [sbtest]> set
global general_log=on; Query OK, 0 rows affected (0.00 sec)

其中,general log的存放路徑可通過以下命令檢視

[email protected] 04:59:  [sbtest]> show variables like '%general_log_file%';
+------------------+---------------------------+
| Variable_name    | Value                     |
+------------------+---------------------------+
| general_log_file | /data/mysql/localhost.log | +------------------+---------------------------+ 1 row in set (0.00 sec)

執行全庫備份

[[email protected] ~]# mysqldump --master-data=2  -R --single-transaction -A -p123456 > lijingkuan.sql
Warning: Using a password on the command line interface can be insecure.
Warning: A partial dump from
a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.

其中

–master-data指定為2指的是會在備份檔案中生成CHANGE MASTER的註釋。具體在本例中,指的是

-- CHANGE MASTER TO MASTER_LOG_FILE='mybinlog.000008', MASTER_LOG_POS=222448728;

如果該值設定為1,則生成的是CHANGE MASTER的命令,而不是註釋。

-R 備份儲存過程與函式

–single-transaction 獲取InnoDB表的一致性備份。

-A 相當於–all-databases。

下面來看看general log中的內容

170529  5:00:47   215 Connect   [email protected] on 
                  215 Query     /*!40100 SET @@SQL_MODE='' */
                  215 Query     /*!40103 SET TIME_ZONE='+00:00' */
                  215 Query     FLUSH /*!40101 LOCAL */ TABLES
                  215 Query     FLUSH TABLES WITH READ LOCK
                  215 Query     SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
                  215 Query     START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */
                  215 Query     SHOW VARIABLES LIKE 'gtid\_mode'
                  215 Query     SELECT @@GLOBAL.GTID_EXECUTED
                  215 Query     SHOW MASTER STATUS
                  215 Query     UNLOCK TABLES
                  215 Query     SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND 
FILE_NAME IS NOT NULL GROUP BY LOGFILE_GROUP_NAME, FILE_NAME, ENGINE ORDER BY LOGFILE_GROUP_NAME
                  215 Query     SELECT DISTINCT TABLESPACE_NAME, FILE_NAME, LOGFILE_GROUP_NAME, EXTENT_SIZE, INITIAL_SIZE, ENGINE FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE 
= 'DATAFILE' ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME
                  215 Query     SHOW DATABASES
                  215 Query     SHOW VARIABLES LIKE 'ndbinfo\_version'

其中,比較重要的有以下幾點:

1.FLUSH /!40101 LOCAL / TABLES

Closes all open tables, forces all tables in use to be closed, and flushes the query cache.

2.FLUSH TABLES WITH READ LOCK

執行flush tables操作,並加一個全域性讀鎖,很多童鞋可能會好奇,這兩個命令貌似是重複的,為什麼不在第一次執行flush tables操作的時候加上鎖呢?

下面看看原始碼中的解釋:

 /*
    We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
    will wait but will not stall the whole mysqld, and when the long update is
    done the FLUSH TABLES WITH READ LOCK will start and succeed quickly. So,
    FLUSH TABLES is to lower the probability of a stage where both mysqldump
    and most client connections are stalled. Of course, if a second long
    update starts between the two FLUSHes, we have that bad stall.
  */

簡而言之,是為了避免較長的事務操作造成FLUSH TABLES WITH READ LOCK操作遲遲得不到鎖,但同時又阻塞了其它客戶端操作。
(flush tables只是關閉所有開啟的表,並不獲取鎖。如果沒有長事務,命令會很快執行完成(因為長事務會導致表無法關閉。但長時間未提交的事務不會導致表無法關閉)。長時間未提交的事務也不會阻塞flush tables。flush tables也不會阻塞後續其他客戶端的事務操作;
flush tables with read lock才會獲取讀鎖。長時間未提交的事務不會阻塞FTWRL,但是FTWRL會阻塞活動的事務執行後續的更改和提交等操作(比如長時間未提交的事務提交,或者繼續update),以及阻塞後續的事務開始執行,資料庫處於stall狀態;)

3.SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

設定當前會話的事務隔離等級為RR,RR可避免不可重複讀和幻讀。

4.START TRANSACTION /!40100 WITH CONSISTENT SNAPSHOT /

獲取當前資料庫的快照,這個是由mysqldump中–single-transaction決定的。

這個只適用於支援事務的表,在MySQL中,只有Innodb。
注意:START TRANSACTION和START TRANSACTION WITH CONSISTENT SNAPSHOT並不一樣,

START TRANSACTION WITH CONSISTENT SNAPSHOT是開啟事務的一致性快照。

下面看看官方的說法,

   The WITH CONSISTENT SNAPSHOT modifier starts a consistent read for storage engines that are capable of it. 
   This applies only to InnoDB. 
   The effect is the same as issuing a START TRANSACTION followed by a SELECT from any InnoDB table. 

如何理解呢?

簡而言之,就是開啟事務並對所有表執行了一次SELECT操作,這樣可保證備份時,在任意時間點執行select * from table得到的資料和執行START TRANSACTION WITH CONSISTENT SNAPSHOT時的資料一致。

注意,WITH CONSISTENT SNAPSHOT只在RR隔離級別下有效。

下面通過例項看看START TRANSACTION WITH CONSISTENT SNAPSHOT和START TRANSACTION的不同

注意:session 2是自動提交

START TRANSACTION WITH CONSISTENT SNAPSHOT
這裡寫圖片描述

START TRANSACTION
這裡寫圖片描述

可見,如果僅是START TRANSACTION,事務2的insert操作提交後,session 1可見(注意,可見的前提是session 2的insert操作在session 1的select操作之前)

而如果是START TRANSACTION WITH CONSISTENT SNAPSHOT,則即便session 2的insert操作在session 1的select操作之前,對session 1均不可見。

5.SHOW MASTER STATUS

這個是由–master-data決定的,記錄了開始備份時,binlog的狀態資訊,包括MASTER_LOG_FILE和MASTER_LOG_POS

6.UNLOCK TABLES

釋放鎖。

因為我的資料庫中只有以下五個庫

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sbtest             |
| test               |
+--------------------+

備份的時候可以發現只備份了mysql和test,sbtest,並沒有備份information_schema和performance_schema。

下面來看看備份mysql和test的日誌輸出資訊,

因日誌輸出資訊太多,在這裡,只選擇sbtest庫的日誌資訊。test庫中一共有一張表sbtest。

                  215 Init DB   sbtest
                  215 Query     SHOW CREATE DATABASE IF NOT EXISTS `sbtest`
                  215 Query     SAVEPOINT sp
                  215 Query     show tables
                  215 Query     show table status like 'sbtest'
                  215 Query     SET SQL_QUOTE_SHOW_CREATE=1
                  215 Query     SET SESSION character_set_results = 'binary'
                  215 Query     show create table `sbtest`
                  215 Query     SET SESSION character_set_results = 'utf8'
                  215 Query     show fields from `sbtest`
                  215 Query     SELECT /*!40001 SQL_NO_CACHE */ * FROM `sbtest`
170529  5:00:51   215 Query     SET SESSION character_set_results = 'binary'
                  215 Query     use `sbtest`
                  215 Query     select @@collation_database
                  215 Query     SHOW TRIGGERS LIKE 'sbtest'
                  215 Query     SET SESSION character_set_results = 'utf8'
                  215 Query     ROLLBACK TO SAVEPOINT sp
                  215 Query     RELEASE SAVEPOINT sp
                  215 Query     use `sbtest`
                  215 Query     select @@collation_database
                  215 Query     SET SESSION character_set_results = 'binary'
                  215 Query     SHOW FUNCTION STATUS WHERE Db = 'sbtest'
                  215 Query     SHOW PROCEDURE STATUS WHERE Db = 'sbtest'
                  215 Query     SET SESSION character_set_results = 'utf8'

從上述輸出可以看出:

  1. 備份的核心是SELECT /!40001 SQL_NO_CACHE / * FROM sbtest語句。

    該語句會查詢到表sbtest的所有資料,在備份檔案中會生成相應的insert語句。

    其中SQL_NO_CACHE的作用是查詢的結果並不會快取到查詢快取中。

  2. SHOW CREATE DATABASE IF NOT EXISTS sbtest,show create table sbtest

    生成創庫語句和創表語句。

  3. SHOW TRIGGERS LIKE ‘sbtest’

    可以看出,如果不加-R引數,預設是會備份觸發器的。

  4. SHOW FUNCTION STATUS WHERE Db = ‘sbtest’
    SHOW PROCEDURE STATUS WHERE Db = ‘sbtest’

    用於備份儲存過程和函式。

  5. 設定SAVEPOINT,然後備份完每個表後再回滾到該SAVEPOINT。

    為什麼要這麼做呢?

    前面通過START TRANSACTION WITH CONSISTENT SNAPSHOT開啟的事務只能通過commit或者rollback來結束,而不是ROLLBACK TO SAVEPOINT sp。

    其實,這樣做不會阻塞在備份期間對已經備份表的ddl操作。

/**
      ROLLBACK TO SAVEPOINT in --single-transaction mode to release metadata
      lock on table which was already dumped. This allows to avoid blocking
      concurrent DDL on this table without sacrificing correctness, as we
      won't access table second time and dumps created by --single-transaction
      mode have validity point at the start of transaction anyway.
      Note that this doesn't make --single-transaction mode with concurrent
      DDL safe in general case. It just improves situation for people for whom
      it might be working.
    */

下面具體來測試一下:

第一種情況:

會話1發起事務,並查詢sbtest表的值,然後會話2進行新增列操作,該操作被hang住。
這裡寫圖片描述
第二種情況:

會話1發起事務,然後會話2進行新增列操作,發現該操作成功。
這裡寫圖片描述
第三種情況:

模仿mysqldump的備份原理,設定斷點。

注意,DDL操作發起的時間是在執行了select * from test之後,如果是在之前,根據上面第二種情況的測試,是可以進行DDL操作的。

此時,如果不執行ROLLBACK TO SAVEPOINT sp,DDL操作會一直hang下去,執行了該操作後,DDL操作可以繼續執行了。

由此可見,ROLLBACK TO SAVEPOINT確實可以提高DDL的併發性。

但還有一點需要注意,如果DDL操作是發生在select * from test之前,正如第二種情況所演示的,DDL操作會成功,此時,檢視test表的資料會報以下錯誤:

[email protected] 04:32:49 > select * from test;
ERROR 1412 (HY000): Table definition has changed, please retry transaction

對應mysqldump,會報如下錯誤:

mysqldump: Error 1412: Table definition has changed, please retry transaction when dumping table `test` at row: 0

這裡寫圖片描述

總結:

  1. mysqldump的本質是通過select * from tab來獲取表的資料的。

  2. START TRANSACTION /!40100 WITH CONSISTENT SNAPSHOT /必須放到FLUSH TABLES WITH READ LOCK和UNLOCK TABLES之間,放到之前會造成START TRANSACTION /!40100 WITH CONSISTENT SNAPSHOT /和FLUSH TABLES WITH READ LOCK之間執行的DML語句丟失,放到之後,會造成從庫重複插入資料。

  3. mysqldump只適合放到業務低峰期做,如果備份的過程中資料操作很頻繁,會造成Undo表空間越來越大,undo表空間預設是放到共享表空間中的,而ibdata的特性是一旦增大,就不會收縮。

  4. mysqldump的效率還是比較低下,START TRANSACTION /!40100 WITH CONSISTENT SNAPSHOT /只能等到所有表備份完後才結束,其實效率比較高的做法是備份完一張表就提交一次,這樣可儘快釋放Undo表空間快照佔用的空間。但這樣做,就無法實現對所有表的一致性備份。

  5. 當有大事務正在執行的時候,會等很久。。。

  6. 對於資料庫中非innodb儲存引擎的表,不能保證一致性。主要是指myisam表。加了–single-transaction就能保證innodb的資料是完全一致的,而myisam引擎無法保證,必須加–lock-all-tables。
  7. myisam引擎為什麼無法保證在–single-transaction下得到一致性的備份?
    因為它壓根就不支援事務,自然就無法實現上述的過程,雖然添加了–single-transaction引數的myisam表處理過程和上面的完全一致,但是因為不支援事務,在整個dump過程中無法保證可重複讀,無法得到一致性的備份。而innodb在備份過程中,雖然其他執行緒也在寫資料,但是dump出來的資料能保證是備份開始時那個binlog pos的資料。
  8. myisam引擎也要保證得到一致性的資料的話,他是如何實現的呢?
    它是通過新增–lock-all-tables,這樣在flush tables with read lock後,直到整個dump過程結束,斷開執行緒後才會unlock tables釋放鎖(沒必要主動發unlock tables指令),整個dump過程其他執行緒不可寫,從而保證資料的一致性。也就是說沒有第六步6.UNLOCK TABLES。

  9. 5.6的mysqldump利用儲存點機制,每備份完一個表就將一個表上的MDL鎖釋放,避免對一張表鎖更長的時間。

  10. 大家可能有一個疑問,為啥備份innodb表之前,就已經將鎖釋放掉了,這實際上是利用了innodb引擎的MVCC機制,開啟快照讀後,就能獲取那個時間的一致的資料,無論需要備份多長時間,直到整個事務結束(commit)為止。

  11. 為什麼備份完成後沒有commit操作
    最後並沒有看到commit,因為在整個事務中,其實並沒有修改任何資料,只是為了保證可重複讀得到備份時間點一致性的快照,dump完成後提交不提交應該無所謂了。

  /*
    No reason to explicitely COMMIT the transaction, neither to explicitely
    UNLOCK TABLES: these will be automatically be done by the server when we
    disconnect now. Saves some code here, some network trips, adds nothing to
    server.
  */

相關推薦

mysql資料庫備份mysqldump備份原理注意事項

關於MySQL熱備,可分為兩種方式: 邏輯備份 物理備份 對於前者,常用的工具是MySQL自帶的mysqldump,對於後者,常用的工具是Percona提供的XtraBackup。 對於規模比較小,業務並不繁忙的資料庫,一般都是選擇mysqldump。 那麼,mysqldump的

mysqldump備份原理注意事項

關於MySQL熱備,可分為兩種方式: 邏輯備份 物理備份 對於前者,常用的工具是MySQL自帶的mysqldump,對於後者,常用的工具是Percona提供的XtraBackup。 對於規模比較小,業務並不繁忙的資料庫,一般都是選擇mysqldump。

段碼液晶屏實現原理注意事項

**段碼液晶屏由於能提供簡單快捷的顯示效果,被廣泛應用於電子領域。我們生活中常見的空調遙控器、電子血壓計以及電子計算器等等,使用的都是段碼液晶屏。** 圖1:幾種常見的段碼屏 <p> Silicon Labs 的

HttpClient4.5.2 連線池原理注意事項

隨著微服務的流行,服務之間的http呼叫越來越多,遇到的問題也比較多,寫這邊文章的目的也是將自己遇到的坑和解決方案跟大家分享 一、為什麼要用Http連線池 1、降低延遲:如果不採用連線池,每次連線發起Http請求的時候都會重新建立TCP連線(經歷3次握手),用完就會關閉連線(4次揮手),如果採用連線池則減

JavaScript之ES6中解構原理注意事項(陣列和物件)

//ES6中的解構原理(常用型別):   //陣列解構: //陣列的元素是按次序排列的,變數的取值由它的位置決定; let [a,b,c] = [1,2,3]; console.log(a,b,c) //結果為: 1,2,3;   //物件解構變數同名(

總結下linux下的IPC使用原理注意事項

首先說明一下mmap函式用途: 採用共享記憶體通訊的一個顯而易見的好處是效率高,因為程序可以直接讀寫記憶體,而不需 要任何資料的拷貝 1、將一個普通檔案對映到記憶體中,通常在需要對檔案進行頻繁讀寫時使用,這樣用記憶體讀    寫取代I/O讀寫,以獲得較高的效能; 2、將特殊

壓力控制器的原理特點注意事項

壓力控制器的工作原理: 是當設別系統內壓力高於或低於設定的額額定的安全壓力時,壓力開關感應器內的碟片瞬時發生移動,通過連線的導杆推動開關接頭接通或斷開,當壓力降至或上升到設定的額定恢復值時,碟片瞬時復位,開關會自動復位,或者簡單的說是當裝置的被測壓力超過設定的額定值時,彈性元器件的自由端產生

學一點 mysql 雙機異地熱備份----快速理解mysql主從,主主備份原理實踐

server counter ror 位置 正在 大型 主循環 備份 配置詳解 雙機熱備的概念簡單說一下,就是要保持兩個數據庫的狀態自動同步。對任何一個數據庫的操作都自動應用到另外一個數據庫,始終保持兩個數據庫數據一致。 這樣做的好處多。 1. 可以做災備,其中一個壞了可

【VUE】git命令列程式碼提交流程注意事項

本篇為我在提交程式碼的過程中使用過的命令 僅做記錄參考 git命令還有很多 其他功能 可自行百度 命令git add (1)git add . 提交全部修改檔案 (2)git add +檔名 提交單個檔案 命令 git commit -m '描述’ eg: git commi

重灌系統後,重新安裝ORACLE加環境變數配置、客戶端PL/SQL的安裝過程,注意事項(避免再次踩坑)

(1)首先了解什麼是OERACLE及Oracle與PL/SQL是什麼關係: ORACLE是資料庫,有客戶端和伺服器; PLSQL Developer只是第三方工具,服務於ORACLE,類似的工具還有Toad,sqlplus,sql developer等等; 安裝PLSQL Developer

【C++】向量(vector) 基本使用方法注意事項

介紹: 向量(Vector)是一個封裝了動態大小陣列的順序容器(Sequence Container)。跟任意其它型別容器一樣,它能夠存放各種型別的物件。可以簡單的認為,向量是一個能夠存放任意型別的動態陣列。 特點: 1.順序序列 順序容器中的元素按照嚴格的線性順序排序。可以通過元素

Windows下RabbitMQ安裝注意事項

Windows下RabbitMQ安裝及注意事項 簡介 背景 1.      RabbitMQ是一個由erlang開發的AMQP(Advanved Message Queue)的開源實現。 RabbitMQ是實現AMQP(高階訊息佇列協議)的訊

XV6環境搭建注意事項

Ubuntu16.04SLT 64位 工具鏈 sudo apt-get install gcc-multilib libsdl1.2-dev, libtool-bin, libglib2.0-dev, libz-dev, and libpixman-1-dev.     下載

仙人劍花怎麼養 仙人劍花的養殖方法注意事項

劍花也稱霸王花、七星劍花、龍骨花,為仙人掌科量天尺屬植物量天尺的花。夏、秋間採收淨花,縱向切開(基部相連),略蒸後,晒乾。量天尺又名:龍骨花(海南保亭),霸王鞭(海南三亞,廣東肇慶),三角柱、三稜箭(北京俗稱)。很多朋友不知道如何養殖仙人劍花,下面來介紹一下。 從生長環境溫度方面來說

阿里雲備案幕布申請郵寄注意事項

阿里雲備案需要幕布(貌似個別地區,例如魔都是不需要幕布的),阿里雲免費提供幕布,很多使用者不清楚阿里雲幕布去哪申請,阿里雲惠網分享阿里雲備案關於幕布相關問題: 一:阿里雲幕布長啥樣? 二:備案幕布申請: 阿里雲備案系統即可申請幕布,首先需要先完成備案初審,初審後登入 阿里雲備案系統,辦理網站

CSS變數實用指南注意事項

近年來,一些動態特性已經開始成為 CSS 語言本身的一部分。 CSS變數 – 官方的術語為 “自定義屬性” – 已經已經加入規範並且具有很好的瀏覽器支援,而 CSS mixins 目前正在開發中 。 在本文中,你將瞭解如何開始將CSS變數整合到CSS開發工作流程中,讓你的樣式表更好維護,且減少重複。 讓我

MySQL索引的使用注意事項

索引是儲存引擎用於快速找到記錄的一種資料結構。索引優化應該是對查詢效能優化最有效的手段了。索引能夠輕易將查詢效能提高几個數量級,"最優"的索引有時比一個"好的"索引效能要好兩個數量級。 索引可以包含一個(單列索引)或多個列(組合索引)的值。 想要使用組合索引首先要了解一個原則:最左字首原則。如果索引包含多

Git- .gitignore匹配規則注意事項

.gitignore檔案的匹配規則 Windows中可以通過echo 命令或者用Windows中的bash建立.gitignore檔案。其主要的匹配規則如下: *.a # 忽略所有 .a 結尾的檔案 !lib.a # 但 lib.a 除外 TODO # 僅僅

分享知識-快樂自己:Struts2(動態方法、動態結果、萬用字元、方法內部跳轉、action跳轉、OGNL 的使用注意事項

這裡主要以案例演示:涵蓋以下知識點 1、動態方法呼叫:使用關鍵 符號 ! 進行操作   例如:/名稱空間 ! 方法名 2、動態結果集:就是說,通過後臺返回的結果 ${} 獲取,重定向到符合預期的頁面。 3、萬能萬用字元:*_*  :第一個 * 為 類名、第二個 * 為方

iOS啟動頁尺寸注意事項

執行環境:Xcode 7.2                    OS X 10.11 1、點選LauchImage,在右側選擇需要支援的裝置及支援的螢幕方向 2、點選圖片的位