MySQL備份與恢復

一、備份的目的


  • 災難恢復。發生災難時,用於恢復損壞的數據
  • 審計。數據庫在過去某一個時間點是什麼樣的
  • 測試。測試新功能是否可用

二、備份的分類


1.物理備份(physical backup)

直接複製數據文件,打包歸檔,不需要額外工具直接歸檔命令即可,但是跨平臺能力比較差;如果數據量超過幾十個G,則適用於物理備份

  • 冷備(cold backup):服務器離線,讀寫操作都不能進行
  • 溫備(warm backup):服務器在線,全局施加共享鎖,只能讀不能寫
  • 熱備(hot backup):數據庫在線,備份的同時,讀寫照樣進行

注:MyISAM不支持熱備,InnoDB支持熱備,但是需要專門的工具

2.邏輯備份(logical backup)

把數據抽取出來保存在sql腳本中,可以使用文本編輯器編輯,並且導入方便,直接讀取sql語句即可;但邏輯備份恢復時間慢,佔據空間大,無法保證浮點數的精度,並且恢復完數據庫後需要重建索引

三、備份的方式


  • 全量備份(full backup):備份MySQL中所有的庫和表,佔用空間較大,是增量備份和差異備份的前提條件
  • 增量備份(incremental backup):備份與上次全量、增量、差異備份後不同的數據內容,比較節約空間。備份數據少、備份速度快、恢復速度慢
  • 差異備份(differential backup):備份從當前時間點到上次完整備份之間不同的數據內容,備份數據多、備份速度慢、恢復速度快

四、備份策略


1.備份需要考慮的因素

備份方式、備份實踐、備份成本、鎖時間、備份時長、性能開銷、恢復成本、恢復時長、所能夠容忍丟失的數據量

2.不同環境的解決方案

針對不同的場景下, 我們應該制定不同的備份策略對數據庫進行備份, 一般情況下, 備份策略一般爲以下三種

  • 直接cp,tar複製數據庫文件
  • mysqldump+複製BIN LOGS
  • vm2快照+複製BIN LOGS
  • xtrabackup

(1)如果數據量較小,可以使用第一種方式,直接複製數據庫文件

(2)如果數據量還行,可以使用第二種方式,先使用mysqldump對數據庫進行完全備份,然後定期備份BINARY LOG達到增量備份的效果

(3)如果數據量一般,而又不過分影響業務運行,可以使用第三種方式,使用lvm2的快照對數據文件進行備份,而後定期備份BINARY LOG達到增量備份的效果

(4)如果數據量很大,而又不過分影響業務運行,可以使用第四種方式,使用xtrabackup進行完全備份後,定期使用xtrabackup進行增量備份或差異備份

3.備份的內容

  • 數據庫中的數據
  • 數據庫的配置文件
  • mysql中的代碼:存儲過程,存儲函數,觸發器
  • OS相關的配置文件,chrontab中的備份策略腳本
  • 如果是主從複製的場景中,複製相關的信息
  • 二進制日誌文件需要定期備份,一旦發現二進制文件出現問題,需馬上對數據進行完全備份

4.MySQL常用備份工具

  • mysqldump:邏輯備份工具, 適用於所有的存儲引擎, 支持溫備、完全備份、部分備份、對於InnoDB存儲引擎支持熱備
  • Xtrabackup(通常用innobackupex工具):強大的InnoDB/XtraDB熱備工具, 支持完全備份、增量備份, 由percona提供,屬物理備份,速度快
  • lvm-snapshot:接近於熱備的工具,因爲要先請求全局鎖,而後創建快照,並在創建快照完成後釋放全局鎖;很難實現增量備份,並且請求全局需要等待一段時間,在繁忙的服務器上尤其如此,幾乎熱備, 需藉助文件系統管理工具進行備份
  • mysqldumper:多線程的mysqldump
    SELECT clause INTO OUTFILE '/path/to/somefile' LOAD DATA INFILE '/path/from/somefile'
  • mysqlhotcopy:接近冷備,基本沒用,僅支持MyISAM存儲引擎
  • cp、tar等歸檔複製工具:物理備份工具, 適用於所有的存儲引擎, 冷備、完全備份、部分備份

