1. 備份和恢復的類型
(1) 物理備份與邏輯備份
物理備份
物理備份是把MySQL數據庫軟件的數據存儲目錄復制並且保存到安全的存儲位置,以防數據庫出現啟動故障后能夠快速恢復,一般把數據庫存儲的目錄進行壓縮備份存儲,生成*.tar.gz文件。如果數據庫存儲的目錄不小心被刪除了,這時就可以把備份的數據文件重新解壓拷貝到數據庫存儲目錄下,進行重新啟動。
物理備份具有以下特點:
-
備份包含完全的數據存儲目錄文件,就是僅僅復制了MySQL所有的文件;
-
物理備份比邏輯備份快,因為它僅僅是文件復制而沒有相關的轉換;
-
備份文件比邏輯備份更緊湊,因為可以壓縮;
-
對於備份速度、數據文件重要性方面,比較適合使用物理備份;
-
備份可以包括日志文件和配置文件;
-
內存中的表數據可能無法備份(企業版可以備份);
-
備份只兼容同一機器或相似機器;
-
備份可以在
shutdown
狀態下進行,也可以在running
狀態下(企業版),不過要確保服務器沒有數據寫入數據文件,企業版備份會自動加鎖; -
物理備份的工具有
mysqlbackup
(企業版),或者使用系統的命令,如cp
,scp
,tar
,rsync
; -
對於使用
mysqlbackup
熱備份的文件,同樣使用mysqlbackup
進行還原;對於在系統層面復制文件的備份,在系統中復制粘貼還原備份文件即可。
另外,如果需要查看MySQL存儲文件,可以在MySQL的終端下執行:
mysql> show global variables like "%datadir%";
邏輯備份
邏輯備份是備份數據庫的邏輯信息,如創建的數據庫、表及其表內的內容。邏輯備份可以把數據轉移到另外的物理機上,也可以修改表的數據或結構,一般生成一個*.sql文件。
邏輯備份具有以下特點:
- 備份是通過查詢MySQL服務器獲得數據庫的結構和內容信息;
- 備份比物理備份慢,因為需要訪問數據庫信息並且轉換成邏輯結構;
- 備份不包括日志或配置文件;
- 備份的內容可以轉移到任意物理機上,具有高度的可移植性;
- 備份執行時,服務器必須是
running
狀態; - 邏輯備份工具有
mysqldump
和SELECT ... INTO OUTFILE
,支持任意存儲引擎,甚至內存中的表數據; - 邏輯備份使用
mysqldump
對應的恢復使用mysql
客戶端,使用SELECT ... INTO OUTFILE
對應的恢復使用LOAD DATA
語法或mysqlimport
客戶端。
(2) 熱備份與冷備份
熱備份方式是在MySQL服務器正在運行中,所以客戶端可以獲得服務器的數據信息;冷備份是在MySQL服務器停止狀態下進行。還有一種方式是暖備份,暖備份是數據庫雖然在運行中,但是數據訪問被加鎖了,無法進行修改。
熱備份
熱備份具有以下特點:
-
備份時,客戶端可以訪問數據並且執行相應的操作;
-
強制加上合適的鎖防止數據修改導致備份的不一致,MySQL Enterprise Backup會自動地加鎖
冷備份
冷備份具有以下特點:
- 在備份時,客戶端無法訪問數據庫。由於數據庫需要關閉,一般情況下,在從節點的數據庫下進行,因為是從節點,所以不影響主數據庫;
- 備份過程簡單快速
(3) 本地備份和遠程備份
本地備份是備份客戶端操作執行在同一MySQL服務端運行的主機上,而遠程備份是備份客戶端操作執行不在同一MySQL服務端運行的主機上。某些備份方式,即使輸出目的地只能是服務端主機,也可以使用遠程方式進行。
mysqldump
可以使用本地和遠程方式。對於輸出為SQL
語句方式(CREATE
和INSERT
語句)的備份,不管是遠程備份還是本地備份,都可以在客戶端上輸出。對於輸出為分隔符方式(使用了--tab
選項)的備份,輸出目錄只能在服務端;SELECT ... INTO OUTFILE
支持遠程和本地方式,不過輸出目錄只能在服務端;- 物理備份方式只能執行在本地的服務端主機。
(4) 全量備份和增量備份
全量備份包括MySQL服務器某一時間點上的所有的數據;增量備份由經過某一段時間改變的數據組成。增量備份通過使用開啟了日志記錄生成二進制日志文件進行備份。
(5) 完全恢復與基於時間點的不完全恢復
完全恢復是使用全量備份的文件恢復所有的數據,完全恢復后也可以使用日志文件進行不完全恢復,把數據庫恢復到某一時間點的狀態。基於時間點的不完全恢復是恢復到數據庫的某一個時間狀態,它基於二進制日志文件並且通常先進行完全恢復后,再進行基於時間點的不完全恢復,根據時間點得到了重做的操作,把服務器恢復的期望的狀態。
2. 備份的方法
(1)使用mysqlbackup
的熱備份
mysqlbackup
是企業版備份工具,可以進行熱備份備份整個數據庫或表的物理文件,屬於物理備份方式。除此,工具還有壓縮備份功能。使用InnoDB
引擎的表格是熱備份方式,而其他存儲引擎的表格是使用暖備份方式。
(2)使用mysqldump
的備份
mysqldump
是邏輯備份工具,可以備份所有類型的表格。對於使用InnoDB
存儲引擎的表格,使用--single-transaction
選項可以在備份過程中不鎖表格。
(3)通過備份表格文件的備份
對於那些存儲引擎的表格擁有自己的文件的,比如MyISAM
存儲引擎的表格,可以簡單地備份復制文件(*.frm
, *.MYD
,*.MYI
)。為了保證備份的數據一致性,最好停止服務器或刷新表格並加鎖。
mysql>flush tables tabble_list with read load;
加上讀取鎖,可以在備份過程中使客戶端可以繼續查詢表格;刷新表格是確保備份時所有的數據都被寫入到了數據文件。
如果服務器沒有在更新數據,備份可以是復制所有的表格文件,但注意,對於InnoDB
存儲引擎的表格就不行了。InnoDB
存儲引擎的表格,即使服務器沒有在更新數據,也可能在緩存中有數據沒有寫入到數據文件。
(4)分隔符文本文件形式的備份
如果想創建包含表格數據的文本文件,可以使用select * into outfile 'file_name' from table_name;
語句,它會在數據庫的存儲目錄下生成file_name
的文本文件,並且要求file_name
文件不能已存在。
(5)通過二進制日志的增量備份
MySQL支持增量備份,是使用二進制日志文件實現的。二進制日志文件提供所有你需要重新讓數據庫執行的操作信息。如果要使用增量備份,在進行完全備份后,使用flush log
操作對當前的日志進行rotate(歸檔),然后對二進制日志文件進行備份,當需要恢復時,進行完全恢復操作,再使用備份的日志文件進行不完全恢復。
(6)通過副本節點的備份
如果數據庫的設計是主從結構,主數據庫的數據會同步到從數據庫,那么就可以通過備份從數據庫來達到備份的目的。如果通過副本節點進行備份,不管哪種備份方法,都要把主數據庫的信息和傳遞日志信息配置進行備份,這些信息可以方便繼續恢復副本節點。(可能有錯)
(7)使用系統快照的備份
如果使用的文件系統支持快照,也可以進行物理文件的快照備份。如vxfs
、LVM
和ZFS
.
3. 備份與恢復的使用
物理備份的冷備份只是把MySQL數據庫的存儲目錄所有文件進行打包壓縮以防數據文件損壞而無法使用數據庫,當然這個備份也包括了寫入了數據庫數據文件的數據信息。物理備份的熱備份mysqlbackup
可以在不關閉數據庫的狀態下備份數據庫的數據文件,不過mysqlbackup
是企業版的功能。這里是演示邏輯備份和恢復。
(1) mysqldump
1)備份:
默認情況下,mysqldump
會把數據信息轉換成SQL語句作為標准輸入,並且可以使用Linux的輸出重定向符>
存儲到文件中:
shell>mysqldump [arguments] > file_name
假設數據庫有root
用戶和player
的賬號,且密碼都為10010
,且數據庫上有兩個自建數據庫schema,分別為neteasemusicplayer
和onlineexam
,其中player
用戶只有neteasemusicplayer
這個schema的訪問權,root用戶擁有兩個schema的訪問權。下面演示備份:
shell>mysqldump -uplayer -p10010 --all-databases > player_dump.sql #備份player用戶所有的數據庫schema,存儲到player_dump.sql文件,這里測試root用戶備份所有數據庫失敗,root用戶有數據庫系統的數據庫訪問權,但因某些未知原因,備份報錯
shell>mysqldump -uroot -p10010 --databases neteasemusicplayer onlineexam > root_dump.sql #備份root用戶的neteasemusicplayer和onlineexam數據庫schema,存儲到root_dump.sql文件
shell>mysqldump -uroot -p10010 onlineexam > onlineexam.sql #這種備份方式得到的*.sql文件沒有`create database xxx;user xxx;`,並且只能指定一個數據庫scheme
第一種方式--all-databases
會把當前用戶下所有的數據庫schema進行備份;第二種方式--databases
可以制定當前用戶的某一或多個數據庫schema;第三種方式單單指定了數據庫schema,它得到的文件就沒有create database
和use
部分,並且這種方式只能指定一個數據庫schema,這樣可以把數據導入到不同數據庫schema中。
2)恢復:
- 備份文件有
create database
和use
語句的恢復
對於使用mysqldump
導出的SQL語句文件,可以使用mysql
客戶端進行恢復,如果備份時使用了all-databases
或--databases
選項,它包含了create database
和use
語句,所以沒必要去指定默認的導入數據庫schema了,直接使用輸入重定向<
傳遞給mysql
客戶端即可恢復:
shell>mysql -uroot -p10010 < player_dump.sql #恢復player用戶備份的所有數據庫schema,這里使用root用戶,我的player用戶無創建數據庫權限
或者在mysql下可以使用source
命令恢復:
shell>mysql -uroot -p10010 #回車進入mysql終端,這里使用root用戶,我的player用戶無創建數據庫權限
mysql>source player_dump.sql; /*恢復player用戶備份的所有數據庫schema*/
- 備份文件無
create database
和use
語句的恢復
如果是上面第三種方式的備份產出的SQL語句,即沒有create database
和use
語句的,如果有需要的話,可以使用mysqladmin
先建立數據庫schedule:
shell>mysqladmin -uroot -p10010 create onlineexam
shell>mysql -uroot -p10010 onlineexam < onlineexam.sql
或者在mysql下先創建數據庫,然后使用source
命令恢復:
shell>mysql -uroot -p10010 #使用root用戶登錄MySQL終端控制台
mysql>create database if not exists onlineexam; /*如果數據庫不存在就創建數據庫scheme*/
mysql>use onlineexam; /*使用onlineexam數據庫scheme*/
mysql>source onlineexam.sql; /*恢復數據庫onlineexam*/
(2) mysqlbinlog
mysqlbinlog
是基於日志文件的不完全恢復,可以把數據庫恢復到某一個時間點或某一個事件點上,對於誤操作恢復很有用。下面演示錯誤刪除onlineexam
數據庫schema的questions
表的不完全恢復。
操作步驟:
1)備份onlineexam
schema;
2)插入了數據到users
表格,但不小心刪除了questions
表;
3)恢復onlineexam
schema,這時的users
表沒有插入的數據;
4)查看日志存儲文件並顯示詳細的記錄,獲取時間點或事件點;
5)使用基於時間點或基於位置的恢復到未錯誤刪除questions
表但是插入了user
表數據的狀態
1)備份
shell>mysqldump -uroot -p10010 onlineexam > onlineexam.sql
2)插入數據到users
表但錯誤刪除了questions
表
shell>mysql -uroot -p10010
mysql>insert into users values('201615210416','10010');
mysql>insert into users values('201615210417','10010');
mysql>drop table questions;
3)使用備份的文件恢復onlineexam
shell>mysql -uroot -p10010 onlineexam < onlineexam.sql
4)查看日志存儲文件並顯示詳細的記錄,獲取時間點或事件點
mysql>show master status; /*查看當前的日志文件位置*/
- 獲取時間點
shell>mysqlbinlog /var/lib/mysql/binlog.000001 > binlog #轉換成文本查看
shell>vim binlog #查看輸出文件,並且搜索'DROP TABLE'
- 獲取事件點
mysql>show binlog events in 'binlog.000001';
5)恢復到某一狀態
- 基於時間點恢復
因為上面查看得到的時間點是09:02:01
執行了錯誤刪除questions
表操作,使用mysqlbinlog --stop-datetime
恢復到這個時間點上,但這個操作是未被執行的,所以執行恢復:
shell>mysqlbinlog --stop-datetime="2020-06-09 09:02:01" /var/lib/mysql/binlog.000001 | mysql -uroot -p10010
- 基於事件點恢復
因為上面查看得到的事件點是856
開始執行誤刪除questions
表操作,執行成功后事件點為1002
,使用mysqlbinlog --stop-position
執行恢復時,--stop-position
應該填寫856
:
shell>mysqlbinlog --stop-position="856" /var/lib/mysql/binlog.000001 | mysql -uroot -p10010
通過基於時間點或基於事件點方式都可以把數據庫恢復到某一個期望狀態下,如下所示恢復結果:
關於mysqlbinlog
的參數說明:
參數 | 說明 |
---|---|
--start-datetime=”datetime“ | 從二進制日志的時間戳等於或晚於datetime的第一個事件開始 |
--stop-datetime=”datetime“ | 從二進制日志的時間戳等於或早於datetime的第一個事件結束 |
--start-position=N | 從二進制日志的事件點等於或大於N的第一個事件開始 |
--stop-position | 從二進制日志的事件點等於或小於datetime參數的第一個事件結束 |
(4) 總結
本篇博客的參考文檔是MySQL 5.7
的官方使用手冊,知識點較多的是根據文檔進行翻譯,也加入了一些自己的理解,第三部分是自己的實踐,也有許多的坑。官方文檔傳送門