程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL/MariaDB數據備份與數據恢復完整

MySQL/MariaDB數據備份與數據恢復完整

編輯:MySQL綜合教程

   MariaDB數據庫管理系統是MySQL的一個分支,主要由開源社區在維護,采用GPL授權許可。開發這個分支的原因之一是:Oracle公司收購了MySQL後,有將MySQL閉源的潛在風險,因此社區采用分支的方式來避開這個風險。

  數據對我們來說再重要不過了,那我們如何做到對數據盡可能的安全呢,當我們的數據丟失了那又該怎麼做呢,所以說數據備份對我們的數據安全性來說太重要了。

  數據對我們來說再熟悉不過了,也最平常不過了,我們每天都在接觸各色各樣的數據,數據記錄了我們平常相關的業務信息,所以數據對於我們來說是很重要的, 這麼重要的數據如果我們的數據丟失了那我們是不是相關的業務都沒法進行了呢,這應該是個很麻煩的問題,那我們怎麼保護我們的數據的安全呢,這就要用到我們 的數據備份了。

  如何執行備份恢復:備份與恢復在工作環境中是重中之重,為什麼需要用到備份和恢復呢:

  1、一般是做災難恢復的,比如說自然災害等。

  2、可以做審計的,比如說某一數據在過去是什麼樣的。

  3、做測試的,比如說一個新的業務架構數據存儲方式是否扛得著業務的訪問

  備份的目的是用於恢復的,如果備份的數據用到時恢復不了數據怎麼辦,所以對備份數據做恢復測試是很有必要的。而且還要定期性的去做測試。

  備份類型:有很多種

  根據備份時,數據庫服務器是否在線:

  冷備份:cold backup,服務器要離線,意味著我們的讀寫操作都不可以進行了,這是最安全的備份方式,也是最不靠譜的方式。

  溫備份:warm backup,全局施加共享鎖,只可讀,不可寫的備份叫溫備份

  熱備份:hot backup,數據庫不離線,讀寫操作都可以進行

  InnoDB記錄數據時都會給數據一個序列號,所以在備份時基於MVCC(多版本並發控制)的機制自動加快照,每啟動一個事務都會創建當前集的一個快 照,而後基於MVCC的機制把每一個序列號都給它記錄一份下來,備份時只備份序列號或序列號之前的數據,往後發生的將不做備份,如果事務的隔離級別不是特 別高的話,它並不會影響事務的讀寫操作,而這樣備份出來的數據一定是時間點一致的數據,所以要完成熱備份,通常是基於事務的存儲引擎才能夠完成的。

  根據備份時的數據集進行分類:

  完全備份:full backup:指備份整個庫,當下數據集的整個庫的數據

  部分備份:partial backup:只備份某張表或某張表的一部份數據,有時備份單張表是有必要的。

  根據備份時的接口(直接備份數據文件還是通過mysql服務器導出數據)

  物理備份:直接復制(歸檔)數據文件的備份方式;跨平台能力沒有邏輯備份好,physucal backup。大數據集用這個比較好。

  邏輯備份:把數據庫中提出來保存為文本文件;通常使用的工具是mysqldump,logical backup,對於大容量數據不適用。恢復速度很慢,占據空間很大

  根據備份時是否備份整個數據還是僅備份變化的數據:

  完全備份:full backup,跟備份數據集中的完全備份概念是相同的,也是備份整個庫

  增量備份:incremental backup,上一次完全備份之後所改變的數據做備份的為增量備份,比如說周一做一次備份,周二做一次備份,周三又做一次,這樣一天天累加上去的叫增量備份。比較節約空間。

  差異備份:differential backup,比如說周一做一次備份,到周二了就把周一和周二這兩天的做一次備份,到周三就把周一周二周三的做一次備份,這就叫差異備份。比較容易恢復。

  備份策略:需要考慮到的問題

  1、選擇備份方式,選擇哪種方式根據我們的生產環境所需要來定;

  2、執行備份時間,選項一個訪問最少的時間做備份是比較合理的;

  3、考慮到恢復成本:恢復時長;

  4、備份成本:考慮到鎖時間、備份時長、備份負載;

  備份對象:我們備份需要備份什麼呢

  1、備份數據庫中的數據是最重要的;

  2、MySQL的配置文件,這個也是我們備份的對象

  3、MySQL的代碼也是需要備份的:存儲過程,存儲函數,觸發器

  4、OS相關的配置文件,如crontab配置計劃及相關的腳本

  5、如果是在主從復制的場景中,跟復制相關的信息也要備份

  6、為了保證數據足夠可靠,二進制日志文件也需要備份

  常用的備份工具:

  mysqldump:邏輯備份工具,是單線程備份工具,所以在某個服務器上做備份時它只能啟動一個CPU啟動一個線程進行備份,性能比較差。

  對InnoDB熱備、對MyISAM只能做到溫備、對Aria溫備,備份和恢復過程較慢;

  mysqldumper:多線程的mysqldump,對多個庫或多張表可以同時進行,提高性能;

  mysqldump、mysqldumper,這兩個都是邏輯備份工具,通常情況也很難實現差異或增量備份,只能做完全備份,但可以做部分備份,比如只備份一張表是可以實現的;

  基於冷備份時:cp, 要基於lvm-snapshot邏輯卷快照進行備份的,接近於熱備工具,因為要先請求全局鎖,而後創建快照,並在創建快照完成後釋放全局鎖;而後使用 cp、tar等工具進行物理備份(因為復制的源數據文件),所以備份和恢復數據速度較快,缺點很難實現增量備份,並且請求全局鎖需要等待一段時間,在繁忙 的服務器上尤其如此。

  SELECT clause INTO OUTFILE ‘/path/to/somefile’;把挑選出來的子句保存到某一個文件中,是個部分備份工具,不會備份關系定義,僅備份表中的數據,但這也是個邏輯 備份工具,在速度上也快於mysqldump,也沒法實現增量備份。

  LOAD ADTA INFILE ‘/path/from/somefile’;表示從哪裡讀數據來恢復的;

  Innobase:提供了商業備份工具為Innobackup,可以實現InnoDB的熱備支持增量備份;但是對於MyISAM不支持增量備份,只能實現完全備份,屬於物理備份,速度比較快。

  Xtrabackup:由Percona組織提供的開源備份工具,物理備份,速度快;

  Mysqlhostcopy:幾乎冷備,吹牛工具,不適用;

  mysqldump:常用的備份工具,也是個邏輯備份工具,用於小數據備份,一般都是在5G以下的小數據進行備份;可以使用文本進行二次處理;相當於MySQL的客戶端工具

  使用格式:mysqldump [options] [db_name [tbl_name ...]]

  備份單個庫時用這個工具:mysqldump[option] db_name

  恢復時,如果目標庫不存在,需要事先手動創建

  --all-databases:備份所有的數據庫--databases db1 db2:備份指定的多個數據庫,用空格隔開--lock-all-tables:請求鎖定所有表之後再備份,一般只對MyISAM做溫備,不過也可以對InnoDB和Aria做溫備。--events:備份事件調度器代碼--routines:備份存儲過程和存儲函數--triggers:備份觸發器--flush-logs:備份前、請求到鎖以後滾動日志,備份時滾動日志,手動滾動就要手動施加鎖--master-data=[0|1|2]復制時的同步位置標記,0表示不記錄,1記錄carnge master語句,2記錄為注釋為change master語句--single-transaction:能夠對InnoDB存儲引擎實現熱備份,啟動一個單一的大事物,基於MVCC(多版本並發控制)實現對InnoDB存儲引擎的熱備,它會自動加鎖的,不要跟--lock-all-tables同時使用;

  # mysqldump --databases hellodb --lock-all-tables > /tmp/hellodb.sql :備份數據庫,並且請求表鎖,這裡備份的所有寫操作都會被阻塞,這種方式也不太理想。

  # mysqldump --databases hellodb --lock-all-tables --flush-logs > /tmp/hellodb.sql

  # mysqldump --databases hellodb --single-transaction --flush-logs > /tmp/hellodb.sql:保證這個庫下所有的表的存儲引擎都是InnoDB的前提下使用--single-transaction進行熱備。

  分時間段查看二進制日志後重定向到某個文件中去:

  # mysqlbinlog --start-porition=367 --stop-position=669 master-bin.000005 > /tmp/hellodb.inc.sql

  定義一個開始點和一個結束點就可以把二進制文件重定向到某個文件中再進行恢復了;

  使用mysqldump備份時:

  請求鎖:--lock-all-tables使用--single-transaction進行innodb熱備;

  滾動日志:--flush-logs

  選定要備份的庫:--databases

  指定二進制日志文件及位置:--master-data=2

  注意:備份前需要加鎖,恢復時,建議關閉二進制日志,關閉其它用戶連接

  備份策略:mysqldump+二進制日志文件:

  恢復:完全備份+各二進制日志文件中至此刻的事件,恢復過程發生的事件沒必要也寫到二進制日志文件中去;所以在恢復時要臨時性的關閉二進制日志文件:

  MariaDB [(hellodb)] > set session sql_log_bin=0:臨時關閉二進制日志文件

  MariaDB [(hellodb)] > source /tmp/hellodb.sql;在數據庫命令行直接讀取備份文件

  對MySQL配置文件,以及與MySQL相關的OS配置文件在每次修改後都應該直接進行備份

  lvm-snapshot:基於LVM快照的備份

  1、基於快照做備份有個提前,事物日志跟數據文件必須在同一個卷上;

  2、創建快照卷之前,要請求MySQL的全局鎖,在快照創建完成之後釋放鎖;

  3、請求全局鎖完成這後做一次日志滾動;做標記,時間記錄,做二進制日志文件及位置標記(需要手動進行);

  注意:

  1、將數據和備份放在不同的磁盤設備上,異機或異地的備份存儲為理想;

  2、備份的數據應該周期性的進行還原測試;

  3、每次災難恢復後都應該立即做一次完全備份

  4、針對不同規模或級別的數據量,要定制好備份策略;

  5、二進制日志應該跟數據文件在不同的磁盤上,並周期性的備份好二進制日志文件;

  從備份中恢復應該遵循的步驟:

  1、停止MySQL服務器;

  2、記錄服務器的配置和文件權限;

  3、將數據從備份移到MySQL數據目錄,其執行方式依賴於工具;

  4、改變配置和文件權限;

  5、以限制訪問模塊重啟服務器,mysqld的--skip-network選項可跳過網絡功能;

  方法:編輯my.cnf配置文件,添加如下項

  skip-networking

  socket=/tmp/mysql-recovery.sock

  6、載入邏輯備份(如果有),而後檢查和重放二進制日志

  7、檢查已經還原的數據;

  8、重新以完全訪問模式重啟服務器;

  使用mysqldump實現備份,用二進制日志恢復數據,這裡我們以當前系統上的數據庫hellodb為例:

  第一步:先把hellodb這個數據庫做一次完全備份,當然,如果數據庫的數據很大,比如說大於10G的話不建議使用mysqldump這個工具做備份,這裡我們只為了說明問題:

  # -u指定用戶,-p指用戶密碼,--databases指定備份哪個數據庫,--lock-all-tables指備份時請求表鎖,--flush-logs滾動日志

  [root@node0 ~]# mysqldump -uroot -plinux --databases hellodb --lock-all-tables --flush-logs --master-data=2 > /root/hellodb.sql

  [root@node0 ~]# ll -h hellodb.sql-rw-r--r-- 1 root root 7.8K May 2 14:26 hellodb.sql

  [root@node0 ~]#

  第二步:在數據庫hellodb中修改或創建一些表或數據,使得之前備份的數據跟現有的數據庫中的數據存在差別,以完後後面的通過二進制日志進行數據恢復:

  MariaDB [hellodb]> CREATE TABLE newtable;

  ERROR 1113 (42000): A table must have at least 1 column

  MariaDB [hellodb]> CREATE TABLE newtable(Name CHAR(20));

  Query OK, 0 rows affected (1.11 sec)

  MariaDB [hellodb]> INSERT INTO newtable values ('Tom'),('Jerry'),('Lucy');

  Query OK, 3 rows affected (0.13 sec)

  Records: 3 Duplicates: 0 Warnings: 0

  第三步:把這個hellodb這個數據庫給刪除了去:

  MariaDB [hellodb]> CREATE TABLE newtable;

  ERROR 1113 (42000): A table must have at least 1 column

  MariaDB [hellodb]> CREATE TABLE newtable(Name CHAR(20));

  Query OK, 0 rows affected (1.11 sec)

  MariaDB [hellodb]> INSERT INTO newtable values ('Tom'),('Jerry'),('Lucy');

  Query OK, 3 rows affected (0.13 sec)

  Records: 3 Duplicates: 0 Warnings: 0

  第四步:查看我們的二進制日志文件,把後來改修改和創建的記錄二進制日志的信息保存出來,以便我們恢復新增的數據內容,我們備份時做了日志滾動,所以查看最後一個日志信息就可以了;

  [root@node0 ~]# cd /mydata/data/[root@node0 data]# mysqlbinlog --start-position=403 --stop-position=663 mysql-bin.000004 > /tmp/hellodb.binlog.sql

  第五步:恢復數據,進入到mysql的命令行模式下,把二進制日志關掉,恢復數據時不需要把恢復信息記錄到二進制日志中去;

  # 關閉當前全話的二進制日志文件

  MariaDB [(none)]> SET session sql_log_bin=0;

  MariaDB [(none)]> source /root/hellodb.sql

  MariaDB [hellodb]> SHOW MASTER STATUS; 查看兩次二進制文件有沒有改動;+------------------+----------+--------------+------------------+

  | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

  +------------------+----------+--------------+------------------+

  | mysql-bin.000004 | 815 | | |

  +------------------+----------+--------------+------------------+MariaDB [hellodb]> SHOW TABLES;

  MariaDB [hellodb]> source /tmp/hellodb.binlog.sql

  MariaDB [hellodb]> SELECT * FROM newtable;+-------+

  | Name |

  +-------+

  | Tom |

  | Jerry |

  | Lucy |

  +-------+3 rows in set (0.00 sec)

  MariaDB [hellodb]> SET session sql_log_bin=1; 讓二進制上線

  OK,這種就是基於mysqldump+二進制日志完成數據完全恢復過來了,通過二進制日志可以很好的幫助我們恢復那些可能沒有來得急備份的數據,對我們的數據安全有很重要。

  lvm-snapshot:基於邏輯卷快照做備份,這裡要注意的是,快照並不是備份,最多也只是說借助於快照來做數據備份,快照本身不是備份;

  做了快照之後,一旦源卷的數據需要修改,就要把源卷上的數據復制一份到快照卷上,以後再通過快照卷訪問時,那些修改了的數據都通過快照存儲來訪問,沒修改的還通過源卷訪問,快照只存儲變化的數據;

  1、它僅僅是作為源卷的一個訪問路徑;

  2、剛創建好的快照卷時,快照卷中是沒有任何數據的,它僅是所有數據指向了源卷的數據,所以訪問的數據都是來自源卷;

  3、一旦源卷中的數據需要修改了,某一數據在改之前需要將數據復制一份到快照卷中,所以以後再通過快照卷訪問的數據都是一部分來自快照卷,一部份來自源 卷;那些修改的數據來自快照卷,沒修改的數據來自源卷;快照卷僅是能夠給我們提供了一個時間一致性文件的訪問通路;

  做快照卷要注意的幾點:

  1、基於快照備份時,事務日志必須跟數據文件在同一個卷上;

  2、創建快照卷之前,要請求mysql的全局鎖,在快照創建完成之後釋放鎖;

  3、請求全局鎖完成之後做一次日志滾動,以便記錄時間點的;做二進制日志文件及位置標記,就是master-data;

  第一步:首先先看一下你的數據目錄的是不是邏輯卷,mount看一下,如果不是邏輯卷的話就別這樣玩;

  [root@node0 ~]# mount/dev/mapper/vg0-root on / type ext4 (rw)

  proc on /proc type proc (rw)

  sysfs on /sys type sysfs (rw)

  devpts on /dev/pts type devpts (rw,gid=5,mode=620)

  tmpfs on /dev/shm type tmpfs (rw)/dev/sda1 on /boot type ext4 (rw)/dev/mapper/vg0-usr on /usr type ext4 (rw)/dev/mapper/vg0-var on /var type ext4 (rw)/dev/mapper/mydata-mysqldata on /mydata/data type ext4 (rw,noatime)

  none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)

  [root@node0 ~]# lvs

  LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert

  mysqldata mydata -wi-ao---- 8.00g

  root vg0 -wi-ao---- 20.00g

  swap vg0 -wi-ao---- 2.00g

  usr vg0 -wi-ao---- 10.00g

  var vg0 -wi-ao---- 20.00g

  [root@node0 ~]# vgs

  VG #PV #LV #SN Attr VSize VFree

  mydata 1 1 0 wz--n- 10.00g 2.00g

  vg0 1 4 0 wz--n- 59.99g 7.99g

  [root@node0 ~]#

  第二步:請求鎖,這個如果是在生產環境中我們可以用腳本來完成,因為這樣請求到釋放鎖的時間就可以比較快;

  MariaDB [(none)]> FLUSH TABLES WITH READ LOCK; # 請求鎖

  Query OK, 0 rows affected (0.01 sec)

  MariaDB [(none)]> FLUSH LOGS; # 滾動一下日志

  Query OK, 0 rows affected (0.02 sec)

  MariaDB [(none)]> SHOW MASTER STATUS; # 查看一下日志position信息+------------------+----------+--------------+------------------+

  | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

  +------------------+----------+--------------+------------------+

  | mysql-bin.000002 | 365 | | |

  +------------------+----------+--------------+------------------+1 row in set (0.04 sec)

  MariaDB [(none)]>

  第三步:創建快照卷,要在你的邏輯卷的有效空間大小范圍內創建,不能超過邏輯卷的大小:

  [root@node0 ~]# mkdir backup

  [root@node0 ~]# mysql -e 'show master status'+------------------+----------+--------------+------------------+

  | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

  +------------------+----------+--------------+------------------+

  | mysql-bin.000002 | 365 | | |

  +------------------+----------+--------------+------------------+[root@node0 ~]# mysql -e 'show master status' > /root/backup/binlog.pos

  [root@node0 ~]# lvcreate -L 100M -s -n mydata-snap -p r /dev/mydata/mysqldata

  Logical volume "mydata-snap" created

  [root@node0 ~]# lvs

  LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert

  mydata-snap mydata sri-a-s--- 100.00m mysqldata 0.01

  mysqldata mydata owi-aos--- 8.00g

  root vg0 -wi-ao---- 20.00g

  swap vg0 -wi-ao---- 2.00g

  usr vg0 -wi-ao---- 10.00g

  var vg0 -wi-ao---- 20.00g

  [root@node0 ~]#

  第四步:然後再到mysql命令行中釋放鎖:

  MariaDB [(none)]> UNLOCK TABLES;

  Query OK, 0 rows affected (0.01 sec)

  MariaDB [(none)]>

  第五步:掛載快照卷,然後需要備份什麼只需要復制一份數據目錄就可以了,其實的按需要做備份就可以了,如果不確定也可以全都復制好了,安全起見:

  [root@node0 ~]# mount /dev/mydata/mydata-snap /data -o ro

  [root@node0 ~]# cd /data/[root@node0 data]# ls aria_log.00000001 ibdata1 multi-master.info mysql-bin.000002 node0.tanxw.com.pid

  aria_log_control ib_logfile0 mysql mysql-bin.index test

  hellodb ib_logfile1 mysql-bin.000001 node0.tanxw.com.err

  [root@node0 data]#

  第六步:這裡才是做真正的備份,只要直接復制數據就可以了,備份完之後就可以卸載快照卷了,如果不需要就可以把快照卷刪除就可以了:

  [root@node0 data]# cp -a /data/ /root/backup/data-2014-05-02 # -a歸檔復制數據

  [root@node0 data]# cd /root/backup/data-2014-05-02[root@node0 data-2014-05-02]# ls aria_log.00000001 ibdata1 multi-master.info mysql-bin.000002 node1.tanxw.com.pid

  aria_log_control ib_logfile0 mysql mysql-bin.index test

  hellodb ib_logfile1 mysql-bin.000001 node1.tanxw.com.err

  [root@node0 data-2014-05-02]# pwd/root/backup/data-2014-05-02[root@node0 data-2014-05-02]# umount /data/[root@node0 ~]# lvremove /dev/mydata/mydata-snap # 刪除快照

  Do you really want to remove active logical volume mydata-snap? [y/n]: y

  Logical volume "mydata-snap" successfully removed

  [root@node0 ~]#

  在這裡需要注意的是:如果備份這一刻有數據修改了,那我們備份下來的數據是不會保存快照後修改的數據的;

  結束:

  數據備份與恢復的重要性大家都知道,當然備份也是其中一個而且是歸重要的一個保護數據安全性的重要手段之一,所以能熟練掌握數據的備份與恢復對我們工作來說也是至關重要的,有什麼不對希望大神多多指點。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved