一,Mysql數據庫備份概述
1,數據庫備份的重要性
- 數據災難恢復:數據庫可能會因為各種原因出現故障,如硬件故障、軟件錯誤、誤操作、病毒攻擊、自然災害等。這些情況都可能導致數據丟失或損壞。如果有定期的備份,就可以在發生災難后將數據庫恢復到最近的一個正常狀態,最大限度地減少數據丟失和業務中斷的影響。
- 誤操作恢復:人為的誤操作是很常見的,例如誤刪除數據、錯誤的更新操作等。備份可以作為一種 “后悔藥”,方便及時將數據庫恢復到誤操作之前的狀態,避免因誤操作而造成的嚴重后果。
- 數據遷移與共享:在進行數據庫遷移到新的服務器或系統時,備份可以方便地將數據從舊環境遷移到新環境。此外,備份也可以用于在不同的系統或團隊之間共享數據,確保數據的一致性和完整性。
- 歷史數據存檔:隨著時間的推移,數據庫中的數據會不斷增加,一些歷史數據可能不再經常被訪問,但仍然需要保留以備查詢和分析。通過備份,可以將這些歷史數據存檔,減輕生產數據庫的存儲壓力,同時也便于在需要時快速恢復和查詢歷史數據。
2,數據庫備份類型
1,按備份內容分類
- 完全備份:對整個數據庫進行完整的備份,包括所有的數據、表結構、索引、存儲過程等數據庫對象。這種備份方式的優點是恢復時簡單快捷,只需將備份文件恢復到數據庫中即可,可一次性將數據庫恢復到備份時的狀態。缺點是備份時間長,占用存儲空間大。
- 差異備份:備份自上次完全備份以來發生變化的數據。恢復時,只需先恢復完全備份,再恢復最新的差異備份,恢復過程相對簡單。與增量備份相比,差異備份不依賴于上一次差異備份的結果,
- 增量備份:只備份自上次備份(可以是完全備份或增量備份)以來發生變化的數據。其優點是備份速度快,占用存儲空間小,可以更頻繁地進行備份,從而減少數據丟失的風險。
2,按備份數據庫的狀態分類
- 熱備份:也稱為在線備份,在數據庫正常運行、用戶可以正常訪問和操作數據庫的情況下進行備份。熱備份不會影響數據庫的正常使用,但實現起來相對復雜,需要數據庫管理系統提供相應的支持。
- 溫備份:在數據庫運行狀態下進行備份,但備份過程中會限制部分數據庫操作,如暫停一些非關鍵的寫入操作,以確保備份數據的一致性。
- 冷備份:也稱為離線備份,在數據庫停止運行的狀態下進行備份。這種方式簡單直接,能保證備份數據的一致性,因為在備份過程中沒有數據的寫入和修改。但冷備份期間數據庫無法使用,會導致業務中斷,
3,按備份數據庫的存儲位置分類
- 本地備份:將備份數據存儲在與數據庫服務器相同的本地存儲設備上,如本地硬盤、磁盤陣列等。本地備份的優點是備份和恢復速度快,因為數據傳輸距離短。缺點是如果本地存儲設備出現故障,
- 異地備份:將備份數據存儲在遠離數據庫服務器的其他地方,如通過網絡將備份數據傳輸到遠程的數據中心、云存儲或其他服務器上。異地備份可以有效防止本地災難(如火災、洪水、地震等)對備份數據的破壞,提高數據的安全性和可靠性。
3,常見的備份方法
- 物理冷備份:
物理冷備份時需要在數據庫處于關閉狀態下,能夠較好地保證數據庫的完整性。物理冷備份一般用于非核心業務,這類業務一般都允許中斷,物理冷備份的特點就是速度快,恢復時也是最為簡單的。通常通過直接打包數據庫文件夾(本章中的數據庫文件夾位于/usr/local/mysql/data)來實現備份。
- 使用第三方工具mysqldump工具
mysqldump 是客戶端常用邏輯備份程序,能夠產生一組被執行以后再現原始數據庫對象定義和表數據的SQL 語句。它可以轉儲一個到多個 MySQL 數據庫,對其進行備份或傳輸到遠程SQL 服務器。mysqldump 更為通用,因為它可以備份各種表。
- 使用mysqlhotcopy工具:
mysqlhotcopy
是一個 Perl 腳本,主要用于對 MyISAM 表進行快速備份。它通過復制表文件的方式來實現備份,在備份時會對表進行鎖定,以確保數據的一致性。語法:mysqlhotcopy [選項] 數據庫名 [備份目錄]
。如果不指定備份目錄,則默認將備份文件存儲在當前目錄下。
- 啟用二進制日志進行增量備份:
MySQL 支持增量備份,進行增量備份時必須啟用二進制日志。二進制日志文件為用戶 提供復制,對執行備份點后進行的數據庫更改所需的信息進行恢復。如果進行增量備份(包含自上次完全備份或增量備份以來發生的數據修改),需要刷新二進制日志。
- 通過第三方工具備份(如 Percona XtraBackup):
這是一款開源的、高性能的 MySQL 數據庫備份工具,主要用于 InnoDB 和 XtraDB 存儲引擎的熱備份。它通過復制數據文件和日志文件,并在備份過程中應用事務日志,來確保備份數據的一致性。
二,數據庫備份操作
1,物理備份與操作
- 使用完全備份來備份數據
mysql> create database db1; ##創建數據庫
Query OK, 1 row affected (0.01 sec)mysql> use db1;
Database changed
mysql> create table t1(user_name char(20),user_pass char(40)); ##創建表
Query OK, 0 rows affected (0.02 sec) mysql> insert into t1 values('zhangsan','123456'); ##準備要備份的數據
Query OK, 1 row affected (0.03 sec)mysql> insert into t1 values('lisi','123456');
Query OK, 1 row affected (0.01 sec)mysql> select * from t1;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 123456 |
| lisi | 123456 |
+-----------+-----------+
2 rows in set (0.00 sec)
- 創建用于存放備份數據的目錄
[root@bogon ~]# systemctl stop mysqld ##因為做的是冷備份所以說需要關閉mysql數據庫[root@bogon ~]# mkdir -p /opt/backup ##創建目錄用于存放備份的文件[root@bogon ~]# cd /usr/local/mysql/
[root@bogon mysql]# ls
bin data docs include lib LICENSE man README share support-files
[root@bogon mysql]# tar zcvf back.tar.gz data ##將數據庫文件data壓縮為back.tar.gz[root@bogon mysql]# mv back.tar.gz /opt/backup ##移動到backup目錄中
[root@bogon mysql]# ls !$
ls /opt/backup
back.tar.gz
-
驗證,模擬數據庫故障
[root@bogon data]# cd /usr/local/mysql/data
[root@bogon data]# lsauto.cnf ca.pem ibtmp1 performance_schemabinlog.000001 client-cert.pem '#innodb_redo' private_key.pembinlog.000002 client-key.pem '#innodb_temp' public_key.pembinlog.000003 error.log localhost.localdomain.pid server-cert.pembinlog.000004 '#ib_16384_0.dblwr' mysql server-key.pembinlog.index '#ib_16384_1.dblwr' mysql.ibd sysbogon.pid ib_buffer_pool mysql.sock undo_001ca-key.pem ibdata1 mysql.sock.lock undo_002
[root@bogon data]# rm -rf * ##將data目錄中的數據刪除,來模擬故障[root@bogon backup]# cd data
[root@bogon data]# mv * /usr/local/mysql/data/ ##將備份號data文件重新復制過去[root@bogon mysql]# systemctl start mysqld ##啟動mysql數據庫mysql> show databases; ##進入到數據庫查看數據
+--------------------+
| Database |
+--------------------+
| db1
2,mysqldump備份與恢復
語法:
mysqldump -u(指定用戶) -p(指定密碼) 庫名 [表名1] 表名2]? > /備份路徑/備份文件名
mysql> create database mysqldb; ##創建數據庫和表
Query OK, 1 row affected (0.01 sec)mysql> use mysqldb;
Database changed
mysql> create table usert1(user_name char(20),user_pass char(40)); ##在表里面添加數據
Query OK, 0 rows affected (0.02 sec)##將數據備份到/opt/backup中并重命名為mysqldb.sql
[root@bogon backup]# mysqldump -uroot -ppwd123 mysqldb usert1 > /opt/backup/mysqldb.sql
drop table usert1 ##備份完成后刪除usert1表[root@bogon backup]# mysql -uroot -ppwd123 mysqldb < mysqldb.sql ##將備份好的數據進行恢復##查看數據的恢復情況
mysql> show tables;
+-------------------+
| Tables_in_mysqldb |
+-------------------+
| usert1 |
+-------------------+
1 row in set (0.00 sec)mysql> desc usert1;
+-----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------+------+-----+---------+-------+
| user_name | char(20) | YES | | NULL | |
| user_pass | char(40) | YES | | NULL | |
+-----------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
- 基于二進制文件進行恢復
[root@bogon ~]# vim /etc/my.cnf ##在此文件中[mysqld]添加三行
log-bin=/usr/local/mysql/mysql-bin ##啟用二進制日志
binlog_format=MIXED ##定義二進制日志的記錄格式為混合模式
server-id=1 ##為mysql分配一個唯一的服務器標識符
[root@bogon ~]# systemctl restart mysqld ##重啟mysqld服務
[root@bogon /]# cd /usr/local/mysql/ ##/usr/local/mysql/中會生成一個mysql-bin.000001的二進制文件
[root@bogon mysql]# lsmysql-bin.000001 [root@bogon mysql]# mysqlbinlog mysql-bin.000001 ##使用此命令查看文件里面會又之前mysql數據庫的命令
create database db1
create table t1(user_name char(20),user_pass char(40))mysql> drop database db1; ##刪除db1數據庫
Query OK, 1 row affected (0.01 sec) ##使用命令恢復db1數據庫
[root@bogon mysql]# mysqlbinlog --no-defaults mysql-bin.000001 | mysql -uroot -ppwd123mysqladmin -uroot -ppwd123 flush-logs ##刷新日志會生成新的日志文件mysql-bin.000002
- 基于二進制文件位置進行恢復
mysql> create database aaa; ##創建數據庫
Query OK, 1 row affected (0.00 sec)mysql> use aaa;
Database changed
mysql> create table bbb(user_name char(20),user_pass char(40));
Query OK, 0 rows affected (0.05 sec)##往表里面添加數據
mysql> insert into bbb values('zhangsan','123'),('lisi','456'),('wangwu','789');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0mysql> select * from bbb;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 123 |
| lisi | 456 |
| wangwu | 789 |
+-----------+-----------+
3 rows in set (0.00 sec)mysql> insert into bbb values('ccc','000'); ##單獨插入一個用戶方便驗證
Query OK, 1 row affected (0.00 sec)##刷新日志
[root@bogon mysql]# mysqladmin -uroot -ppwd123 flush-logs
BEGIN ##開始位置
/*!*/;
# at 1644
#250509 8:36:33 server id 1 end_log_pos 1754 CRC32 0x1919625c Query thread_i
SET TIMESTAMP=1746750993/*!*/;
insert into bbb values('ccc','000')
/*!*/;
# at 1754
#250509 8:36:33 server id 1 end_log_pos 1785 CRC32 0xb5f69b37 Xid = 74
COMMIT/*!*/; ##結束位置Database changed
mysql> select * from bbb;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 123 |
| lisi | 456 |
| wangwu | 789 |
| ccc | 000 |
+-----------+-----------+
4 rows in set (0.00 sec)mysql> delete from bbb where user_name="ccc"; ##刪除ccc用戶
Query OK, 1 row affected (0.00 sec)mysql> select * from bbb;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 123 |
| lisi | 456 |
| wangwu | 789 |
+-----------+-----------+
3 rows in set (0.00 sec)
?驗證
##恢復指定位置的內容
[root@bogon mysql]# mysqlbinlog --no-defaults --start-position='1644' --stop-position='1754' mysql-bin.000002 | mysql -uroot -ppwd123##查看恢復情況
mysql> select * from aaa.bbb;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 123 |
| lisi | 456 |
| wangwu | 789 |
| ccc | 000 |
+-----------+-----------+
4 rows in set (0.00 sec)
- 基于二進制文件時間進行恢復
mysql> insert into bbb values('ddd','999');
Query OK, 1 row affected (0.00 sec)mysql> select * from aaa.bbb;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 123 |
| lisi | 456 |
| wangwu | 789 |
| ccc | 000 |
| ddd | 999 |
+-----------+-----------+
5 rows in set (0.00 sec)BEGIN
/*!*/;
# at 929
#250509 8:47:58 server id 1 end_log_pos 1039 CRC32 0xa963fcd4 Query thread_id=21 exec_time=0 error_code=0
SET TIMESTAMP=1746751678/*!*/;
insert into bbb values('ddd','999')
/*!*/;
# at 1039
#250509 8:47:58 server id 1 end_log_pos 1070 CRC32 0xe7b5c0fc Xid = 126
COMMIT/*!*/;
驗證?
mysql> select * from aaa.bbb;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 123 |
| lisi | 456 |
| wangwu | 789 |
| ccc | 000 |
| ddd | 999 |
+-----------+-----------+
5 rows in set (0.00 sec)mysql> delete from bbb where user_name="ddd"; ##刪除ddd用戶
Query OK, 1 row affected (0.01 sec)mysql> select * from aaa.bbb;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 123 |
| lisi | 456 |
| wangwu | 789 |
| ccc | 000 |
+-----------+-----------+
4 rows in set (0.00 sec)##基于時間恢復
[root@bogon mysql]# mysqlbinlog --no-defaults --start-datetime='2025-05-09 8:47:58' --stop-datetime='2025-05-09 8:47:58' mysql-bin.000003 | mysql -uroot -ppwd123mysql> select * from aaa.bbb;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 123 |
| lisi | 456 |
| wangwu | 789 |
| ccc | 000 |
| ddd | 999 |
+-----------+-----------+
5 rows in set (0.00 sec)