# mysql備份恢復(mysqldump備份 mysqlbinlog恢復) ## 一、備份的分類 1. 物理備份 物理備份:對資料庫操作系統的物理文件(如數據文件、日誌文件等) - 冷備份(離線備份) :是在關閉資料庫的時候進行的 - 熱備份(聯機備份) :資料庫處於運行狀態,依賴於資料庫的日 ...
mysql備份恢復(mysqldump備份 mysqlbinlog恢復)
一、備份的分類
-
物理備份
物理備份:對資料庫操作系統的物理文件(如數據文件、日誌文件等)
- 冷備份(離線備份) :是在關閉資料庫的時候進行的
- 熱備份(聯機備份) :資料庫處於運行狀態,依賴於資料庫的日誌文件
- 溫備份:資料庫鎖定表格(不可寫入但可讀)的狀態下進行備份操作
-
邏輯備份
邏輯備份:對資料庫邏輯組件(如: 表等資料庫對象)的備份
從資料庫的備份策略角度,備份可分為
- 完全備份:每次對數據進行完整的備份
- 差異備份:差異備份是指在一次全備份後到進行差異備份的這段時間內,對那些增加或者修改文件的備份。在進行恢復時,我們只需對第一次全備份和最後一次差異備份進行恢復。
- 增量備份:增量備份是指在一次全備份或上一次增量備份後,以後每次的備份只需備份與前一次相比增加和者被修改的文件。這就意味著,第一次增量備份的對象是進行全備後所產生的增加和修改的文件;第二次增量備份的對象是進行第一次增量備份後所產生的增加和修改的文件,如此類推。
二、常見的備份方法
- 物理冷備
- 備份時資料庫處於關閉狀態,直接打包資料庫文件
- 備份速度快,恢復時也是最簡單的
- 直接複製資料庫文件,適用於大型資料庫環境,不受存儲引擎的限制,但不能恢復到不同的MySQL版本。
- 專用備份工具mydump或mysqlhotcopy
- mysqldump常用的邏輯備份工具
- mysqlhotcopy僅擁有備份MyISAM和ARCHIVE表
- 啟用二進位日誌進行增量備份
- 進行增量備份,需要刷新_二進位日誌
- 第三方工具備份
- 免費的MySQl熱備份軟體Percona XtraBackup
三、mysql完全備份
-
定義
完全備份是對整個資料庫的備份、資料庫結構和文件結構的備份
完全備份保存的是備份完成時刻的資料庫
完全備份是增量備份的基礎 -
優點
安全性高
備份與恢復操作簡單方便 -
缺點
數據存在大量的重覆
占用大量的備份空間,空間利用率低
備份與恢復時間長
四、資料庫完全備份分類
4.1 物理備份/冷備份-tar (備份與恢復)
關閉MySQL資料庫
使用tar命令直接打包資料庫文件夾
直接替換現有MySQL目錄即可
- 準備好資料庫(當然可以自己準備資料庫,主要演示對數據的增刪改)
進入mysql 創建kings資料庫
create database kings;
use kings;
創建tanks表
tanks | CREATE TABLE `tanks` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`skills` varchar(100) NOT NULL,
`price` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
插入數據
insert into tanks(name,skills,price) values('豬八戒','像一個肉球一樣彈',12888);
select * from tanks;
+----+-----------+--------------------------+-------+
| id | name | skills | price |
+----+-----------+--------------------------+-------+
| 2 | 豬八戒 | 像一個肉球一樣彈 | 12888 |
+----+-----------+--------------------------+-------+
1 row in set (0.00 sec)
- 先退出mysql,關閉資料庫服務,再打包備份
tar zcf /backup/mysql_all-$(date +%F).tar.gz /usr/local/mysql/data/
cd /backup/
ll
總用量 760
-rw-r--r-- 1 root root 776114 8月 7 01:21 mysql_all-2023-08-07.tar.gz
- 將原來的數據移走到備份文件夾中,解壓剛纔備份的tar包到/restore目錄下,再移動到mysql服務的文件夾中
mkdir /bak
將現有mysql的data 移走
mv /usr/local/mysql/data/ /bak
mkdir /restore
將備份文件解壓到restore
tar -zxf /backup/mysql_all-2023-08-07.tar.gz -C /restore/
將解壓的備份文件data 移動到mysql中
mv restore/usr/local/mysql/data/ /usr/local/mysql
- 重啟mysql服務,登錄mysql,查看數據是否恢復
mysql>use kings;
mysql> show tables;
+-----------------+
| Tables_in_kings |
+-----------------+
| tanks |
+-----------------+
1 row in set (0.00 sec)
mysql> select * from tanks;
+----+-----------+--------------------------+-------+
| id | name | skills | price |
+----+-----------+--------------------------+-------+
| 2 | 豬八戒 | 像一個肉球一樣彈 | 12888 |
+----+-----------+--------------------------+-------+
1 row in set (0.00 sec)
4.2 邏輯備份/熱備份-mysqldump備份
MySQL自帶的備份工具,可方便實現對MySQL的備份
可以將指定的庫、表導出為SQL腳本
mysqldump命令備份過程,實際上是把資料庫、表,以SQL語句的形式,輸出為文件的備份過程,這種方式稱之為邏輯備份。
但是這種方式效率並不高,以SQL導出,在海量數據下,例如幾十G的場景,備份、恢復的時間都會過長。
備份的是建表、建庫、插入等操作所執行SQL語句(DDL DML DCL),適用於中小型資料庫。
mysqldump命令用於備份MySQL資料庫
語法:
mysqldump -u username -p password [option] database_name table_name > backup_file.sql
常用參數:
--all-databases:備份所有資料庫。
--single-transaction:在備份期間使用單個事務,確保數據的一致性(不停機備份)。
--master-data:為1時在文件中生成change master語句,為2時也添加change master並註釋。
--delete-master-logs:在master上備份後刪除其二進位日誌。
--flush-logs:切斷日誌,做一次日誌輪轉。
--skip-lock-tables:備份時跳過鎖定表,適用於大型資料庫。
--no-create-db:備份時不包含創建資料庫語句。
--no-create-info:備份時不包含創建表的語句。
--no-data:備份時不包含數據。
--add-drop-database:備份時在創建資料庫之前添加DROP DATABASE語句。
--add-drop-table:備份時在創建表之前添加DROP TABLE語句。
--result-file=file_name:將備份結果輸出到指定文件中。
--compress:在備份過程中使用壓縮。
常用命令:
mysqldump -u root -p --all-databses > all-data-$(date +%F).sql ###備份所有資料庫
mysqldump -u root -p -databases auth mysql > auth-mysql.sql ###備份auth和mysql庫
mysqldump -u root -p auth > auth-$(data +%F).sql ###備份auth資料庫
mysqldump -u root -p mysql user > mysql-user-$(date +%F).sql ###備份mysql的user表
mysqldump -u root -p -d mysql user > /tmp/desc-mysql-user.sql ###備份mysql庫user表的結構
mysqldump -u root -p --all-databases --single-transaction --master-data=2 --flush-logs >/backup/`date +%F-%H`mysql_all.sql ###備份所有庫,添加change master並註釋,並切斷日誌
對單個表備份
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| kings |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
[root@localhost ~]# mysqldump -u root -p kings > /backup/kings-$(date +%F).sql
Enter password:
[root@localhost ~]# cd /backup/
[root@localhost backup]# ls
kings-2023-08-07.sql mysql_all-2023-08-07.tar.gz
對所有庫進行備份
[root@localhost ~]# mysqldump -u root -p --all-databases > /backup/all-$(date +%F).sql
Enter password:
[root@localhost ~]# cd /backup/
[root@localhost backup]# ls
all-2023-08-07.sql kings-2023-08-07.sql mysql_all-2023-08-07.tar.gz
備份表
[root@localhost backup]# mysqldump -u root -p kings tanks > /backup/kings.tanks-$(date +%F).sql
[root@localhost backup]# ls
all-2023-08-07.sql kings-2023-08-07.sql kings.tanks-2023-08-07.sql mysql_all-2023-08-07.tar.gz
4.2.1使用source命令恢複數據庫
source命令【作用於mysql模式下】
使用source恢複數據庫
模擬刪除表 恢復表
mysql> drop table tanks;
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
Empty set (0.00 sec)
mysql> source /backup/kings.tanks-2023-08-07.sql;
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
...
mysql> show tables;
+-----------------+
| Tables_in_kings |
+-----------------+
| tanks |
+-----------------+
1 row in set (0.00 sec)
4.2.2使用mysql命令恢複數據庫
mysql命令【作用於於linux模式下】
模擬刪表 恢復
mysql> drop table tanks;
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
Empty set (0.00 sec)
kings為資料庫名字 恢復導入表需要指定資料庫!
[root@localhost ~]# mysql -uroot -p kings < /backup/kings.tanks-2023-08-07.sql
Enter password:
mysql> show tables;
+-----------------+
| Tables_in_kings |
+-----------------+
| tanks |
+-----------------+
1 row in set (0.00 sec)
五、二進位日誌備份、恢復
mysqlbinlog工具來讀取和分析binlog文件
語法:
mysqlbinlog [options] logfile1 logfile2
常用參數:
--database=name,僅顯示指定資料庫的轉儲內容。
--short-form,使用簡單格式。
--start-datetime=name,轉儲日誌的起始時間。
--stop-datetime=name,轉儲日誌的截止時間。
--start-position=#,轉儲日誌的起始位置。
--stop-position=#,轉儲日誌的截止位置。
--no-defaults:指定不載入或使用預設配置文件,以確保按照命令行參數指定的配置選項進行操作。
--base64-output=decode-rows:將讀取的二進位數據解碼為可讀格式,即將Base64編碼的內容解碼為原始數據。
-v:輸出詳細信息,包括讀取的日誌事件和相關數據。
常用命令:
查看日誌
mysqlbinlog --no-defaults --base64-output=decode-rows -v
恢複數據
mysqlbinlog --stop-position=xxx [mysql-bin.0000xx] | mysql -uroot -p
mysqlbinlog --start-position=xxx --stop-position=xxx [mysql-bin.0000xx] | mysql -uroot -p
mysqlbinlog --start-datetime=xxx --stop-datetime=xxx [mysql-bin.0000xx] | mysql -uroot -p
5.1基於position(位置點)備份
1.開啟mysql伺服器的二進位日誌功能
[root@localhost ~]# tail -15 /etc/my.cnf
[mysqld]
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
socket = /usr/local/mysql/mysql.sock
port = 3306
pid-file = /usr/local/mysql/mysql.pid
user = mysql
skip-name-resolve
server-id = 1 // 設置伺服器標識
log-bin = /usr/local/mysql/mysql-bin //開啟二進位功能
查看日誌文件
[root@localhost ~]# ll /opt/data/
-rw-r-----. 1 mysql mysql 154 2月 22 16:37 mysql_bin.000001
-rw-r-----. 1 mysql mysql 19 2月 22 16:37 mysql_bin.index
2.對資料庫進行完全備份
mysqldump -uroot -p --single-transation --master-data=2 --flush-logs --all-databases --delete-master-logs > /backup/all-`date +%F-%H`.sql
可以看到all-2023-08-07-16.sql已經創建
[root@localhost backup]# ls
all-2023-08-07-16.sql kings-2023-08-07.sql mysql_all-2023-08-07.tar.gz
all-2023-08-07.sql kings.tanks-2023-08-07.sql
3.在數據資料庫中增加類容
mysql> select * from tanks;
+----+-----------+--------------------------+-------+
| id | name | skills | price |
+----+-----------+--------------------------+-------+
| 2 | 豬八戒 | 像一個肉球一樣彈 | 12888 |
+----+-----------+--------------------------+-------+
1 row in set (0.00 sec)
mysql> insert into tanks(name,skills,price) values('鐘馗','鉤子英雄',12888);
Query OK, 1 row affected (0.01 sec)
mysql> select * from tanks;
+----+-----------+--------------------------+-------+
| id | name | skills | price |
+----+-----------+--------------------------+-------+
| 2 | 豬八戒 | 像一個肉球一樣彈 | 12888 |
| 3 | 鐘馗 | 鉤子英雄 | 12888 |
+----+-----------+--------------------------+-------+
2 rows in set (0.00 sec)
4.模擬刪庫
mysql> drop database kings;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
5.刷新二進位文件
[root@localhost mysql]# mysqladmin -uroot -p flush-logs
[root@localhost mysql]# ls /usr/local/mysql/
mysql-bin.000002 mysql-bin.000003 ...
6.恢復完全備份
查看tanks表內容,可以發現備份之後修改的內容丟失
[root@localhost mysql]# mysql -uroot -p < /backup/all-2023-08-07-16.sql
Enter password:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| kings |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql> use kings;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------+
| Tables_in_kings |
+-----------------+
| tanks |
+-----------------+
1 row in set (0.00 sec)
mysql> select * from tanks;
+----+-----------+--------------------------+-------+
| id | name | skills | price |
+----+-----------+--------------------------+-------+
| 2 | 豬八戒 | 像一個肉球一樣彈 | 12888 |
+----+-----------+--------------------------+-------+
1 row in set (0.00 sec)
7.查看binlog 日誌,發現414為刪庫前,所以恢復到414
mysql> show binlog events in 'mysql-bin.000002'\G
*************************** 4. row ***************************
Log_name: mysql-bin.000002
Pos: 233
Event_type: Query
Server_id: 1
End_log_pos: 383
Info: use `kings`; insert into tanks(name,skills,price) values('鐘馗','鉤子英雄',12888)
*************************** 5. row ***************************
Log_name: mysql-bin.000002
Pos: 383
Event_type: Xid
Server_id: 1
End_log_pos: 414
Info: COMMIT /* xid=965 */
*************************** 6. row ***************************
Log_name: mysql-bin.000002
Pos: 414
Event_type: Query
Server_id: 1
End_log_pos: 509
Info: drop database kings
恢復到刪庫前
退出mysql 執行mysqlbinlog --stop-position=
[root@localhost ~]# mysqlbinlog --stop-position=414 /usr/local/mysql/mysql-bin.000003 | mysql -uroot -p
Enter password:
進入mysql 查看tanks表
mysql> select * from tanks;
+----+-----------+--------------------------+-------+
| id | name | skills | price |
+----+-----------+--------------------------+-------+
| 2 | 豬八戒 | 像一個肉球一樣彈 | 12888 |
| 3 | 鐘馗 | 鉤子英雄 | 12888 |
+----+-----------+--------------------------+-------+
2 rows in set (0.00 sec)
同理也可以恢復到插入'id=3'語句之前
對二進位日誌查詢還可以用
mysql> show binlog events in 'mysql-bin.000002';
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------------------+
| mysql-bin.000023 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.40-log, Binlog ver: 4 |
| mysql-bin.000023 | 120 | Query | 1 | 201 | BEGIN |
| mysql-bin.000023 | 201 | Intvar | 1 | 233 | INSERT_ID=3 |
| mysql-bin.000023 | 233 | Query | 1 | 383 | use `kings`; insert into tanks(name,skills,price) values('鐘馗','鉤子英雄',12888) |
| mysql-bin.000023 | 383 | Xid | 1 | 414 | COMMIT /* xid=965 */ |
| mysql-bin.000023 | 414 | Query | 1 | 509 | drop database kings |
| mysql-bin.000023 | 509 | Rotate | 1 | 556 | mysql-bin.000024;pos=4 |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------------------+
7 rows in set (0.00 sec)
5.2基於datetime(時間點)備份
1.刪庫 (之前添加的id=3 數據 這裡不進行修改表了)
mysql> select * from tanks;
+----+-----------+--------------------------+-------+
| id | name | skills | price |
+----+-----------+--------------------------+-------+
| 2 | 豬八戒 | 像一個肉球一樣彈 | 12888 |
| 3 | 鐘馗 | 鉤子英雄 | 12888 |
+----+-----------+--------------------------+-------+
2 rows in set (0.01 sec)
Database changed
mysql> drop database kings;
Query OK, 1 row affected (0.00 sec)
2.恢復完全備份 (因為之前有備份過就不需要進行mysqldump備份了,直接使用備份文件完全恢復就行)
mysql -uroot -p < /backup/all-2023-08-07-16.sql
3.查看表 此時已經恢復到了完全備份的數據狀態
mysql> select * from tanks;
+----+-----------+--------------------------+-------+
| id | name | skills | price |
+----+-----------+--------------------------+-------+
| 2 | 豬八戒 | 像一個肉球一樣彈 | 12888 |
+----+-----------+--------------------------+-------+
1 row in set (0.01 sec)
4.使用mysqlbinlog查詢時間點
[root@localhost data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000002
找到有關的信息
# at 233
#230807 17:01:37 server id 1 end_log_pos 233 CRC32 0xf9822b3a Intvar
SET INSERT_ID=3/*!*/;
#230807 17:01:37 server id 1 end_log_pos 383 CRC32 0xc6524022 Query thread_id=9 exec_time=0 error_code=0
use `kings`/*!*/;
SET TIMESTAMP=1691398897/*!*/;
insert into tanks(name,skills,price) values('鐘馗','鉤子英雄',12888)
/*!*/;
# at 383
#230807 17:01:37 server id 1 end_log_pos 414 CRC32 0x090e26df Xid = 965
COMMIT/*!*/;
# at 414
#230807 17:02:35 server id 1 end_log_pos 509 CRC32 0xd7c5718b Query thread_id=9 exec_time=0 error_code=0
SET TIMESTAMP=1691398955/*!*/;
drop database kings
/*!*/;
5.使用mysqlbinlog時間點恢復
[root@localhost 3306]# mysqlbinlog --no-defaults --start-datetime='2023-08-07 17:01:37' --stop-datetime='2023-08-07 17:02:35' /usr/local/mysql/mysql-bin.000023 | mysql -uroot -p
mysql> select * from tanks;
+----+-----------+--------------------------+-------+
| id | name | skills | price |
+----+-----------+--------------------------+-------+
| 2 | 豬八戒 | 像一個肉球一樣彈 | 12888 |
| 3 | 鐘馗 | 鉤子英雄 | 12888 |
+----+-----------+--------------------------+-------+
2 rows in set (0.00 sec)