五、備份案例


1.使用tar或cp冷備份並恢復

(1)數據模擬

mysql -u root -p                                        //登錄MySQL

mysql>create database hiahia;          //創建名爲hiahia的數據庫

mysql>create table hiahia.user (user_name char(12),user_phone char(11),primary key (user_phone));

//在hiahia庫下創建user表,表中兩個字段,其中user_phone爲主鍵

mysql>insert into hiahia.user values ('Zhangsan','2691376416');

mysql>insert into hiahia.user values ('Lisi','2691376417');

mysql>select * from hiahia.user;        //查看錶中的數據

(2)備份與恢復【cp命令】

mysql>flush tables with read lock;          //向所有表施加讀鎖,防止過程中有寫入

mkdir /Backup/                                    //創建備份數據庫存放目錄

chown -R mysql:mysql /Backup/       //更改所有者及所有組

cp -a /usr/local/mysql/data/* /Backup/   //保留權限拷貝源數據文件.

rm -rf /usr/local/mysql/data/*                  //刪除數據庫的所有文件,模擬故障

mysql -u root -p

mysql>select * from hiahia.user;             //驗證數據情況

cp -a /Backup/* /usr/local/mysql/data/  //將備份的數據文件拷貝回去

mysql -u root -p

mysql>select * from hiahia.user;             //驗證數據情況

(3)備份與恢復【tar命令】

mysql>flush tables with read lock;          //向所有表施加讀鎖,防止過程中有寫入

mkdir /Backup/                                    //創建備份數據庫存放目錄

chown -R mysql:mysql /Backup/       //更改所有者及所有組

cd /usr/local/mysql/data/                          //進入MySQL數據存儲目錄

tar Jcvpf /Backup/mysql-$(date +%F).tar.xz ./*

//使用xz壓縮當前目錄下所有內容並將壓縮文件放入/Backup目錄,以日期取名文件

rm -rf /usr/local/mysql/data/*                  //刪除數據庫的所有文件,模擬故障

mysql -u root -p

mysql>select * from hiahia.user;             //驗證數據情況

tar -Jxvpf /Backup/mysql-2018-03-21.tar.xz -C /usr/local/mysql/data/

//通過tar備份文件恢復數據到/usr/local/mysql/data/目錄下

mysql -u root -p

mysql>select * from hiahia.user;             //驗證數據情況

2.使用mysqldump全量備份恢復

(1)數據模擬

mysql -u root -p                                        //登錄MySQL

mysql>create database hiahia;          //創建名爲hiahia的數據庫

mysql>create table hiahia.user (user_name char(12),user_phone char(11),primary key (user_phone));

//在hiahia庫下創建user表,表中兩個字段,其中user_phone爲主鍵

mysql>insert into hiahia.user values ('Zhangsan','2691376416');

mysql>insert into hiahia.user values ('Lisi','2691376417');

mysql>select * from hiahia.user;        //查看錶中的數據

(2)mysqldump全量備份

mkdir /Backup/                                           //創建備份數據庫存放目錄
chown -R mysql:mysql /Backup/              //更改所有者及所有組
(2.1)備份庫
mysqldump -u 用戶名 -p 密碼 數據庫名 >/備份路徑/備份文件名

mysqldump -u root -p hiahia >/Backup/hiahia-$(date +%F).sql

//備份hiahia庫,並將導出的sql語句文件重定向導出到/Backup目錄下
(2.2)備份庫下的表
mysqldump -u 用戶名 -p 密碼 數據庫名 表名 >/備份路徑/備份文件名

mysqldump -u root -p hiahia user >/Backup/hiahia-user-$(date +%F).sql

//備份hiahia庫下的user表,並將導出的sql語句文件重定向導出到/Backup目錄下
(2.3)備份多個庫
mysqldump -u 用戶名 -p 密碼 --databases 庫名1 [庫名2] ... >/備份路徑/備份文件名

mysqldump -u root -p --databases hiahia mysql >/Backup/hiahia-mysql-$(date +%F).sql

//備份hiahia、mysql兩個庫,並將導出的sql語句文件重定向導出到/Backup目錄下
(2.4)備份整個庫
mysqldump -u 用戶名 -p 密碼 --all-databases >/備份路徑/備份文件名

mysqldump -u root -p --all-databases >/Backup/all-$(date +%F).sql

//將這個MySQL庫備份,並將導出的sql語句文件重定向導出到/Backup目錄下
(2.5)備份表結構
mysqldump -u 用戶名 -p [密碼] -d 數據庫名 表名 >/備份路徑/備份文件名

mysqldump -u root -p -d hiahia user >/Backup/hiahia-desc-user-$(date +%F).sql

//只備份hiahia庫下user表的結構(即表的頭部),並將導出的sql語句文件重定向導出到/Backup目錄下

(3)mysqldump全量恢復

(3.1)使用source恢復
  • 登錄MySQL數據庫

  • 執行source 備份sql腳本文件路徑
(3.2)使用mysql命令恢復
mysql -u root -p [密碼] </庫備份腳本路徑
(3.3)恢復表
mysql -u root -p                                        //登錄MySQL數據庫,密碼爲123

mysql>drop table hiahia.user;                 //刪除user表,模擬表故障

mysql>select * from hiahia.user;             //驗證數據情況

mysql>use hiahia;                               //進入要恢復的庫

mysql>source /Backup/hiahia-user-2018-03-21.sql

//通過備份的表sql文件恢復數據

mysql>select * from hiahia.user;             //驗證數據情況
(3.4)恢復庫
mysql -u root -p                                        //登錄MySQL數據庫,密碼爲123

mysql>drop database hiahia;                   //刪除hiahia庫,模擬庫故障

mysql>show databases;                      //驗證數據情況

注:使用mysql恢復庫時,如庫已不存在,需自行創建同名庫,再通過備份庫文件恢復,並且在恢復時需指定恢復到哪個庫

mysql -u root -p                                        //登錄MySQL數據庫,密碼爲123

mysql>create database hiahia;          //創建庫

mysql -u root -p hiahia </Backup/hiahia-2018-03-21.sql

//通過備份庫sql文件恢復庫數據到hiahia庫下

mysql -u root -p                                        //登錄MySQL數據庫,密碼爲123

mysql>show databases;                      //驗證數據情況

六、MySQL增量備份與恢復


mysqldump完全備份的缺點:備份數據中有重複數據、備份時間與恢復時間長

1.增量備份

備份自上一次備份之後增加或變化的文件或者內容

特點

  • 重複數據,備份量不大,時間短
  • 但恢復麻煩,需要上次完整備份及完整備份之後所有的增量備份才能恢復,而且要對所有增量備份進行逐個反推恢復
  • 但MySQL中並未直接提供增量備份方法,但可通過MySQL提供的二進制日誌(Binary logs)間接實現增量備份

2.二進制日誌

  • 保存所有更新數據庫的操作
  • MySQL啓動後便開始記錄,當達到max_binlog_size選項值後或收到flush logs命令後自動重新創建新的日誌文件
  • 因此只需定時執行flush logs命令,再將新生成日誌文件保存到安全位置,即可完成這一時間段增量備份

3.案例:MySQL增量備份

(1)數據模擬

mysql -u root -p                                        //登錄MySQL

mysql>create database hiahia;          //創建名爲hiahia的數據庫

mysql>create table hiahia.user (user_name char(12),user_phone char(11),primary key (user_phone));

//在hiahia庫下創建user表,表中兩個字段,其中user_phone爲主鍵

mysql>insert into hiahia.user values ('Zhangsan','2691376416');

mysql>insert into hiahia.user values ('Lisi','2691376417');

mysql>select * from hiahia.user;        //查看錶中的數據

(2)開啓MySQL二進制日誌

  • 方式一:編輯my.cnf配置文件在[mysqld]項下加入log-bin=filepath,重啓mysqld服務即可(默認即爲開啓)

MySQL備份與恢復

  • 方式二:運行"mysqld --log-bin=filepath",然後重啓mysqld服務

注:filepath爲二進制文件存儲路徑,如不指定路徑只指定名稱,默認存儲在數據目錄下(源碼默認:/usr/local/mysql/data/;rpm/yum:/var/lib/mysql)

(3)完整備份

增量備份前,必須有完整備份纔可以

mysqldump -u root -p hiahia user >/Backup/hiahia-user-$(date +%F).sql
//備份hiahia庫下的user表,並將導出的sql語句文件重定向導出到/Backup目錄下

(4)增量備份

mkdir /Backup/                                           //創建備份數據庫存放目錄

chown -R mysql:mysql /Backup/              //更改所有者及所有組

ls -l /usr/local/mysql/data/
//增量備份前,查詢原二進制日誌文件名,以便區分新舊二進制日誌文件

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>flush logs;                                        //生成新的二進制日誌,下面操作全部記錄到新日誌文件中,方便增量備份

mysql>insert into hiahia.user values ('hehe','13452231231');
//模擬數據更改
mysql> insert into hiahia.user values ('haha','13456223123');

mysql>insert into hiahia.user values ('huohuo','12345621231');

mysql>insert into hiahia.user values ('heihei','136741234312');

mysqladmin -u root -p flush-logs
//通過命令,再次生成新的日誌文件,以便將新增數據記錄日誌截取爲獨立的日誌文件

ls -l /usr/local/mysql/data/
//查詢新增二進制日誌文件,新增日誌文件裏即記錄新增量數據情況

mysqlbinlog /usr/local/mysql/data/mysql-bin.000005
//使用mysqlbinlog命令查看新記錄二進制日誌內容

注:如mysqlbinlog查看時出現"unknown variable ....",可以使用mysqlbinlog --no-defaults 二進制日誌文件,該方式查看

cp /usr/local/mysql/data/mysql-bin.000005 /Backup/

4.案例:MySQL增量恢復

增量恢復場景

  • 人爲SQL語句破壞數據庫
  • 在下次全量備份前發生系統故障導致數據庫數據丟失
  • 主從架構中,主庫數據發生故障

數據丟失分類

  • 只丟失完全備份之後的數據
  • 包括完整備份在內的所有數據

(1)只丟失完全備份之後的數據(恢復過程)

mysqladmin -u root -p flush-logs
//生成新的二進制日誌,避免恢復時將所有的操作都記錄,導致數據出錯(建議備份前和恢復前都輸入一次)

mysqlbinlog 二進制日誌文件 | mysql -u root -p
//將二進制增量文件逐個推倒恢復數據庫,直到恢復到完整備份時刻

(2)包括完整備份在內的所有數據(恢復過程)

mysqladmin -u root -p flush-logs
//生成新的二進制日誌,避免恢復時將所有的操作都記錄,導致數據出錯(建議備份前和恢復前都輸入一次)

mysql -u root -p 數據庫名 </庫備份腳本路徑.
//恢復完整備份數據

mysqlbinlog 二進制日誌文件 | mysql -u root -p

(3)基於時間點與位置的恢復

默認增量恢復是恢復整個二進制日誌中內容,當然也可以利用二進制日誌實現基於某個時間點及位置的恢復,達到精確恢復
(3.1)基於時間點恢復
指定導入停止時間點,可只恢復到該時間點前面數據,從而跳過某個發生錯誤的時間點實現數據恢復;也可指定導入開始時間點,從該時間點到日誌文件結尾全部導入

mysqlbinlog --stop-datetime='日期 時間' 二進制日誌文件 | mysql -u root -p

mysqlbinlog --start-datetime='日期 時間' 二進制日誌文件 | mysql -u root -p
(3.2)基於位置恢復
如採用基於時間點恢復,可能出現某個時間點既同時存在正確操作又存在錯誤操作的情況,因此基於位置的恢復可以更好的控制

每個操作都會記錄一個end_log_pos值,使用基於位置恢復可以基於某條語句恢復

mysqlbinlog --stop-position='end_log_pos' 二進制日誌文件 | mysql -u root -p

mysqlbinlog --start-position='end_log_pos' 二進制日誌文件 | mysql -u root -p

5.案例:MySQL增量恢復(丟失完全備份後)

(1)丟失完全備份之後的數據

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>delete from hiahia.user where user_name='hehe';
//模擬增量數據丟失

mysql>delete from hiahia.user where user_name='haha';

mysql> delete from hiahia.user where user_name='huohuo';

mysql>delete from hiahia.user where user_name='heihei';

mysql>select * from hiahia.user;                           //驗證數據情況

mysqladmin -u root -p flush-logs                  //生成新的二進制日誌

mysqlbinlog /Backup/mysql-bin.000005 | mysql -u root -p

//通過備份的增量二進制日誌文件恢復增量數據,如有多個增量日誌文件逐個恢復

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>select * from hiahia.user;                    //驗證數據情況

(2)丟失完整備份在內數據

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>drop table hiahia.user;                        //刪除user表,模擬表故障

mysql>select * from hiahia.user;                    //驗證數據情況

mysql>mysql -u root -p hiahia </Backup/hiahia-user-2018-03-21.sql
//通過備份表sql文件恢復表數據到hiahia庫下

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>select * from hiahia.user;                    //驗證數據情況,完整備份恢復

mysqladmin -u root -p flush-logs                  //生成新的二進制日誌

mysqlbinlog /Backup/mysql-bin.000005 | mysql -u root -p
//通過備份的增量二進制日誌文件恢復增量數據,如有多個增量日誌文件逐個恢復

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>select * from hiahia.user;                    //驗證數據情況

(3)基於時間點恢復

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>delete from hiahia.user where user_name='hehe';

//模擬增量數據丟失

mysql>delete from hiahia.user where user_name='haha';

mysql> delete from hiahia.user where user_name='huohuo';

mysql>delete from hiahia.user where user_name='heihei';

mysql>select * from hiahia.user;                    //驗證數據情況

mysqladmin -u root -p flush-logs                  //生成新的二進制日誌

mysqlbinlog /Backup/mysql-bin.000005
//通過查看二進制日誌確認恢復時間點,如該處爲"180321 19:58:40"

mysqlbinlog /Backup/mysql-bin.000005 --stop-datetime='2018-03-21 19:58:40' | mysql -u root -p
//只恢復'2018-03-21 19:58:40'之前數據

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>select * from hiahia.user;                    //驗證數據情況

mysqlbinlog /Backup/mysql-bin.000005
//通過查看二進制日誌確認恢復時間點,如該處爲從"180321 19:58:45"

mysqlbinlog /Backup/mysql-bin.000005 --start-datetime='2018-03-21 19:58:45' | mysql -u root -p

//只恢復'2018-03-21 19:58:45'之後數據

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>select * from hiahia.user;                    //驗證數據情況

注:"stop-datetime或start-datetime"不要相同時間點導入多次,會重複性導入

(4)基於位置恢復

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>delete from hiahia.user where user_name='hehe';
//模擬增量數據丟失

mysql>delete from hiahia.user where user_name='haha';

mysql> delete from hiahia.user where user_name='huohuo';

mysql>delete from hiahia.user where user_name='heihei';

mysql>select * from hiahia.user;                           //驗證數據情況

mysqladmin -u root -p flush-logs                         //生成新的二進制日誌

mysqlbinlog /Backup/mysql-bin.000005
//通過查看二進制日誌確認恢復pos,如該處爲從"577"

mysqlbinlog /Backup/mysql-bin.000005 --stop-position='577' | mysql -u root -p
//只恢復'577'之前數據

mysql -u root -p                                           //登錄MySQL,密碼爲123

mysql>select * from hiahia.user;                           //驗證數據情況

mysqlbinlog /Backup/mysql-bin.000005
//通過查看二進制日誌確認恢復時間點,如該處爲從"718"

mysqlbinlog /Backup/mysql-bin.000005 --start-position='718' | mysql -u root -p
//只恢復'718'之後數據

mysql -u root -p                                               //登錄MySQL,密碼爲123

mysql>select * from hiahia.user;                    //驗證數據情況

七、root密碼遺忘解決辦法

1.修改my.cnf配置文件

vim /etc/my.cnf
38 skip-grant-tables            //跳過密碼驗證

2.重啓服務並驗證

/etc/init.d/mysqld restart
mysql -u root
mysql> update mysql.user set Password=password(123456) where User='root';
//重置root密碼爲123456

3.開啓密碼驗證並重啓服務

vim /etc/my.cnf
38 #skip-grant-tables           //跳過密碼驗證
/etc/init.d/mysqld restart
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章